From 857fd74e1b0becae283368b9e0ce5ecf5b640324 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 18 Nov 2015 13:44:46 +0100 Subject: [PATCH 001/571] commiting changes from svn branch SIC-receiver from revision 6836 to 7896 (current svn head). See svn log for details. --- openair1/PHY/INIT/lte_init.c | 61 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 292 +- openair1/PHY/LTE_TRANSPORT/defs.h | 6 + .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3940 +++++++++-------- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 94 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 215 +- openair1/PHY/LTE_TRANSPORT/power_control.c | 25 +- openair1/PHY/LTE_TRANSPORT/proto.h | 38 +- openair1/PHY/TOOLS/lte_phy_scope.c | 208 +- openair1/PHY/TOOLS/lte_phy_scope.h | 2 + openair1/PHY/impl_defs_lte.h | 21 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 1239 ++++-- openair1/SIMULATION/TOOLS/defs.h | 8 +- openair1/SIMULATION/TOOLS/random_channel.c | 246 +- openair2/UTIL/LOG/log.c | 64 +- 15 files changed, 3991 insertions(+), 2468 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index bdf35cccf9..6353f7fd7c 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -882,33 +882,31 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS pdsch->pmi_ext = (uint8_t*)malloc16_clear( frame_parms->N_RB_DL ); pdsch->llr[0] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); pdsch->llr128 = (int16_t**)malloc16_clear( sizeof(int16_t*) ); - pdsch->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) ); // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV + // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there pdsch->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); pdsch->rxdataF_comp0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->rho = (int32_t**)malloc16_clear( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); pdsch->dl_ch_mag0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); pdsch->dl_ch_magb0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->dl_ch_mag1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->dl_ch_magb1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); // the allocated memory size is fixed: AssertFatal( frame_parms->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); for (int i=0; inb_antennas_rx; i++) { - pdsch->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(frame_parms->N_RB_DL*12*7*2) ); for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) const int idx = (j<<1)+i; - const size_t num = 7*2*frame_parms->N_RB_DL*12; + const size_t num = 7*2*frame_parms->N_RB_DL*12+4; pdsch->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch->rxdataF_comp0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_mag0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_magb0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_mag1[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_magb1[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); } } } @@ -943,7 +941,7 @@ void phy_init_lte_ue__PDSCH_FLP( LTE_UE_PDSCH_FLP* const pdsch_flp, const LTE_DL pdsch_flp->rho[i] = (double*)malloc16_clear( sizeof(double)*(frame_parms->N_RB_DL*12*7*2) ); for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) const int idx = (j<<1)+i; - const size_t num = 7*2*frame_parms->N_RB_DL*12; + const size_t num = 7*2*frame_parms->N_RB_DL*12+4; pdsch_flp->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch_flp->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch_flp->rxdataF_comp[idx] = (double*)malloc16_clear( sizeof(double) * num ); @@ -970,7 +968,7 @@ int phy_init_lte_ue(PHY_VARS_UE *phy_vars_ue, LTE_UE_PDCCH** const ue_pdcch_vars = phy_vars_ue->lte_ue_pdcch_vars; LTE_UE_PRACH** const ue_prach_vars = phy_vars_ue->lte_ue_prach_vars; - int i,j,k; + int i,j,k,l; int eNB_id; msg("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,frame_parms->nb_antennas_tx,frame_parms->nb_antennas_rx); @@ -1064,25 +1062,42 @@ int phy_init_lte_ue(PHY_VARS_UE *phy_vars_ue, ue_pbch_vars[eNB_id] = (LTE_UE_PBCH *)malloc16_clear(sizeof(LTE_UE_PBCH)); if (abstraction_flag == 0) { + // init basic (common) variables phy_init_lte_ue__PDSCH( ue_pdsch_vars[eNB_id], frame_parms ); - ue_pdsch_vars[eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*frame_parms->N_RB_DL*12); - ue_pdsch_vars[eNB_id]->llr_shifts_p = ue_pdsch_vars[eNB_id]->llr_shifts; - ue_pdsch_vars[eNB_id]->dl_ch_mag1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - ue_pdsch_vars[eNB_id]->dl_ch_magb1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - ue_pdsch_vars[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + // init variables only needed for standard PDSCH + ue_pdsch_vars[eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*frame_parms->N_RB_DL*12); + ue_pdsch_vars[eNB_id]->llr_shifts_p = ue_pdsch_vars[eNB_id]->llr_shifts; + ue_pdsch_vars[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + ue_pdsch_vars[eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) ); - for (k=0;k<8;k++) - ue_pdsch_vars[eNB_id]->rxdataF_comp1[k] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + ue_pdsch_vars[eNB_id]->rho = (int32_t**)malloc16_clear( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); + for (int i=0; inb_antennas_rx; i++) + ue_pdsch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(frame_parms->N_RB_DL*12*7*2) ); + + ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); for (i=0; inb_antennas_rx; i++) for (j=0; j<4;j++) { - int idx = (j<<1)+i; - ue_pdsch_vars[eNB_id]->dl_ch_mag1[idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(frame_parms->N_RB_DL*12) ); - ue_pdsch_vars[eNB_id]->dl_ch_magb1[idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(frame_parms->N_RB_DL*12) ); - for (k=0;k<8;k++) - ue_pdsch_vars[eNB_id]->rxdataF_comp1[idx][k] = (int32_t*)malloc16_clear( sizeof(int32_t)*(frame_parms->N_RB_DL*12*14) ); + const int idx = (j<<1)+i; + const size_t num = 7*2*frame_parms->N_RB_DL*12+4; + ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); } + for (k=0;k<8;k++) { //harq_pid + for (l=0;l<8;l++) { //round + ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + + for (int i=0; inb_antennas_rx; i++) + for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) + const int idx = (j<<1)+i; + const size_t num = 7*2*frame_parms->N_RB_DL*12+4; + ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + } + } + } + #ifdef ENABLE_FULL_FLP phy_init_lte_ue__PDSCH_FLP( ue_pdsch_vars_flp[eNB_id], frame_parms ); #endif @@ -1106,7 +1121,7 @@ int phy_init_lte_ue(PHY_VARS_UE *phy_vars_ue, ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(frame_parms->N_RB_DL*12*7*2) ); for (j=0; j<4;j++) {//frame_parms->nb_antennas_tx; j++) int idx = (j<<1)+i; - size_t num = 7*2*frame_parms->N_RB_DL*12; + size_t num = 7*2*frame_parms->N_RB_DL*12+4; ue_pdcch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); ue_pdcch_vars[eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); ue_pdcch_vars[eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 1ccb3196fc..fc4173f499 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1217,26 +1217,28 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, if (frame_parms->nb_antennas_tx == 2) { if (dlsch1->active == 1) { // both TBs are active + dlsch0_harq->dl_power_off = 1; //no power offset?? + dlsch1_harq->dl_power_off = 1; //no power offset?? dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; switch (tpmi) { case 0: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); break; case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch0_harq->pmi_alloc = DL_pmi_single; + dlsch0_harq->pmi_alloc = DL_pmi_single; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = DL_pmi_single; + dlsch1_harq->pmi_alloc = DL_pmi_single; break; default: break; @@ -1245,6 +1247,7 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; } else { // only one is active + dlsch0_harq->dl_power_off = 1; //??? switch (tpmi) { case 0 : dlsch0_harq->mimo_mode = ALAMOUTI; @@ -1292,8 +1295,8 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, dlsch0->rnti = rnti; dlsch1->rnti = rnti; - dlsch0_harq->dl_power_off = 0; - dlsch1_harq->dl_power_off = 0; + // dlsch0_harq->dl_power_off = 1; + // dlsch1_harq->dl_power_off = 1; break; @@ -1513,7 +1516,7 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0 // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated - if (tbswap == 0) { + if (tbswap == 0) { dlsch0 = dlsch[0]; dlsch1 = dlsch[1]; } @@ -1568,25 +1571,27 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, dlsch1->active = 0; } - dlsch0_harq->dl_power_off = 0; - dlsch1_harq->dl_power_off = 0; + // dlsch0_harq->dl_power_off = 0; + // dlsch1_harq->dl_power_off = 0; if (frame_parms->nb_antennas_tx == 2) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; if ((dlsch0->active==1) && (dlsch1->active==1)) { + dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; } else { + dlsch0_harq->dl_power_off = 1; dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; } } - else if (frame_parms->nb_antennas_tx == 4) { // 4 antenna case + else if (frame_parms->nb_antennas_tx == 4) { if ((dlsch0->active==1) && (dlsch1->active==1)) { switch (tpmi) { case 0: // one layer per transport block @@ -1629,6 +1634,7 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, case 0: // one layer per transport block dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; + dlsch0_harq->dl_power_off = 1; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; break; case 1: // two-layers on TB 0 @@ -1648,6 +1654,7 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, case 0: // one layer per transport block dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; + dlsch1_harq->dl_power_off = 1; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; break; case 1: // two-layers on TB 0 @@ -2316,7 +2323,7 @@ int generate_eNB_dlsch_params_from_dci(uint8_t subframe, #endif // compute DL power control parameters - computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off); + computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off); @@ -3737,12 +3744,9 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, dlsch0_harq->dl_power_off = 1; //no power offset - LOG_D(PHY,"UE (%x/%d): Subframe %d Format2 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, + LOG_D(PHY,"UE (%x/%d): Subframe %d Format1 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, dlsch0_harq->first_tx,dlsch0_harq->status); - // printf("Format2 DCI (UE, hard pid %d): ndi %d, old_ndi %d (first tx %d)\n",harq_pid,ndi,dlsch0_harq->DCINdi, - // dlsch0_harq->first_tx); - if ((ndi!=dlsch0_harq->DCINdi)|| (dlsch0_harq->first_tx==1)) { // printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx); @@ -3750,7 +3754,7 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, dlsch0_harq->status = ACTIVE; dlsch0_harq->DCINdi = ndi; if (dlsch0_harq->first_tx==1) { - LOG_D(PHY,"[PDSCH %x/%d] Format 1 DCI First TX: Clearing flag\n"); + LOG_D(PHY,"Format 1 DCI First TX: Clearing flag\n"); dlsch0_harq->first_tx = 0; } } @@ -3792,6 +3796,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rballoc = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi; @@ -3802,6 +3808,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rballoc = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi; @@ -3814,6 +3822,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rballoc = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; @@ -3824,6 +3834,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rballoc = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; @@ -3842,6 +3854,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; @@ -3853,6 +3867,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; @@ -3866,6 +3882,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; @@ -3877,6 +3895,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; @@ -3895,6 +3915,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; @@ -3906,6 +3928,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; @@ -3919,6 +3943,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; @@ -3930,6 +3956,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; @@ -3949,6 +3977,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; @@ -3960,6 +3990,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; @@ -3973,6 +4005,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; @@ -3984,6 +4018,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; @@ -4001,9 +4037,6 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, } - dlsch[0]->current_harq_pid = harq_pid; - dlsch[0]->harq_ack[subframe].harq_id = harq_pid; - tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; if (tbswap == 0) { dlsch0 = dlsch[0]; @@ -4016,114 +4049,166 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; + dlsch0->current_harq_pid = harq_pid; + dlsch1->current_harq_pid = harq_pid; + dlsch0->harq_ack[subframe].harq_id = harq_pid; + dlsch1->harq_ack[subframe].harq_id = harq_pid; + conv_rballoc(rah, rballoc, frame_parms->N_RB_DL, dlsch0_harq->rb_alloc); + dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); + rballoc, + frame_parms->N_RB_DL); dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; dlsch0_harq->mcs = mcs1; + dlsch1_harq->mcs = mcs2; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - /* - if (dlsch0_harq->mcs>20) { - msg("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs); - return(-1); - } - */ + dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch1_harq->mcs = mcs2; dlsch0_harq->rvidx = rv1; dlsch1_harq->rvidx = rv2; // check if either TB is disabled (see 36-213 V8.6 p. 26) + if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) + dlsch0->active = 0; + else + dlsch0->active = 1; + + if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) + dlsch1->active = 0; + else + dlsch1->active = 1; - if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { - dlsch0_harq->status = DISABLED; - } - if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { - dlsch1_harq->status = DISABLED; - } dlsch0_harq->Nl = 1; + dlsch1_harq->Nl = 1; // dlsch0->layer_index = tbswap; // dlsch1->layer_index = 1-tbswap; - switch (tpmi) { - case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - break; - case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); - break; - case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - break; - case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); - break; - case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; - case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - LOG_E(PHY,"Unsupported TPMI\n"); - return(-1); - break; + if (dlsch1->active==1) { //two codewords + dlsch0_harq->dl_power_off = 1; //no power offset?? + dlsch1_harq->dl_power_off = 1; //no power offset?? + switch (tpmi) { + case 0: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + break; + case 1: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3); + break; + case 2: // PUSCH precoding + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch0_harq->pmi_alloc = 0; //TODO: DL_pmi_single; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->pmi_alloc = 0; //TODO: DL_pmi_single; + break; + default: + break; + } + } + else { + dlsch0_harq->dl_power_off = 1;//???? + switch (tpmi) { + case 0 : + dlsch0_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + break; + case 2: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + break; + case 3: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + break; + case 4: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + break; + case 5: + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; + case 6: + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + LOG_E(PHY,"Unsupported TPMI\n"); + return(-1); + break; + } } - if (frame_parms->mode1_flag == 1) dlsch0_harq->mimo_mode = SISO; - if (ndi1!=dlsch0_harq->DCINdi) { - dlsch0_harq->round = 0; - dlsch0_harq->status = ACTIVE; - dlsch0_harq->DCINdi = ndi1; - } - else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, + + if (dlsch0->active == 1) { + if ((ndi1!=dlsch0_harq->DCINdi) || + (dlsch0_harq->first_tx==1)) { + dlsch0_harq->round = 0; + dlsch0_harq->status = ACTIVE; + dlsch0_harq->DCINdi = ndi1; + if (dlsch0_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); + dlsch0_harq->first_tx = 0; + } + } + else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received - - dlsch0->harq_ack[subframe].ack = 1; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch0->harq_ack[subframe].send_harq_status = 1; - dlsch0->active = 0; - return(0); + + dlsch0->harq_ack[subframe].ack = 1; + dlsch0->harq_ack[subframe].harq_id = harq_pid; + dlsch0->harq_ack[subframe].send_harq_status = 1; + dlsch0->active = 0; + } } - dlsch0_harq->mcs = mcs1; + + if (dlsch1->active == 1) { + if ((ndi2!=dlsch1_harq->DCINdi) || + (dlsch1_harq->first_tx==1)) { + dlsch1_harq->round = 0; + dlsch1_harq->status = ACTIVE; + dlsch1_harq->DCINdi = ndi2; + if (dlsch1_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); + dlsch1_harq->first_tx = 0; + } + } + else if (dlsch1_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, + // this happens if either another harq process in the same + // is NAK or an ACK was not received + + dlsch1->harq_ack[subframe].ack = 1; + dlsch1->harq_ack[subframe].harq_id = harq_pid; + dlsch1->harq_ack[subframe].send_harq_status = 1; + dlsch1->active = 0; + } + } + if (dlsch0_harq->nb_rb>1) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; } else - dlsch0_harq->TBS =0; - /* - if (dlsch0_harq->mcs > 18) - printf("mcs %d, TBS %d\n",dlsch0_harq->mcs,dlsch0_harq->TBS); - */ + dlsch0_harq->TBS = 0; - if (dlsch1_harq->DCINdi != ndi2) { - dlsch1_harq->round=0; - dlsch1_harq->status = ACTIVE; - } - dlsch1_harq->DCINdi = ndi2; - dlsch1_harq->mcs = mcs2; if (dlsch1_harq->nb_rb>1) { - dlsch1_harq->TBS = TBStable[dlsch1_harq->mcs][dlsch1_harq->nb_rb-1]; + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; } else dlsch1_harq->TBS = 0; @@ -4131,11 +4216,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, dlsch0->rnti = rnti; dlsch1->rnti = rnti; - dlsch0_harq->dl_power_off = 1; //no power offset - dlsch1_harq->dl_power_off = 1; //no power offset - - dlsch0->active = 1; - dlsch1->active = 1; + // dlsch0_harq->dl_power_off = 1; //no power offset + // dlsch1_harq->dl_power_off = 1; //no power offset break; @@ -4461,7 +4543,7 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, dlsch0_harq->status = ACTIVE; dlsch0_harq->DCINdi = ndi1; if (dlsch0_harq->first_tx==1) { - LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX0: Clearing flag\n"); + LOG_D(PHY,"Format 2A DCI First TX0: Clearing flag\n"); dlsch0_harq->first_tx = 0; } } @@ -4485,7 +4567,7 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, dlsch1_harq->DCINdi = ndi2; if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX1: Clearing flag\n",rnti,harq_pid); + LOG_D(PHY,"Format 2A DCI First TX1: Clearing flag\n",rnti,harq_pid); dlsch1_harq->first_tx = 0; } @@ -4768,7 +4850,7 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe, dlsch[0]->active=1; // compute DL power control parameters - computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off); + computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off); diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index aedd996ad3..67c0112af2 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -695,6 +695,12 @@ typedef enum { PMCH } PDSCH_t; +typedef enum { + rx_standard=0, + rx_IC_single_stream, + rx_IC_dual_stream, +} RX_type_t; + typedef enum { pucch_format1=0, pucch_format1a, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 6428a3899f..9655716b90 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -84,7 +84,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, uint8_t subframe, unsigned char symbol, unsigned char first_symbol_flag, - unsigned char dual_stream_flag, + RX_type_t rx_type, unsigned char i_mod, unsigned char harq_pid) { @@ -95,10 +95,13 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LTE_UE_DLSCH_t **dlsch_ue; unsigned char aatx,aarx; - unsigned short nb_rb; + unsigned short nb_rb, round; int avgs, rb; LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0; + int32_t **rxdataF_comp_ptr; + int32_t **dl_ch_mag_ptr; + switch (type) { case SI_PDSCH: lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]; @@ -123,6 +126,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, break; } + DevAssert(dlsch0_harq); + round = dlsch0_harq->round; if (eNB_id > 2) { LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id); @@ -148,7 +153,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_W(PHY,"dlsch_demodulation.c: Null lte_frame_parms\n"); return(-1); } - // printf("rx_dlsch subframe %d symbol %d: eNB_id %d, eNB_id_i %d, dual_stream_flag %d\n",subframe,symbol,eNB_id,eNB_id_i,dual_stream_flag); + //printf("rx_dlsch subframe %d symbol %d: eNB_id %d, eNB_id_i %d\n",subframe,symbol,eNB_id,eNB_id_i); // symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; /* @@ -158,87 +163,101 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, pilots=0; */ + if (dlsch0_harq->mimo_mode>DUALSTREAM_UNIFORM_PRECODINGj) { + LOG_E(PHY,"This transmission mode is not yet supported!\n"); + return(-1); + } + if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING))) { + DevAssert(dlsch1_harq); + if (eNB_id!=eNB_id_i) { + LOG_E(PHY,"TM3/TM4 requires to set eNB_id==eNB_id_i!\n"); + return(-1); + } + } + + //printf("rx_pdsch: harq_pid=%d, round=%d\n",harq_pid,round); + if (frame_parms->nb_antennas_tx_eNB>1) { #ifdef DEBUG_DLSCH_MOD LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch_ue[0],dlsch0_harq->rb_alloc[0]); #endif nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, - lte_ue_common_vars->dl_ch_estimates[eNB_id], - lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, - dlsch0_harq->rb_alloc, - symbol, - subframe, - phy_vars_ue->high_speed_flag, - frame_parms); + lte_ue_common_vars->dl_ch_estimates[eNB_id], + lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + dlsch0_harq->rb_alloc, + symbol, + subframe, + phy_vars_ue->high_speed_flag, + frame_parms); - if (dual_stream_flag==1) { - if (eNB_id_in_connected_eNB) - nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, - lte_ue_common_vars->dl_ch_estimates[eNB_id_i], - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, - dlsch0_harq->rb_alloc, - symbol, - subframe, - phy_vars_ue->high_speed_flag, - frame_parms); + if (rx_type==rx_IC_single_stream) { + if (eNB_id_in_connected_eNB) // we are in TM5 + nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, + lte_ue_common_vars->dl_ch_estimates[eNB_id_i], + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, + dlsch0_harq->rb_alloc, + symbol, + subframe, + phy_vars_ue->high_speed_flag, + frame_parms); else - nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, - lte_ue_common_vars->dl_ch_estimates[eNB_id], - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, - dlsch0_harq->rb_alloc, - symbol, - subframe, - phy_vars_ue->high_speed_flag, - frame_parms); + nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, + lte_ue_common_vars->dl_ch_estimates[eNB_id], + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, + dlsch0_harq->rb_alloc, + symbol, + subframe, + phy_vars_ue->high_speed_flag, + frame_parms); } } // if n_tx>1 else { nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF, - lte_ue_common_vars->dl_ch_estimates[eNB_id], - lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, - dlsch0_harq->rb_alloc, - symbol, - subframe, - phy_vars_ue->high_speed_flag, - frame_parms); + lte_ue_common_vars->dl_ch_estimates[eNB_id], + lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + dlsch0_harq->rb_alloc, + symbol, + subframe, + phy_vars_ue->high_speed_flag, + frame_parms); - if (dual_stream_flag==1) { + if (rx_type==rx_IC_single_stream) { if (eNB_id_in_connected_eNB) - nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF, - lte_ue_common_vars->dl_ch_estimates[eNB_id_i], - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, - dlsch0_harq->rb_alloc, - symbol, - subframe, - phy_vars_ue->high_speed_flag, - frame_parms); + nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF, + lte_ue_common_vars->dl_ch_estimates[eNB_id_i], + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, + dlsch0_harq->rb_alloc, + symbol, + subframe, + phy_vars_ue->high_speed_flag, + frame_parms); else - nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF, - lte_ue_common_vars->dl_ch_estimates[eNB_id], - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, - dlsch0_harq->rb_alloc, - symbol, - subframe, - phy_vars_ue->high_speed_flag, - frame_parms); + nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF, + lte_ue_common_vars->dl_ch_estimates[eNB_id], + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + dlsch0_harq->pmi_alloc, + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, + dlsch0_harq->rb_alloc, + symbol, + subframe, + phy_vars_ue->high_speed_flag, + frame_parms); } } //else n_tx>1 @@ -257,10 +276,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, */ if (first_symbol_flag==1) { dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - avg, - symbol, - nb_rb); + frame_parms, + avg, + symbol, + nb_rb); #ifdef DEBUG_PHY LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]); #endif @@ -271,8 +290,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avgs = 0; for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); - // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2); @@ -280,10 +299,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // + log2_approx(frame_parms->nb_antennas_rx-1); if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) && - (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) && - (dlsch0_harq->dl_power_off==1)) // we are in TM 6 + (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) && + (dlsch0_harq->dl_power_off==1)) // we are in TM 6 lte_ue_pdsch_vars[eNB_id]->log2_maxh++; + //printf("log2_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); + // this version here applies the factor .5 also to the extra terms. however, it does not work so well as the one above /* K = Nb_rx in TM1 Nb_tx*Nb_rx in TM2,4,5 @@ -307,249 +328,297 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, aarx = frame_parms->nb_antennas_rx; if (dlsch0_harq->mimo_moderxdataF_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - (aatx>1) ? lte_ue_pdsch_vars[eNB_id]->rho : NULL, - frame_parms, - symbol, - first_symbol_flag, - get_Qm(dlsch0_harq->mcs), - nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh, - phy_measurements); // log2_maxh+I0_shift -#ifdef DEBUG_PHY - if (symbol==5) - write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); -#endif - - if ((dual_stream_flag==1) && - (eNB_id_in_connected_eNB)) { + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + (aatx>1) ? lte_ue_pdsch_vars[eNB_id]->rho : NULL, + frame_parms, + symbol, + first_symbol_flag, + get_Qm(dlsch0_harq->mcs), + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + phy_measurements); // log2_maxh+I0_shift + /* + if (symbol == 5) { + write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + } */ + if ((rx_type==rx_IC_single_stream) && + (eNB_id_in_connected_eNB)) { + // we don't use IA receiver for TM1 and TM2 // get MF output for interfering stream dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - (aatx>1) ? lte_ue_pdsch_vars[eNB_id_i]->rho : NULL, - frame_parms, - symbol, - first_symbol_flag, - i_mod, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh, - phy_measurements); // log2_maxh+I0_shift + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, + (aatx>1) ? lte_ue_pdsch_vars[eNB_id_i]->rho : NULL, + frame_parms, + symbol, + first_symbol_flag, + i_mod, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + phy_measurements); // log2_maxh+I0_shift #ifdef DEBUG_PHY if (symbol == 5) { - write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - write_output("rxF_comp_i.m","rxF_c_i",<e_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + write_output("rxF_comp_i.m","rxF_c_i",<e_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } #endif - + // compute correlation between signal and interference channels dlsch_dual_stream_correlation(frame_parms, - symbol, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->log2_maxh); + symbol, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->log2_maxh); } + } - else if (dlsch0_harq->mimo_mode == LARGE_CDD) { // TM3 + else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || + ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 // LOG_I(PHY,"Running PDSCH RX for TM3\n"); + if (frame_parms->nb_antennas_tx_eNB == 2) { - if (first_symbol_flag==1) { - // effective channel of desired user is always stronger than interfering eff. channel - dlsch_channel_level_TM3(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - avg, symbol, nb_rb); + + + // scaling interfering channel (following for TM56) + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + dlsch_ue, + symbol, + nb_rb); - // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]); - avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; + + if (first_symbol_flag==1) { + // effective channel of desired user is always stronger than interfering eff. channel + + dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avg, symbol, nb_rb, + dlsch0_harq->mimo_mode); + + /* + if (rx_type>rx_standard) { + // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; + } + else + */ - lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); - // printf("log2_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); - } - dlsch_channel_compensation_TM3(frame_parms, - lte_ue_pdsch_vars[eNB_id], - phy_measurements, - eNB_id, - symbol, - get_Qm(dlsch0_harq->mcs), - get_Qm(dlsch1_harq->mcs), - dlsch0_harq->round, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh); + lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; + } + + dlsch_channel_compensation_TM34(frame_parms, + lte_ue_pdsch_vars[eNB_id], + phy_measurements, + eNB_id, + symbol, + get_Qm(dlsch0_harq->mcs), + get_Qm(dlsch1_harq->mcs), + harq_pid, + dlsch0_harq->round, + dlsch0_harq->mimo_mode, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh); + /* + if (symbol == 5) { + + write_output("rxF_comp_d00.m","rxF_c_d00",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + write_output("rxF_comp_d01.m","rxF_c_d01",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rxF_comp_d10.m","rxF_c_d10",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rxF_comp_d11.m","rxF_c_d11",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM + + +}*/ // compute correlation between signal and interference channels (rho12 and rho21) dlsch_dual_stream_correlation(frame_parms, - symbol, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, + symbol, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + //lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh); + + //to be optimized (just take complex conjugate) dlsch_dual_stream_correlation(frame_parms, - symbol, - nb_rb, - &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->log2_maxh); + symbol, + nb_rb, + &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + //lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->log2_maxh); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); - } - else { + +} + else { LOG_E(PHY, "only 2 tx antennas supported for TM3\n"); + return(-1); } } - else if (dlsch0_harq->mimo_modemimo_moden_connected_eNB)) { // TM5 two-user + if ((rx_type==rx_IC_single_stream) && (eNB_id_i==phy_vars_ue->n_connected_eNB)) { // TM5 two-user // Scale the channel estimates for interfering stream dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); + frame_parms, + dlsch_ue, + symbol, + nb_rb); /* compute new log2_maxh for effective channel */ if (first_symbol_flag==1) { - // effective channel of desired user is always stronger than interfering eff. channel - dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb); - - // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); - avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; + // effective channel of desired user is always stronger than interfering eff. channel + dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb); + + // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); + avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; - lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); - //printf("log1_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); + lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); + //printf("log1_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); } dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, - frame_parms, - phy_measurements, - eNB_id, - symbol, - get_Qm(dlsch0_harq->mcs), - nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh, - dlsch0_harq->dl_power_off); + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + frame_parms, + phy_measurements, + eNB_id, + symbol, + get_Qm(dlsch0_harq->mcs), + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + dlsch0_harq->dl_power_off); // if interference source is MU interference, assume opposite precoder was used at eNB // calculate opposite PMI for (rb=0;rbpmi_ext[rb]) { - case 0: - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=1; - break; - case 1: - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=0; - break; - case 2: - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=3; - break; - case 3: - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=2; - break; - } - // if (rb==0) - // printf("pmi %d, pmi_i %d\n",lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb],lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]); - + switch(lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb]) { + case 0: + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=1; + break; + case 1: + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=0; + break; + case 2: + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=3; + break; + case 3: + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]=2; + break; + } + // if (rb==0) + // printf("pmi %d, pmi_i %d\n",lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb],lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]); + } dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, - frame_parms, - phy_measurements, - eNB_id_i, - symbol, - i_mod, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh, - dlsch0_harq->dl_power_off); + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, + frame_parms, + phy_measurements, + eNB_id_i, + symbol, + i_mod, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + dlsch0_harq->dl_power_off); #ifdef DEBUG_PHY if (symbol==5) { - write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - write_output("rxF_comp_i.m","rxF_c_i",<e_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + write_output("rxF_comp_i.m","rxF_c_i",<e_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } #endif dlsch_dual_stream_correlation(frame_parms, - symbol, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->log2_maxh); + symbol, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->log2_maxh); } else { dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, - frame_parms, - phy_measurements, - eNB_id, - symbol, - get_Qm(dlsch0_harq->mcs), - nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh, - 1); + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + frame_parms, + phy_measurements, + eNB_id, + symbol, + get_Qm(dlsch0_harq->mcs), + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + 1); + //write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } } // printf("MRC\n"); if (frame_parms->nb_antennas_rx > 1) { - if (dlsch0_harq->mimo_mode == LARGE_CDD) { + if ((dlsch0_harq->mimo_mode == LARGE_CDD) || + ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 if (frame_parms->nb_antennas_tx_eNB == 2) { - dlsch_detection_mrc(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round], - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->rho, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, - symbol, - nb_rb, - dual_stream_flag); + dlsch_detection_mrc_TM34(frame_parms, + lte_ue_pdsch_vars[eNB_id], + harq_pid, + dlsch0_harq->round, + symbol, + nb_rb, + 1); + /*dlsch_detection_mrc(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + symbol, + nb_rb, + 1); //dual_stream_flag);*/ //this has to be 1, otherwise mrc is not done on second stream } } else { dlsch_detection_mrc(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->rho, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, - symbol, - nb_rb, - dual_stream_flag); + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->rho, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, + symbol, + nb_rb, + rx_type==rx_IC_single_stream); } } // printf("Combining"); @@ -567,211 +636,270 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else if (dlsch0_harq->mimo_mode == ALAMOUTI) { dlsch_alamouti(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, - symbol, - nb_rb); + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, + symbol, + nb_rb); } - else if (dlsch0_harq->mimo_mode == LARGE_CDD) { - + // printf("LLR"); + if ((dlsch0_harq->mimo_mode == LARGE_CDD) || + ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { + rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; + dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1; + i_mod = get_Qm(dlsch1_harq->mcs) ; } else { - LOG_W(PHY,"dlsch_rx: Unknown MIMO mode\n"); - return (-1); + rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0; + dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0; + //i_mod should have been passed as a parameter } - // printf("LLR"); - switch (get_Qm(dlsch0_harq->mcs)) { case 2 : - if (dlsch0_harq->mimo_mode != LARGE_CDD) { - if (dual_stream_flag == 0) - dlsch_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - else if (i_mod == 2) { - dlsch_qpsk_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - } - else if (i_mod == 4) { - dlsch_qpsk_16qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - } - else { - dlsch_qpsk_64qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - - } + if (rx_type==rx_standard) { + dlsch_qpsk_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); } - else { // TM3 - DevAssert(dlsch1_harq); - if (get_Qm(dlsch1_harq->mcs) == 2) { - /* dlsch_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - */ - dlsch_qpsk_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round], - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - dlsch_qpsk_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round], - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + else if ((rx_type==rx_IC_single_stream) || (rx_type==rx_IC_dual_stream)) { + if (i_mod == 2) { + dlsch_qpsk_qpsk_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_qpsk_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } + else if (i_mod == 4) { + dlsch_qpsk_16qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_16qam_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } + else { + dlsch_qpsk_64qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_64qam_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } } - else if (get_Qm(dlsch1_harq->mcs) == 4) { - dlsch_qpsk_16qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round], - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - } - else { - dlsch_qpsk_64qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[dlsch0_harq->round], - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - - } - } break; case 4 : - if (dual_stream_flag == 0) { + if (rx_type==rx_standard) { dlsch_16qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->llr[0], - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,4,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->llr[0], + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); } - else if (i_mod == 2) { - dlsch_16qam_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - } - else if (i_mod == 4) { - dlsch_16qam_16qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - } else { - dlsch_16qam_64qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); + else if ((rx_type==rx_IC_single_stream) || (rx_type==rx_IC_dual_stream)) { + if (i_mod == 2) { + dlsch_16qam_qpsk_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_qpsk_16qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } + else if (i_mod == 4) { + dlsch_16qam_16qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_16qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } + else { + dlsch_16qam_64qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_64qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } } break; case 6 : - if (dual_stream_flag == 0) { + if (rx_type==rx_standard) { dlsch_64qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->llr[0], - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,6,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + lte_ue_pdsch_vars[eNB_id]->llr[0], + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); } - else if (i_mod == 2) { - dlsch_64qam_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - } - else if (i_mod == 4) { - dlsch_64qam_16qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - - } - else { - dlsch_64qam_64qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); + else if ((rx_type==rx_IC_single_stream) || (rx_type==rx_IC_dual_stream)) { + if (i_mod == 2) { + dlsch_64qam_qpsk_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_qpsk_64qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } + else if (i_mod == 4) { + dlsch_64qam_16qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_16qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } + else { + dlsch_64qam_64qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_64qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + } } break; default: @@ -780,6 +908,47 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, break; } + switch (get_Qm(dlsch1_harq->mcs)) { + case 2 : + if (rx_type==rx_standard) { + dlsch_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + break; + case 4: + if (rx_type==rx_standard) { + dlsch_16qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->llr[1], + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + break; + case 6 : + if (rx_type==rx_standard) { + dlsch_64qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->llr[1], + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } + break; + default: + LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); + return(-1); + break; + } + + return(0); } @@ -822,7 +991,7 @@ void dlsch_channel_compensation(int **rxdataF_ext, QAM_amp128b = _mm_setzero_si128(); } else if (mod_order == 6) { - QAM_amp128 = _mm_set1_epi16(QAM64_n1); // + QAM_amp128 = _mm_set1_epi16(QAM64_n1); QAM_amp128b = _mm_set1_epi16(QAM64_n2); } @@ -838,128 +1007,128 @@ void dlsch_channel_compensation(int **rxdataF_ext, for (rb=0;rb2) { - // get channel amplitude if not QPSK + if (mod_order>2) { + // get channel amplitude if not QPSK - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - // store channel magnitude here in a new field of dlsch + // store channel magnitude here in a new field of dlsch - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[0] = dl_ch_mag128[0]; - dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); - dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); + dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[1] = dl_ch_mag128[1]; - dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); - dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); + dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag128b[2] = dl_ch_mag128[2]; + dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); - } + dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); + dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); + } - dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); - dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); + dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - if (pilots==0) { - dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); - } - } - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); + if (pilots==0) { + dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + } + } + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); + // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch128+2); + // print_shorts("pack:",rxdataF_comp128+2); - dl_ch128+=3; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } - else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch128+=2; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } + dl_ch128+=3; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + rxdataF128+=3; + rxdataF_comp128+=3; + } + else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less + dl_ch128+=2; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; + } } } @@ -974,75 +1143,75 @@ void dlsch_channel_compensation(int **rxdataF_ext, dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0;rbrx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12); + phy_measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12); } } } @@ -1134,26 +1303,44 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { - __m128i amp; - amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); - __m128i tmp1; + // __m128i amp; + // amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + __m128i tmp0,tmp1; - if (pmi == 0) { - ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); - ch1[0] = _mm_subs_epi16(ch0[0],ch1[0]); + //print_shorts("prec2A_TM4 ch0 (before):",ch0); + //print_shorts("prec2A_TM4 ch1 (before):",ch1); + + if (pmi == 0) { //[1 1;1 -1] + tmp0 = ch0[0]; + tmp1 = ch1[0]; + ch0[0] = _mm_adds_epi16(tmp0,tmp1); + ch1[0] = _mm_subs_epi16(tmp0,tmp1); } else { + tmp0 = ch0[0]; tmp1 = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); tmp1 = _mm_shufflehi_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); - ch0[0] = _mm_subs_epi16(ch0[0],tmp1); - ch1[0] = _mm_subs_epi16(ch0[0],tmp1); + ch0[0] = _mm_subs_epi16(tmp0,tmp1); + ch1[0] = _mm_subs_epi16(tmp0,tmp1); } - ch0[0] = _mm_mulhi_epi16(ch0[0],amp); - ch0[0] = _mm_slli_epi16(ch0[0],1); - ch1[0] = _mm_mulhi_epi16(ch1[0],amp); - ch1[0] = _mm_slli_epi16(ch1[0],1); + //print_shorts("prec2A_TM4 ch0 (middle):",ch0); + //print_shorts("prec2A_TM4 ch1 (middle):",ch1); + + //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); + //ch0[0] = _mm_slli_epi16(ch0[0],1); + //ch1[0] = _mm_mulhi_epi16(ch1[0],amp); + //ch1[0] = _mm_slli_epi16(ch1[0],1); + + //print_shorts("prec2A_TM4 ch0 (end):",ch0); + //print_shorts("prec2A_TM4 ch1 (end):",ch1); + ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 + ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 + + + // print_shorts("prec2A_TM4 ch0 (end):",ch0); + //print_shorts("prec2A_TM4 ch1 (end):",ch1); } void dlsch_channel_compensation_TM56(int **rxdataF_ext, @@ -1216,82 +1403,82 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); if (pilots==0) { - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); } if (mod_order>2) { - // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // get channel amplitude if not QPSK + + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[0] = dl_ch_mag128[0]; - dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); - dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); + dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]); + //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]); - dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b[1] = dl_ch_mag128[1]; - dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); - dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); + dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag128b[2] = dl_ch_mag128[2]; + dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); - } + dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); + dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); + } - dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]); + //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]); - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); - dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); + dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - if (pilots==0) { - dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); - } + if (pilots==0) { + dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + } } // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); + // print_ints("re",&mmtmpD0); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); + // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); + // print_ints("re(shift)",&mmtmpD0); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); + // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch128); + // print_shorts("pack:",rxdataF_comp128); // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); @@ -1307,71 +1494,73 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch128+1); + // print_shorts("pack:",rxdataF_comp128+1); if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch128+2); + // print_shorts("pack:",rxdataF_comp128+2); - dl_ch0_128+=3; - dl_ch1_128+=3; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - rxdataF128+=3; - rxdataF_comp128+=3; + dl_ch0_128+=3; + dl_ch1_128+=3; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + rxdataF128+=3; + rxdataF_comp128+=3; } else { - dl_ch0_128+=2; - dl_ch1_128+=2; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - rxdataF128+=2; - rxdataF_comp128+=2; + dl_ch0_128+=2; + dl_ch1_128+=2; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=2; + rxdataF_comp128+=2; } } Nre = (pilots==0) ? 12 : 8; precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); } // rx_antennas phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,phy_measurements->n0_power_tot); - + //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, - // phy_measurements->precoded_cqi_dB[eNB_id][0]); + // phy_measurements->precoded_cqi_dB[eNB_id][0]); _mm_empty(); _m_empty(); } -void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *lte_ue_pdsch_vars, - PHY_MEASUREMENTS *phy_measurements, - int eNB_id, - unsigned char symbol, - unsigned char mod_order0, - unsigned char mod_order1, - int round, - unsigned short nb_rb, - unsigned char output_shift) { +void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDSCH *lte_ue_pdsch_vars, + PHY_MEASUREMENTS *phy_measurements, + int eNB_id, + unsigned char symbol, + unsigned char mod_order0, + unsigned char mod_order1, + int harq_pid, + int round, + MIMO_mode_t mimo_mode, + unsigned short nb_rb, + unsigned char output_shift) { unsigned short rb,Nre; __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag0_128,*dl_ch_mag1_128,*dl_ch_mag0_128b,*dl_ch_mag1_128b,*rxdataF128,*rxdataF_comp0_128,*rxdataF_comp1_128; @@ -1385,7 +1574,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; - int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[round]; //? + int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; @@ -1396,7 +1585,7 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms, rx_power_correction = 1; - //printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); + // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); if (mod_order0 == 4) { QAM_amp0_128 = _mm_set1_epi16(QAM16_n1); @@ -1417,155 +1606,180 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms, for (aarx=0;aarxnb_antennas_rx;aarx++) { - dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + // printf("symbol %d, rx antenna %d\n", symbol, aarx); + + dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 + dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 - dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag1_128b = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp0_128 = (__m128i *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp1_128 = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; - + dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 + dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1 + dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 + dl_ch_mag1_128b = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; //received signal on antenna of interest h11*x1+h12*x2 + rxdataF_comp0_128 = (__m128i *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x1 on antenna of interest + rxdataF_comp1_128 = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x2 on antenna of interest for (rb=0;rb2) { - // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // get channel amplitude if not QPSK + + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag0_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag0_128b[0] = dl_ch_mag0_128[0]; - dl_ch_mag0_128[0] = _mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128); - dl_ch_mag0_128[0] = _mm_slli_epi16(dl_ch_mag0_128[0],1); + dl_ch_mag0_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag0_128b[0] = dl_ch_mag0_128[0]; + dl_ch_mag0_128[0] = _mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128); + dl_ch_mag0_128[0] = _mm_slli_epi16(dl_ch_mag0_128[0],1); - // print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]); + // print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]); - dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag0_128b[1] = dl_ch_mag0_128[1]; - dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128); - dl_ch_mag0_128[1] = _mm_slli_epi16(dl_ch_mag0_128[1],1); + dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag0_128b[1] = dl_ch_mag0_128[1]; + dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128); + dl_ch_mag0_128[1] = _mm_slli_epi16(dl_ch_mag0_128[1],1); - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag0_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag0_128b[2] = dl_ch_mag0_128[2]; + dl_ch_mag0_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag0_128b[2] = dl_ch_mag0_128[2]; - dl_ch_mag0_128[2] = _mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128); - dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1); - } + dl_ch_mag0_128[2] = _mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128); + dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1); + } - dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b); - dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1); + dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b); + dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1); - //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]); + // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]); - dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b); - dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1); + dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b); + dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1); - if (pilots==0) { - dl_ch_mag0_128b[2] = _mm_mulhi_epi16(dl_ch_mag0_128b[2],QAM_amp0_128b); - dl_ch_mag0_128b[2] = _mm_slli_epi16(dl_ch_mag0_128b[2],1); - } + if (pilots==0) { + dl_ch_mag0_128b[2] = _mm_mulhi_epi16(dl_ch_mag0_128b[2],QAM_amp0_128b); + dl_ch_mag0_128b[2] = _mm_slli_epi16(dl_ch_mag0_128b[2],1); + } } if (mod_order1>2) { - // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + // get channel amplitude if not QPSK + + mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag1_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag1_128b[0] = dl_ch_mag1_128[0]; - dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128); - dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1); + dl_ch_mag1_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag1_128b[0] = dl_ch_mag1_128[0]; + dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128); + dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1); - //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]); + // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]); - dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag1_128b[1] = dl_ch_mag1_128[1]; - dl_ch_mag1_128[1] = _mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128); - dl_ch_mag1_128[1] = _mm_slli_epi16(dl_ch_mag1_128[1],1); + dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag1_128b[1] = dl_ch_mag1_128[1]; + dl_ch_mag1_128[1] = _mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128); + dl_ch_mag1_128[1] = _mm_slli_epi16(dl_ch_mag1_128[1],1); - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag1_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag1_128b[2] = dl_ch_mag1_128[2]; + dl_ch_mag1_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag1_128b[2] = dl_ch_mag1_128[2]; - dl_ch_mag1_128[2] = _mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128); - dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1); - } + dl_ch_mag1_128[2] = _mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128); + dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1); + } - dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b); - dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1); + dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b); + dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1); - //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]); + // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]); - dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b); - dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1); + dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b); + dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1); - if (pilots==0) { - dl_ch_mag1_128b[2] = _mm_mulhi_epi16(dl_ch_mag1_128b[2],QAM_amp1_128b); - dl_ch_mag1_128b[2] = _mm_slli_epi16(dl_ch_mag1_128b[2],1); - } + if (pilots==0) { + dl_ch_mag1_128b[2] = _mm_mulhi_epi16(dl_ch_mag1_128b[2],QAM_amp1_128b); + dl_ch_mag1_128b[2] = _mm_slli_epi16(dl_ch_mag1_128b[2],1); + } } - // layer 0 + // layer 0 // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]); - //print_ints("re",&mmtmpD0); + // print_ints("re",&mmtmpD0); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // print_ints("im",&mmtmpD1); + // print_ints("im",&mmtmpD1); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // printf("Shift: %d\n",output_shift); - // print_ints("re(shift)",&mmtmpD0); + // printf("Shift: %d\n",output_shift); + // print_ints("re(shift)",&mmtmpD0); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); + // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); rxdataF_comp0_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch0_128); - // print_shorts("pack:",rxdataF_comp0_128); - + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch0_128); + // print_shorts("pack:",rxdataF_comp0_128); + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -1580,59 +1794,58 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); rxdataF_comp0_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch0_128+1); + // print_shorts("pack:",rxdataF_comp0_128+1); if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp0_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); + rxdataF_comp0_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch0_128+2); + // print_shorts("pack:",rxdataF_comp0_128+2); + + } - else { - - } // layer 1 // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); + // print_ints("re",&mmtmpD0); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); + // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - // print_ints("re(shift)",&mmtmpD0); + // print_ints("re(shift)",&mmtmpD0); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - // print_ints("im(shift)",&mmtmpD1); + // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); rxdataF_comp1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch1_128); + // print_shorts("pack:",rxdataF_comp1_128); // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch1_128[1],rxdataF128[1]); @@ -1648,71 +1861,73 @@ void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); rxdataF_comp1_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch1_128+1); + // print_shorts("pack:",rxdataF_comp1_128+1); if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp1_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - - dl_ch0_128+=3; - dl_ch1_128+=3; - dl_ch_mag0_128+=3; - dl_ch_mag1_128+=3; - dl_ch_mag0_128b+=3; - dl_ch_mag1_128b+=3; - rxdataF128+=3; - rxdataF_comp0_128+=3; - rxdataF_comp1_128+=3; + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp1_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch1_128+2); + // print_shorts("pack:",rxdataF_comp1_128+2); + + dl_ch0_128+=3; + dl_ch1_128+=3; + dl_ch_mag0_128+=3; + dl_ch_mag1_128+=3; + dl_ch_mag0_128b+=3; + dl_ch_mag1_128b+=3; + rxdataF128+=3; + rxdataF_comp0_128+=3; + rxdataF_comp1_128+=3; } else { - dl_ch0_128+=2; - dl_ch1_128+=2; - dl_ch_mag0_128+=2; - dl_ch_mag1_128+=2; - dl_ch_mag0_128b+=2; - dl_ch_mag1_128b+=2; - rxdataF128+=2; - rxdataF_comp0_128+=2; - rxdataF_comp1_128+=2; + dl_ch0_128+=2; + dl_ch1_128+=2; + dl_ch_mag0_128+=2; + dl_ch_mag1_128+=2; + dl_ch_mag0_128b+=2; + dl_ch_mag1_128b+=2; + rxdataF128+=2; + rxdataF_comp0_128+=2; + rxdataF_comp1_128+=2; } - Nre = (pilots==0) ? 12 : 8; - - precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); - - precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); } // rb loop + Nre = (pilots==0) ? 12 : 8; + + precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); + + precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); } // rx_antennas phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,phy_measurements->n0_power_tot); phy_measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,phy_measurements->n0_power_tot); - - //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, - // phy_measurements->precoded_cqi_dB[eNB_id][0]); + + // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, + // phy_measurements->precoded_cqi_dB[eNB_id][0]); _mm_empty(); _m_empty(); } + + void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, unsigned char symbol, unsigned short nb_rb, @@ -1780,30 +1995,30 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - dl_ch128+=3; - dl_ch128i+=3; - dl_ch_rho128+=3; + dl_ch128+=3; + dl_ch128i+=3; + dl_ch_rho128+=3; } else { - dl_ch128+=2; - dl_ch128i+=2; - dl_ch_rho128+=2; + dl_ch128+=2; + dl_ch128i+=2; + dl_ch_rho128+=2; } - } + } } _mm_empty(); @@ -1840,9 +2055,14 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) for (i=0;iN_RB_DL*12]; rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; for (i=0;iN_RB_DL*12]; dl_ch_mag128_i1b = (__m128i *)&dl_ch_magb_i[1][symbol*frame_parms->N_RB_DL*12]; for (i=0;irxdataF_comp0; + int **rxdataF_comp1 =lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; + int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; + int **dl_ch_rho2_ext =lte_ue_pdsch_vars->dl_ch_rho2_ext; + int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; + int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; + int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; + int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; + + + if (frame_parms->nb_antennas_rx>1) { + + for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) { + + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; + + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0;iN_RB_DL*12]; + rho128_1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; + for (i=0;iN_RB_DL*12]; + rho128_i1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i1 = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i0b = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i1b = (__m128i *)&dl_ch_magb1[1][symbol*frame_parms->N_RB_DL*12]; + for (i=0;isqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); + +ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); - // LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); + LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 - - for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) { + for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) { for (aarx=0;aarxnb_antennas_rx;aarx++) { dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0;rbN_RB_DL*12]; for (rb=0;rbNcp-1)))&&(frame_parms->mode1_flag==0)) { - dl_ch128+=2; - } - else { - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); - dl_ch128+=3; - } - /* - if (rb==0) { - print_shorts("dl_ch128",&dl_ch128[0]); - print_shorts("dl_ch128",&dl_ch128[1]); - print_shorts("dl_ch128",&dl_ch128[2]); - } - */ + // printf("rb %d : ",rb); + // print_shorts("ch",&dl_ch128[0]); + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) { + dl_ch128+=2; + } + else { + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); + dl_ch128+=3; + } + /* + if (rb==0) { + print_shorts("dl_ch128",&dl_ch128[0]); + print_shorts("dl_ch128",&dl_ch128[1]); + print_shorts("dl_ch128",&dl_ch128[2]); + } + */ } if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) - nre=8; + nre=8; else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1)) - nre=10; + nre=10; else - nre=12; + nre=12; avg[(aatx<<1)+aarx] = (((int*)&avg128D)[0] + - ((int*)&avg128D)[1] + - ((int*)&avg128D)[2] + - ((int*)&avg128D)[3])/(nb_rb*nre); + ((int*)&avg128D)[1] + + ((int*)&avg128D)[2] + + ((int*)&avg128D)[3])/(nb_rb*nre); // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); } @@ -1991,11 +2298,12 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, } //compute average channel_level of effective (precoded) channel -void dlsch_channel_level_TM3(int **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - int *avg, - uint8_t symbol, - unsigned short nb_rb){ +void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + int *avg, + uint8_t symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode){ short rb; unsigned char aarx,nre=12,symbol_mod; @@ -2025,31 +2333,49 @@ void dlsch_channel_level_TM3(int **dl_ch_estimates_ext, dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]); - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + // mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]); - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + // mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) { - dl_ch0_128+=2; - dl_ch1_128+=2; + dl_ch0_128+=2; + dl_ch1_128+=2; } else { - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); + dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); + dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); - // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - dl_ch0_128+=3; - dl_ch1_128+=3; + // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + dl_ch0_128+=3; + dl_ch1_128+=3; } } avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + @@ -2112,19 +2438,19 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) { - dl_ch0_128+=2; - dl_ch1_128+=2; + dl_ch0_128+=2; + dl_ch1_128+=2; } else { - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); + dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); + dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); - // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - dl_ch0_128+=3; - dl_ch1_128+=3; + dl_ch0_128+=3; + dl_ch1_128+=3; } } avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + @@ -2264,7 +2590,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, unsigned int *rb_alloc, unsigned char symbol, unsigned char subframe, - uint32_t high_speed_flag, + uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms) { @@ -2307,420 +2633,420 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs for (rb=0;rbN_RB_DL;rb++) { - - if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; - else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; - else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; - else if (rb < 100) - rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; - else - rb_alloc_ind = 0; - - // For second half of RBs skip DC carrier - if (rb==(frame_parms->N_RB_DL>>1)) { - rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; - //dl_ch0++; - } - - if (rb_alloc_ind==1) { - *pmi_ext = (pmi>>((rb>>2)<<1))&3; - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - /* - printf("rb %d\n",rb); - for (i=0;i<12;i++) - printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]); - printf("\n"); - */ - if (pilots==0) { - for (i=0;i<12;i++) { - rxF_ext[i]=rxF[i]; - /* - printf("%d : (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]), - ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/ - } - dl_ch0_ext+=12; - rxF_ext+=12; - } - else { - j=0; - for (i=0;i<12;i++) { - if ((i!=(frame_parms->nushift+poffset)) && - (i!=((frame_parms->nushift+poffset+6)%12))) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - - } - } - dl_ch0_ext+=10; - rxF_ext+=10; - } - nb_rb++; - } - dl_ch0+=12; - rxF+=12; + + if (rb < 32) + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + else if (rb < 64) + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + else if (rb < 96) + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + else if (rb < 100) + rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; + else + rb_alloc_ind = 0; + + // For second half of RBs skip DC carrier + if (rb==(frame_parms->N_RB_DL>>1)) { + rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; + //dl_ch0++; + } + + if (rb_alloc_ind==1) { + *pmi_ext = (pmi>>((rb>>2)<<1))&3; + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); + /* + printf("rb %d\n",rb); + for (i=0;i<12;i++) + printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]); + printf("\n"); + */ + if (pilots==0) { + for (i=0;i<12;i++) { + rxF_ext[i]=rxF[i]; + /* + printf("%d : (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]), + ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/ + } + dl_ch0_ext+=12; + rxF_ext+=12; + } + else { + j=0; + for (i=0;i<12;i++) { + if ((i!=(frame_parms->nushift+poffset)) && + (i!=((frame_parms->nushift+poffset+6)%12))) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + + } + } + dl_ch0_ext+=10; + rxF_ext+=10; + } + nb_rb++; + } + dl_ch0+=12; + rxF+=12; } else { // Odd number of RBs for (rb=0;rbN_RB_DL>>1;rb++) { - // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); - skip_half=0; - if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; - else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; - else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; - else if (rb < 100) - rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; - else - rb_alloc_ind = 0; + // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); + skip_half=0; + if (rb < 32) + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + else if (rb < 64) + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + else if (rb < 96) + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + else if (rb < 100) + rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; + else + rb_alloc_ind = 0; - // PBCH - if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; - } - //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 - if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=1; - else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=2; - - //SSS + // PBCH + if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { + rb_alloc_ind = 0; + } + //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 + if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=1; + else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=2; + + //SSS - if (((subframe==0)||(subframe==5)) && - (rb>((frame_parms->N_RB_DL>>1)-3)) && - (rb<((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb) ) { - rb_alloc_ind = 0; - } - //SSS - if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)-3)) && - (l==sss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb)) - skip_half=2; + if (((subframe==0)||(subframe==5)) && + (rb>((frame_parms->N_RB_DL>>1)-3)) && + (rb<((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb) ) { + rb_alloc_ind = 0; + } + //SSS + if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)-3)) && + (l==sss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb)) + skip_half=2; - //PSS in subframe 0/5 if FDD - if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } - - if ((frame_parms->frame_type == TDD) && - (subframe==6)){ //TDD Subframe 6 - if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } + //PSS in subframe 0/5 if FDD + if (frame_parms->frame_type == FDD) { //FDD + if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } + + if ((frame_parms->frame_type == TDD) && + (subframe==6)){ //TDD Subframe 6 + if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } - if (rb_alloc_ind==1) { - // printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); + if (rb_alloc_ind==1) { + // printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); - if (pilots==0) { - // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); - if (skip_half==1) { - memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[i]; - dl_ch0_ext+=6; - rxF_ext+=6; - } - else if (skip_half==2) { - memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[(i+6)]; - dl_ch0_ext+=6; - rxF_ext+=6; - } - else { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - for (i=0;i<12;i++) - rxF_ext[i]=rxF[i]; - dl_ch0_ext+=12; - rxF_ext+=12; - } - } - else { - // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); - j=0; - if (skip_half==1) { - for (i=0;i<6;i++) { - if (i!=((frame_parms->nushift+poffset)%6)) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - } - } - dl_ch0_ext+=5; - rxF_ext+=5; - } - else if (skip_half==2) { - for (i=0;i<6;i++) { - if (i!=((frame_parms->nushift+poffset)%6)) { - rxF_ext[j]=rxF[(i+6)]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i+6]; - } - } - dl_ch0_ext+=5; - rxF_ext+=5; - } - else { - for (i=0;i<12;i++) { - if ((i!=(frame_parms->nushift+poffset)) && - (i!=((frame_parms->nushift+poffset+6)%12))) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - - } - } - dl_ch0_ext+=10; - rxF_ext+=10; - } - } - nb_rb++; - } - dl_ch0+=12; - rxF+=12; + if (pilots==0) { + // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + if (skip_half==1) { + memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[i]; + dl_ch0_ext+=6; + rxF_ext+=6; + } + else if (skip_half==2) { + memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[(i+6)]; + dl_ch0_ext+=6; + rxF_ext+=6; + } + else { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); + for (i=0;i<12;i++) + rxF_ext[i]=rxF[i]; + dl_ch0_ext+=12; + rxF_ext+=12; + } + } + else { + // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + j=0; + if (skip_half==1) { + for (i=0;i<6;i++) { + if (i!=((frame_parms->nushift+poffset)%6)) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + } + } + dl_ch0_ext+=5; + rxF_ext+=5; + } + else if (skip_half==2) { + for (i=0;i<6;i++) { + if (i!=((frame_parms->nushift+poffset)%6)) { + rxF_ext[j]=rxF[(i+6)]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i+6]; + } + } + dl_ch0_ext+=5; + rxF_ext+=5; + } + else { + for (i=0;i<12;i++) { + if ((i!=(frame_parms->nushift+poffset)) && + (i!=((frame_parms->nushift+poffset+6)%12))) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + + } + } + dl_ch0_ext+=10; + rxF_ext+=10; + } + } + nb_rb++; + } + dl_ch0+=12; + rxF+=12; } // first half loop // Do middle RB (around DC) if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; else if (rb < 100) - rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; + rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; else - rb_alloc_ind = 0; + rb_alloc_ind = 0; // PBCH if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; + rb_alloc_ind = 0; } //SSS if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { - rb_alloc_ind = 0; + rb_alloc_ind = 0; } if (frame_parms->frame_type == FDD) { - //PSS - if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } + //PSS + if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } } if ((frame_parms->frame_type == TDD) && - (subframe==6)){ - //PSS - if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } + (subframe==6)){ + //PSS + if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } } - // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); + // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); // printf("DC rb %d (%p)\n",rb,rxF); if (rb_alloc_ind==1) { - // printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); - if (pilots==0) { - for (i=0;i<6;i++) { - dl_ch0_ext[i]=dl_ch0[i]; - rxF_ext[i]=rxF[i]; - } - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; - for (;i<12;i++) { - dl_ch0_ext[i]=dl_ch0[i]; - rxF_ext[i]=rxF[(1+i-6)]; - } - dl_ch0_ext+=12; - rxF_ext+=12; - } - else { // pilots==1 - j=0; - for (i=0;i<6;i++) { - if (i!=((frame_parms->nushift+poffset)%6)) { - dl_ch0_ext[j]=dl_ch0[i]; - rxF_ext[j++]=rxF[i]; - // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); - } - } - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; - for (;i<12;i++) { - if (i!=((frame_parms->nushift+6+poffset)%12)) { - dl_ch0_ext[j]=dl_ch0[i]; - rxF_ext[j++]=rxF[(1+i-6)]; - // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); - } - } - dl_ch0_ext+=10; - rxF_ext+=10; - } // symbol_mod==0 - nb_rb++; + // printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); + if (pilots==0) { + for (i=0;i<6;i++) { + dl_ch0_ext[i]=dl_ch0[i]; + rxF_ext[i]=rxF[i]; + } + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + for (;i<12;i++) { + dl_ch0_ext[i]=dl_ch0[i]; + rxF_ext[i]=rxF[(1+i-6)]; + } + dl_ch0_ext+=12; + rxF_ext+=12; + } + else { // pilots==1 + j=0; + for (i=0;i<6;i++) { + if (i!=((frame_parms->nushift+poffset)%6)) { + dl_ch0_ext[j]=dl_ch0[i]; + rxF_ext[j++]=rxF[i]; + // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + } + } + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + for (;i<12;i++) { + if (i!=((frame_parms->nushift+6+poffset)%12)) { + dl_ch0_ext[j]=dl_ch0[i]; + rxF_ext[j++]=rxF[(1+i-6)]; + // printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + } + } + dl_ch0_ext+=10; + rxF_ext+=10; + } // symbol_mod==0 + nb_rb++; } // rballoc==1 else { - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; } dl_ch0+=12; rxF+=7; rb++; for (;rbN_RB_DL;rb++) { - // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); - // printf("rb %d (%p)\n",rb,rxF); - skip_half=0; - if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; - else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; - else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; - else if (rb < 100) - rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; - else - rb_alloc_ind = 0; + // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); + // printf("rb %d (%p)\n",rb,rxF); + skip_half=0; + if (rb < 32) + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + else if (rb < 64) + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + else if (rb < 96) + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + else if (rb < 100) + rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; + else + rb_alloc_ind = 0; - // PBCH - if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; - } - //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 - if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=1; - else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=2; - //SSS - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { - rb_alloc_ind = 0; - } - //SSS - if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb)) - skip_half=2; + // PBCH + if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) { + rb_alloc_ind = 0; + } + //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 + if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=1; + else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=2; + //SSS + if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { + rb_alloc_ind = 0; + } + //SSS + if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb)) + skip_half=2; - if (frame_parms->frame_type == FDD) { - //PSS - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - //PSS - if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } + if (frame_parms->frame_type == FDD) { + //PSS + if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + //PSS + if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } - if ((frame_parms->frame_type == TDD) && - (subframe==6)){ //TDD Subframe 6 - if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } - - if (rb_alloc_ind==1) { - // printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); - /* - printf("rb %d\n",rb); - for (i=0;i<12;i++) - printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]); - printf("\n"); - */ - if (pilots==0) { - // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); - if (skip_half==1) { - memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[i]; - dl_ch0_ext+=6; - rxF_ext+=6; + if ((frame_parms->frame_type == TDD) && + (subframe==6)){ //TDD Subframe 6 + if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } + + if (rb_alloc_ind==1) { + // printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); + /* + printf("rb %d\n",rb); + for (i=0;i<12;i++) + printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]); + printf("\n"); + */ + if (pilots==0) { + // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + if (skip_half==1) { + memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[i]; + dl_ch0_ext+=6; + rxF_ext+=6; - } - else if (skip_half==2) { - memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[(i+6)]; - dl_ch0_ext+=6; - rxF_ext+=6; + } + else if (skip_half==2) { + memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[(i+6)]; + dl_ch0_ext+=6; + rxF_ext+=6; - } - else { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - for (i=0;i<12;i++) - rxF_ext[i]=rxF[i]; - dl_ch0_ext+=12; - rxF_ext+=12; - } - } - else { - // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); - j=0; - if (skip_half==1) { - for (i=0;i<6;i++) { - if (i!=((frame_parms->nushift+poffset)%6)) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - } - } - dl_ch0_ext+=5; - rxF_ext+=5; - } - else if (skip_half==2) { - for (i=0;i<6;i++) { - if (i!=((frame_parms->nushift+poffset)%6)) { - rxF_ext[j]=rxF[(i+6)]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i+6]; - } - } - dl_ch0_ext+=5; - rxF_ext+=5; - } - else { - for (i=0;i<12;i++) { - if ((i!=(frame_parms->nushift+poffset)) && - (i!=((frame_parms->nushift+poffset+6)%12))) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j++]=dl_ch0[i]; - } - } - dl_ch0_ext+=10; - rxF_ext+=10; - } - } // pilots=0 - nb_rb++; - } - dl_ch0+=12; - rxF+=12; + } + else { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); + for (i=0;i<12;i++) + rxF_ext[i]=rxF[i]; + dl_ch0_ext+=12; + rxF_ext+=12; + } + } + else { + // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + j=0; + if (skip_half==1) { + for (i=0;i<6;i++) { + if (i!=((frame_parms->nushift+poffset)%6)) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + } + } + dl_ch0_ext+=5; + rxF_ext+=5; + } + else if (skip_half==2) { + for (i=0;i<6;i++) { + if (i!=((frame_parms->nushift+poffset)%6)) { + rxF_ext[j]=rxF[(i+6)]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i+6]; + } + } + dl_ch0_ext+=5; + rxF_ext+=5; + } + else { + for (i=0;i<12;i++) { + if ((i!=(frame_parms->nushift+poffset)) && + (i!=((frame_parms->nushift+poffset+6)%12))) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j++]=dl_ch0[i]; + } + } + dl_ch0_ext+=10; + rxF_ext+=10; + } + } // pilots=0 + nb_rb++; + } + dl_ch0+=12; + rxF+=12; } } } @@ -2740,7 +3066,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, unsigned int *rb_alloc, unsigned char symbol, unsigned char subframe, - uint32_t high_speed_flag, + uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms) { @@ -2787,284 +3113,284 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs for (rb=0;rbN_RB_DL;rb++) { - skip_half=0; - if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; - else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; - else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; - else if (rb < 100) - rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; - else - rb_alloc_ind = 0; - - // For second half of RBs skip DC carrier - if (rb==(frame_parms->N_RB_DL>>1)) { - rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; - //dl_ch0++; - //dl_ch1++; - } + skip_half=0; + if (rb < 32) + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + else if (rb < 64) + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + else if (rb < 96) + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + else if (rb < 100) + rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; + else + rb_alloc_ind = 0; + + // For second half of RBs skip DC carrier + if (rb==(frame_parms->N_RB_DL>>1)) { + rxF = &rxdataF[aarx][(1 + (symbol*(frame_parms->ofdm_symbol_size)))]; + //dl_ch0++; + //dl_ch1++; + } - // PBCH - if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; - } - - //SSS + // PBCH + if ((subframe==0) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { + rb_alloc_ind = 0; + } + + //SSS - if (((subframe==0)||(subframe==5)) && - (rb>=((frame_parms->N_RB_DL>>1)-3)) && - (rb<((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb) ) { - rb_alloc_ind = 0; - } + if (((subframe==0)||(subframe==5)) && + (rb>=((frame_parms->N_RB_DL>>1)-3)) && + (rb<((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb) ) { + rb_alloc_ind = 0; + } - //PSS in subframe 0/5 if FDD - if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - } - - if ((frame_parms->frame_type == TDD) && - (subframe==6)){ //TDD Subframe 6 - if ((rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - } + //PSS in subframe 0/5 if FDD + if (frame_parms->frame_type == FDD) { //FDD + if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + } + + if ((frame_parms->frame_type == TDD) && + (subframe==6)){ //TDD Subframe 6 + if ((rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + } - if (rb_alloc_ind==1) { + if (rb_alloc_ind==1) { //printf("demod: rb %d\n",rb); - *pmi_loc = (pmi>>((rb>>2)<<1))&3; - // printf("rb %d: sb %d : pmi %d\n",rb,rb>>2,*pmi_loc); + *pmi_loc = (pmi>>((rb>>2)<<1))&3; + // printf("rb %d: sb %d : pmi %d\n",rb,rb>>2,*pmi_loc); - pmi_loc++; + pmi_loc++; - if (pilots == 0) { + if (pilots == 0) { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); - /* - printf("rb %d\n",rb); - for (i=0;i<12;i++) - printf("(%d %d)",((short *)dl_ch)[i<<1],((short*)dl_ch)[1+(i<<1)]); - printf("\n");*/ - - for (i=0;i<12;i++) { - rxF_ext[i]=rxF[i]; - // printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[(aatx<<1)+aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2, - // ((short*)&rxF[i<<1])[0],((short*)&rxF[i<<1])[0]); - } - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - } - else { - j=0; - for (i=0;i<12;i++) { - if ((i!=frame_parms->nushift) && - (i!=frame_parms->nushift+3) && - (i!=frame_parms->nushift+6) && - (i!=((frame_parms->nushift+9)%12))) { - rxF_ext[j]=rxF[i]; - // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - } - } - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - } // pilots==1 - - nb_rb++; + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); + memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); + /* + printf("rb %d\n",rb); + for (i=0;i<12;i++) + printf("(%d %d)",((short *)dl_ch)[i<<1],((short*)dl_ch)[1+(i<<1)]); + printf("\n");*/ + + for (i=0;i<12;i++) { + rxF_ext[i]=rxF[i]; + // printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[(aatx<<1)+aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2, + // ((short*)&rxF[i<<1])[0],((short*)&rxF[i<<1])[0]); + } + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + } + else { + j=0; + for (i=0;i<12;i++) { + if ((i!=frame_parms->nushift) && + (i!=frame_parms->nushift+3) && + (i!=frame_parms->nushift+6) && + (i!=((frame_parms->nushift+9)%12))) { + rxF_ext[j]=rxF[i]; + // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + } + } + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + } // pilots==1 + + nb_rb++; - } - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; + } + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; } else { // Odd number of RBs for (rb=0;rbN_RB_DL>>1;rb++) { - skip_half=0; - if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; - else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; - else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; - else if (rb < 100) - rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; - else - rb_alloc_ind = 0; + skip_half=0; + if (rb < 32) + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + else if (rb < 64) + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + else if (rb < 96) + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + else if (rb < 100) + rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; + else + rb_alloc_ind = 0; - // PBCH - if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; - } - //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 - if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=1; - else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=2; - - //SSS + // PBCH + if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { + rb_alloc_ind = 0; + } + //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 + if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=1; + else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=2; + + //SSS - if (((subframe==0)||(subframe==5)) && - (rb>((frame_parms->N_RB_DL>>1)-3)) && - (rb<((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb) ) { - rb_alloc_ind = 0; - } - //SSS - if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)-3)) && - (l==sss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb)) - skip_half=2; - - //PSS in subframe 0/5 if FDD - if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } - - if ((frame_parms->frame_type == TDD) && - (subframe==6)){ //TDD Subframe 6 - if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } - // printf("rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p)\n",rb,rb_alloc_ind,skip_half,rxF,rxF_ext); + if (((subframe==0)||(subframe==5)) && + (rb>((frame_parms->N_RB_DL>>1)-3)) && + (rb<((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb) ) { + rb_alloc_ind = 0; + } + //SSS + if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)-3)) && + (l==sss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb)) + skip_half=2; + + //PSS in subframe 0/5 if FDD + if (frame_parms->frame_type == FDD) { //FDD + if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } + + if ((frame_parms->frame_type == TDD) && + (subframe==6)){ //TDD Subframe 6 + if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } + // printf("rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p)\n",rb,rb_alloc_ind,skip_half,rxF,rxF_ext); - if (rb_alloc_ind==1) { + if (rb_alloc_ind==1) { - *pmi_loc = (pmi>>((rb>>2)<<1))&3; - // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); - - pmi_loc++; - if (pilots==0) { - if (skip_half==1) { - memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[i]; - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - } - else if (skip_half==2) { - memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1+6,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[(i+6)]; - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - } - else { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); - for (i=0;i<12;i++) - rxF_ext[i]=rxF[i]; - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - } - } - else { // pilots=1 - j=0; - if (skip_half==1) { - for (i=0;i<6;i++) { - if ((i!=frame_parms->nushift) && - (i!=((frame_parms->nushift+3)%6))) { - rxF_ext[j]=rxF[i]; - // printf("(pilots,skip1)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - } - } - dl_ch0_ext+=4; - dl_ch1_ext+=4; - rxF_ext+=4; - } - else if (skip_half==2) { - for (i=0;i<6;i++) { - if ((i!=frame_parms->nushift) && - (i!=((frame_parms->nushift+3)%6))) { - rxF_ext[j]=rxF[(i+6)]; - // printf("(pilots,skip2)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i+6]; - dl_ch1_ext[j++]=dl_ch1[i+6]; - } - - dl_ch0_ext+=4; - dl_ch1_ext+=4; - rxF_ext+=4; - } - } - else { - for (i=0;i<12;i++) { - if ((i!=frame_parms->nushift) && - (i!=frame_parms->nushift+3) && - (i!=frame_parms->nushift+6) && - (i!=((frame_parms->nushift+9)%12))) { - rxF_ext[j]=rxF[i]; - // printf("(pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - - dl_ch0_ext[j] =dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - - // printf("extract rb %d, re %d => ch0 (%d,%d) ch1 (%d,%d)\n",rb,i, - // *(short *)&dl_ch0_ext[j-1],*(1+(short*)&dl_ch0_ext[j-1]), - // *(short *)&dl_ch1_ext[j-1],*(1+(short*)&dl_ch1_ext[j-1])); - } - } - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - } - } - nb_rb++; - } + *pmi_loc = (pmi>>((rb>>2)<<1))&3; + // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); + + pmi_loc++; + if (pilots==0) { + if (skip_half==1) { + memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); + memcpy(dl_ch1_ext,dl_ch1,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[i]; + dl_ch0_ext+=6; + dl_ch1_ext+=6; + rxF_ext+=6; + } + else if (skip_half==2) { + memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); + memcpy(dl_ch1_ext,dl_ch1+6,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[(i+6)]; + dl_ch0_ext+=6; + dl_ch1_ext+=6; + rxF_ext+=6; + } + else { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); + memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); + for (i=0;i<12;i++) + rxF_ext[i]=rxF[i]; + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + } + } + else { // pilots=1 + j=0; + if (skip_half==1) { + for (i=0;i<6;i++) { + if ((i!=frame_parms->nushift) && + (i!=((frame_parms->nushift+3)%6))) { + rxF_ext[j]=rxF[i]; + // printf("(pilots,skip1)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + } + } + dl_ch0_ext+=4; + dl_ch1_ext+=4; + rxF_ext+=4; + } + else if (skip_half==2) { + for (i=0;i<6;i++) { + if ((i!=frame_parms->nushift) && + (i!=((frame_parms->nushift+3)%6))) { + rxF_ext[j]=rxF[(i+6)]; + // printf("(pilots,skip2)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i+6]; + dl_ch1_ext[j++]=dl_ch1[i+6]; + } + + dl_ch0_ext+=4; + dl_ch1_ext+=4; + rxF_ext+=4; + } + } + else { + for (i=0;i<12;i++) { + if ((i!=frame_parms->nushift) && + (i!=frame_parms->nushift+3) && + (i!=frame_parms->nushift+6) && + (i!=((frame_parms->nushift+9)%12))) { + rxF_ext[j]=rxF[i]; + // printf("(pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + + dl_ch0_ext[j] =dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + + // printf("extract rb %d, re %d => ch0 (%d,%d) ch1 (%d,%d)\n",rb,i, + // *(short *)&dl_ch0_ext[j-1],*(1+(short*)&dl_ch0_ext[j-1]), + // *(short *)&dl_ch1_ext[j-1],*(1+(short*)&dl_ch1_ext[j-1])); + } + } + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + } + } + nb_rb++; + } - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; } // Do middle RB (around DC) if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; else if (rb < 100) - rb_alloc_ind = (rb_alloc[0]>>(rb-96)) & 1; + rb_alloc_ind = (rb_alloc[0]>>(rb-96)) & 1; else - rb_alloc_ind = 0; + rb_alloc_ind = 0; @@ -3072,82 +3398,82 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, // PBCH if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; + rb_alloc_ind = 0; } //SSS if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { - rb_alloc_ind = 0; + rb_alloc_ind = 0; } if (frame_parms->frame_type == FDD) { - //PSS - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } + //PSS + if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } } if ((frame_parms->frame_type == TDD) && - (subframe==6)){ - //PSS - if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } + (subframe==6)){ + //PSS + if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } } if (rb_alloc_ind==1) { - - *pmi_loc = (pmi>>((rb>>2)<<1))&3; - // printf("rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); - pmi_loc++; - - if (pilots==0) { - for (i=0;i<6;i++) { - dl_ch0_ext[i]=dl_ch0[i]; - dl_ch1_ext[i]=dl_ch1[i]; - rxF_ext[i]=rxF[i]; - } - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; - for (;i<12;i++) { - dl_ch0_ext[i]=dl_ch0[i]; - dl_ch1_ext[i]=dl_ch1[i]; - rxF_ext[i]=rxF[(1+i-6)]; - } - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - } - else { // pilots==1 - j=0; - for (i=0;i<6;i++) { - if ((i!=frame_parms->nushift) && - (i!=((frame_parms->nushift+3)%6))){ - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j]=dl_ch1[i]; - rxF_ext[j++]=rxF[i]; - // printf("(pilots center)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); - // printf("extract rb %d, re %d => ch0 (%d,%d) ch1 (%d,%d)\n",rb,i, - // *(short *)&dl_ch0_ext[j-1],*(1+(short*)&dl_ch0_ext[j-1]), - // *(short *)&dl_ch1_ext[j-1],*(1+(short*)&dl_ch1_ext[j-1])); - } - } - rxF = &rxdataF[aarx][symbol*(frame_parms->ofdm_symbol_size)]; - - for (;i<12;i++) { - if ((i!=((frame_parms->nushift+6)%12)) && - (i!=((frame_parms->nushift+9)%12))){ - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j]=dl_ch1[i]; - rxF_ext[j++]=rxF[(1+i-6)]; - } - } - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - } - nb_rb++; + + *pmi_loc = (pmi>>((rb>>2)<<1))&3; + // printf("rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); + pmi_loc++; + + if (pilots==0) { + for (i=0;i<6;i++) { + dl_ch0_ext[i]=dl_ch0[i]; + dl_ch1_ext[i]=dl_ch1[i]; + rxF_ext[i]=rxF[i]; + } + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + for (;i<12;i++) { + dl_ch0_ext[i]=dl_ch0[i]; + dl_ch1_ext[i]=dl_ch1[i]; + rxF_ext[i]=rxF[(1+i-6)]; + } + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + } + else { // pilots==1 + j=0; + for (i=0;i<6;i++) { + if ((i!=frame_parms->nushift) && + (i!=((frame_parms->nushift+3)%6))){ + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j]=dl_ch1[i]; + rxF_ext[j++]=rxF[i]; + // printf("(pilots center)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + // printf("extract rb %d, re %d => ch0 (%d,%d) ch1 (%d,%d)\n",rb,i, + // *(short *)&dl_ch0_ext[j-1],*(1+(short*)&dl_ch0_ext[j-1]), + // *(short *)&dl_ch1_ext[j-1],*(1+(short*)&dl_ch1_ext[j-1])); + } + } + rxF = &rxdataF[aarx][symbol*(frame_parms->ofdm_symbol_size)]; + + for (;i<12;i++) { + if ((i!=((frame_parms->nushift+6)%12)) && + (i!=((frame_parms->nushift+9)%12))){ + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j]=dl_ch1[i]; + rxF_ext[j++]=rxF[(1+i-6)]; + } + } + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + } + nb_rb++; } else { - rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; + rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; } dl_ch0+=12; dl_ch1+=12; @@ -3155,163 +3481,163 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rb++; for (;rbN_RB_DL;rb++) { - skip_half=0; - - if (rb < 32) - rb_alloc_ind = (rb_alloc[0]>>rb) & 1; - else if (rb < 64) - rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; - else if (rb < 96) - rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; - else if (rb < 100) - rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; - else - rb_alloc_ind = 0; - - - // PBCH - if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; - } - //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 - if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=1; - else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) - skip_half=2; + skip_half=0; + + if (rb < 32) + rb_alloc_ind = (rb_alloc[0]>>rb) & 1; + else if (rb < 64) + rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1; + else if (rb < 96) + rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1; + else if (rb < 100) + rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1; + else + rb_alloc_ind = 0; + + + // PBCH + if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { + rb_alloc_ind = 0; + } + //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 + if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=1; + else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) + skip_half=2; - //SSS - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { - rb_alloc_ind = 0; - } - //SSS - if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)-3)) && - (l==sss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb)) - skip_half=2; + //SSS + if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { + rb_alloc_ind = 0; + } + //SSS + if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)-3)) && + (l==sss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb)) + skip_half=2; - if (frame_parms->frame_type == FDD) { - //PSS - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; + if (frame_parms->frame_type == FDD) { + //PSS + if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; - } - if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } - - if ((frame_parms->frame_type == TDD) && - (subframe==6)){ - //PSS - if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { - rb_alloc_ind = 0; - } - if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) - skip_half=1; - else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) - skip_half=2; - } - - if (rb_alloc_ind==1) { - - *pmi_loc = (pmi>>((rb>>2)<<1))&3; - // printf("rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); - - pmi_loc++; - - if (pilots==0) { - if (skip_half==1) { - memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[i]; - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - - } - else if (skip_half==2) { - memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1+6,6*sizeof(int)); - for (i=0;i<6;i++) - rxF_ext[i]=rxF[(i+6)]; - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - - } - else { - memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); - for (i=0;i<12;i++) - rxF_ext[i]=rxF[i]; + } + if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } + + if ((frame_parms->frame_type == TDD) && + (subframe==6)){ + //PSS + if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { + rb_alloc_ind = 0; + } + if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) + skip_half=1; + else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) + skip_half=2; + } + + if (rb_alloc_ind==1) { + + *pmi_loc = (pmi>>((rb>>2)<<1))&3; + // printf("rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); + + pmi_loc++; + + if (pilots==0) { + if (skip_half==1) { + memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); + memcpy(dl_ch1_ext,dl_ch1,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[i]; + dl_ch0_ext+=6; + dl_ch1_ext+=6; + rxF_ext+=6; + + } + else if (skip_half==2) { + memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); + memcpy(dl_ch1_ext,dl_ch1+6,6*sizeof(int)); + for (i=0;i<6;i++) + rxF_ext[i]=rxF[(i+6)]; + dl_ch0_ext+=6; + dl_ch1_ext+=6; + rxF_ext+=6; + + } + else { + memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); + memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int)); + for (i=0;i<12;i++) + rxF_ext[i]=rxF[i]; - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - } - } - else { - j=0; - if (skip_half==1) { - for (i=0;i<6;i++) { - if ((i!=(frame_parms->nushift)) && - (i!=((frame_parms->nushift+3)%6))){ - rxF_ext[j]=rxF[i]; - // printf("(skip1,pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - } - } - dl_ch0_ext+=4; - dl_ch1_ext+=4; - rxF_ext+=4; - } - else if (skip_half==2) { - for (i=0;i<6;i++) { - if ((i!=(frame_parms->nushift)) && - (i!=((frame_parms->nushift+3)%6))){ - rxF_ext[j]=rxF[(i+6)]; - // printf("(skip2,pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i+6]; - dl_ch1_ext[j++]=dl_ch1[i+6]; - } - } - dl_ch0_ext+=4; - dl_ch1_ext+=4; - rxF_ext+=4; - } - else { - for (i=0;i<12;i++) { - if ((i!=frame_parms->nushift) && - (i!=frame_parms->nushift+3) && - (i!=frame_parms->nushift+6) && - (i!=((frame_parms->nushift+9)%12))) { - rxF_ext[j]=rxF[i]; - // printf("(pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); - dl_ch0_ext[j]=dl_ch0[i]; - dl_ch1_ext[j++]=dl_ch1[i]; - // printf("extract rb %d, re %d => ch0 (%d,%d) ch1 (%d,%d)\n",rb,i, - // *(short *)&dl_ch0_ext[j-1],*(1+(short*)&dl_ch0_ext[j-1]), - // *(short *)&dl_ch1_ext[j-1],*(1+(short*)&dl_ch1_ext[j-1])); - } - } - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - - } - } - nb_rb++; - } - dl_ch0+=12; - dl_ch1+=12; - rxF+=12; + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + } + } + else { + j=0; + if (skip_half==1) { + for (i=0;i<6;i++) { + if ((i!=(frame_parms->nushift)) && + (i!=((frame_parms->nushift+3)%6))){ + rxF_ext[j]=rxF[i]; + // printf("(skip1,pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + } + } + dl_ch0_ext+=4; + dl_ch1_ext+=4; + rxF_ext+=4; + } + else if (skip_half==2) { + for (i=0;i<6;i++) { + if ((i!=(frame_parms->nushift)) && + (i!=((frame_parms->nushift+3)%6))){ + rxF_ext[j]=rxF[(i+6)]; + // printf("(skip2,pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i+6]; + dl_ch1_ext[j++]=dl_ch1[i+6]; + } + } + dl_ch0_ext+=4; + dl_ch1_ext+=4; + rxF_ext+=4; + } + else { + for (i=0;i<12;i++) { + if ((i!=frame_parms->nushift) && + (i!=frame_parms->nushift+3) && + (i!=frame_parms->nushift+6) && + (i!=((frame_parms->nushift+9)%12))) { + rxF_ext[j]=rxF[i]; + // printf("(pilots)extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + dl_ch0_ext[j]=dl_ch0[i]; + dl_ch1_ext[j++]=dl_ch1[i]; + // printf("extract rb %d, re %d => ch0 (%d,%d) ch1 (%d,%d)\n",rb,i, + // *(short *)&dl_ch0_ext[j-1],*(1+(short*)&dl_ch0_ext[j-1]), + // *(short *)&dl_ch1_ext[j-1],*(1+(short*)&dl_ch1_ext[j-1])); + } + } + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + + } + } + nb_rb++; + } + dl_ch0+=12; + dl_ch1+=12; + rxF+=12; } } } @@ -3329,7 +3655,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, #ifdef USER_MODE -void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round) { +void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid ) { unsigned int nsymb = (phy_vars_ue->lte_frame_parms.Ncp == 0) ? 14 : 12; char fname[32],vname[32]; @@ -3368,7 +3694,7 @@ void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per */ sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round); sprintf(vname,"dl_rho_r%d_%d",eNB_id,round); - write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0][0],12*N_RB_DL*nsymb,1,1); sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round); @@ -3377,7 +3703,7 @@ void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per if (phy_vars_ue->lte_frame_parms.nb_antennas_tx_eNB == 2) { sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round); - write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[0][round],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); } sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 7fa6bddcab..d1ef184e7f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -642,7 +642,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr32p) { - uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; uint32_t *llr32; int i,len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -698,7 +698,7 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, int16_t **llr32p) { - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + __m128i *rxF = (__m128i*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; __m128i *ch_mag; __m128i llr128[2]; int i,len; @@ -715,7 +715,7 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; + ch_mag = (__m128i*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { if (frame_parms->mode1_flag==0) @@ -774,7 +774,7 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr_save) { - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + __m128i *rxF = (__m128i*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; __m128i *ch_mag,*ch_magb; int i,len,len2; unsigned char symbol_mod,len_mod4; @@ -788,8 +788,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; + ch_mag = (__m128i*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + ch_magb = (__m128i*)&dl_ch_magb[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { if (frame_parms->mode1_flag==0) @@ -902,9 +902,9 @@ int dlsch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF=(int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho=(int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -935,7 +935,7 @@ int dlsch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } - // printf("qpsk_qpsk: len %d, llr16 %p\n",len,llr16); + //printf("qpsk_qpsk: len %d, llr16 %p, rho %p\n",len,llr16,rho); qpsk_qpsk((short *)rxF, (short *)rxF_i, (short *)llr16, @@ -981,6 +981,7 @@ length = number of resource elements ONE_OVER_SQRT_8 = _mm_set1_epi16(23170); //round(2^16/sqrt(8)) for (i=0;i>2;i+=2) { + //printf("%d.",i); // in each iteration, we take 8 complex samples xmm0 = rho01_128i[i]; // 4 symbols @@ -1115,6 +1116,7 @@ length = number of resource elements _mm_storeu_si128(&stream0_128i_out[i+1],_mm_unpackhi_epi16(y0r,y0i)); } + //printf("\n"); _mm_empty(); _m_empty(); } @@ -1131,10 +1133,10 @@ int dlsch_qpsk_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF=(int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho=(int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -1390,10 +1392,10 @@ int dlsch_qpsk_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF=(int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho=(int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -2077,10 +2079,10 @@ int dlsch_16qam_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF = (int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho = (int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -2580,11 +2582,11 @@ int dlsch_16qam_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF = (int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho = (int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -3112,11 +3114,11 @@ int dlsch_16qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF = (int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho = (int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -4456,10 +4458,10 @@ int dlsch_64qam_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF = (int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho = (int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -5718,11 +5720,11 @@ int dlsch_64qam_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF = (int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho = (int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; @@ -7108,11 +7110,11 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr16p) { - int16_t *rxF = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)]; - int16_t *rho = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)]; + int16_t *rxF = (int16_t*)&rxdataF_comp[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rxF_i = (int16_t*)&rxdataF_comp_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag = (int16_t*)&dl_ch_mag[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; + int16_t *rho = (int16_t*)&rho_i[0][(((int)symbol)*((int)frame_parms->N_RB_DL)*12)]; int16_t *llr16; int len; uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 6e4c7803d4..15b5db72e8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -155,15 +155,14 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, int first_layer0 = dlsch0_harq->first_layer; int Nlayers0 = dlsch0_harq->Nlayers; uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs); - + uint8_t mod_order1=2; + uint8_t precoder_index0,precoder_index1; uint8_t *x1=NULL; - uint8_t mod_order1=2; // Fill these in later for TM8-10 // int Nlayers1; // int first_layer1; - int use2ndpilots = (frame_parms->mode1_flag==1)?1:0; uint32_t tti_offset,aa; @@ -642,7 +641,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } } else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) { - // this is for transmission modes 4-6 (1 layer) + // this is for transmission modes 5-6 (1 layer) *re_allocated = *re_allocated + 1; amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); @@ -740,6 +739,214 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } } + else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) { + // this is for transmission mode 4 (1 layer) + *re_allocated = *re_allocated + 1; + //amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); + amp = tmp_amp/2; + gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); + + if (precoder_index==0) { + precoder_index0 = 0; //[1 1] + precoder_index1 = 1; //[1 -1] + } + else if (precoder_index==1) { + precoder_index0 = 2; //[1 j] + precoder_index1 = 3; //[1 -j] + } + else { + LOG_E(PHY,"problem with precoder in TM4\n"); + return(-1); + } + + switch (mod_order0) { + case 2: //QPSK + + ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; + ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; + + // normalization for 2 tx antennas + ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + } + + break; + + case 4: //16QAM + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; + + if (x0[*jj] == 1) + qam16_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=2; + *jj=*jj+1; + + + if (x0[*jj] == 1) + qam16_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + } + + break; + + case 6: //64QAM + + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + if (x0[*jj] == 1) + qam64_table_offset_re+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + } + + break; + + } + switch (mod_order1) { + case 2: //QPSK + + ((int16_t*)&tmp_sample1)[0] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj2 = *jj2 + 1; + ((int16_t*)&tmp_sample1)[1] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj2 = *jj2 + 1; + + // normalization for 2 tx antennas + ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + } + + break; + + case 4: //16QAM + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; + + if (x1[*jj2] == 1) + qam16_table_offset_re+=2; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam16_table_offset_im+=2; + *jj2=*jj2+1; + + + if (x1[*jj2] == 1) + qam16_table_offset_re+=1; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam16_table_offset_im+=1; + *jj2=*jj2+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + } + + break; + + case 6: //64QAM + + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + if (x1[*jj2] == 1) + qam64_table_offset_re+=4; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_im+=4; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_re+=2; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_im+=2; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_re+=1; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_im+=1; + *jj2=*jj2+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + } + + break; + + } + } + if (mimo_mode == ALAMOUTI) { re++; // adjacent carriers are taken care of by precoding *re_allocated = *re_allocated + 1; diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 5f7ffe1e2f..14f4614721 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -36,24 +36,27 @@ double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0}, { 5.0/4.0,1.0,3.0/4.0,1.0/2.0}}; */ -double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, +double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db { 0.96910, 0.00000, -1.24939, -3.01030}}; -double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; +double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by higher layers double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated) { return(pa_values[pdsch_config_dedicated->p_a]); } double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - LTE_eNB_DLSCH_t *dlsch_eNB,int dl_power_off){ + LTE_eNB_DLSCH_t *dlsch_eNB,int dl_power_off, uint8_t n_antenna_port){ double rho_a_dB; double sqrt_rho_a_lin; rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; - if(!dl_power_off) + if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5 rho_a_dB-=10*log10(2); + + if(n_antenna_port==4) // see TS 36.213 Section 5.2 + rho_a_dB=+10*log10(2); sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); @@ -75,7 +78,7 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB, rho_b_dB; double sqrt_rho_b_lin; - rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off); + rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off, n_antenna_port); if(n_antenna_port>1) rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; @@ -95,7 +98,9 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_UE_DLSCH_t *dlsch_ue, - unsigned char dl_power_off){ + unsigned char dl_power_off, + uint8_t n_antenna_port + ){ double rho_a_dB; double sqrt_rho_a_lin; @@ -103,7 +108,11 @@ double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; if(!dl_power_off) - rho_a_dB-=10*log10(2); + rho_a_dB-=10*log10(2); + //if dl_power_offset is 0, this is for MU-interference, TM5. But in practice UE may assume 16 or 64QAM TM4 as multiuser + + if(n_antenna_port==4) // see TS 36.213 Section 5.2 + rho_a_dB=+10*log10(2); sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); @@ -125,7 +134,7 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB, rho_b_dB; double sqrt_rho_b_lin; - rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off); + rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off, n_antenna_port); if(n_antenna_port>1) rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index e60b6abfe8..7b58cd701e 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -145,7 +145,7 @@ void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB, \brief Fills RB with data \param txdataF pointer to output data (frequency domain signal) \param jj index to output (from CW 1) - \param jj index to output (from CW 2) + \param jj2 index to output (from CW 2) \param re_offset index of the first RE of the RB \param symbol_offset index to the OFDM symbol \param dlsch0_harq Pointer to Transport block 0 HARQ structure @@ -833,6 +833,14 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, uint16_t nb_rb, uint8_t dual_stream_UE); +void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDSCH *lte_ue_pdsch_vars, + int harq_pid, + int round, + unsigned char symbol, + unsigned short nb_rb, + unsigned char dual_stream_UE); + /** \fn dlsch_extract_rbs_single(int32_t **rxdataF, int32_t **dl_ch_estimates, int32_t **rxdataF_ext, @@ -956,14 +964,16 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, unsigned char output_shift, unsigned char dl_power_off); -void dlsch_channel_compensation_TM3(LTE_DL_FRAME_PARMS *frame_parms, +void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_PDSCH *lte_ue_pdsch_vars, PHY_MEASUREMENTS *phy_measurements, int eNB_id, unsigned char symbol, unsigned char mod_order0, unsigned char mod_order1, + int harq_pid, int round, + MIMO_mode_t mimo_mode, unsigned short nb_rb, unsigned char output_shift); @@ -981,11 +991,12 @@ void dlsch_channel_level(int32_t **dl_ch_estimates_ext, uint8_t pilots_flag, uint16_t nb_rb); -void dlsch_channel_level_TM3(int **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - int *avg, - uint8_t symbol, - unsigned short nb_rb); +void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + int *avg, + uint8_t symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode); void dlsch_channel_level_TM56(int32_t **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, @@ -1038,6 +1049,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, - RE extraction (pilot, PBCH, synch. signals) - antenna combining (MRC, Alamouti, cycling) - LLR computation + This function supports TM1, 2, 3, 5, and 6. @param phy_vars_ue Pointer to PHY variables @param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH) @param eNB_id eNb index (Nid1) 0,1,2 @@ -1045,7 +1057,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, @param subframe Subframe number @param symbol Symbol on which to act (within sub-frame) @param first_symbol_flag set to 1 on first DLSCH symbol - @param dual_stream_UE Flag to indicate dual-stream interference cancellation + @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice. @param i_mod Modulation order of the interfering stream */ int32_t rx_pdsch(PHY_VARS_UE *phy_vars_ue, @@ -1055,7 +1067,7 @@ int32_t rx_pdsch(PHY_VARS_UE *phy_vars_ue, uint8_t subframe, uint8_t symbol, uint8_t first_symbol_flag, - uint8_t dual_stream_UE, + RX_type_t rx_type, uint8_t i_mod, uint8_t harq_pid); @@ -1407,7 +1419,7 @@ void dump_dlsch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint8_t void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe); void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe); -void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round); +void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round,uint8_t harq_pid ); #endif int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci); @@ -1740,7 +1752,8 @@ double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated); double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_eNB_DLSCH_t *dlsch_eNB, - int dl_power_off); + int dl_power_off, + uint8_t n_antenna_port); double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, PDSCH_CONFIG_COMMON *pdsch_config_common, @@ -1749,7 +1762,8 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_UE_DLSCH_t *dlsch_ue, - uint8_t dl_power_off); + uint8_t dl_power_off, + uint8_t n_antenna_port); double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, PDSCH_CONFIG_COMMON *pdsch_config_common, diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 3fb0f8244c..3ba2892706 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -319,10 +319,10 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui ); // Define form - fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 900 ); + fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 ); // This the whole UI box - obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" ); + obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" ); fl_set_object_color( obj, FL_BLACK, FL_BLACK ); // Received signal @@ -345,6 +345,7 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color fl_set_xyplot_ybounds( fdui->chest_f,30,70); + /* // LLR of PBCH fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX ); @@ -377,9 +378,11 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdcch_comp,2); fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR); + */ + int offset=240; // LLR of PDSCH - fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); + fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW ); fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color @@ -387,12 +390,28 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR); // I/Q PDSCH comp - fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output" ); + fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW ); fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdsch_comp,2); - + + // LLR of PDSCH + fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2); + fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR); + + // I/Q PDSCH comp + fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2); + + /* // Throughput on PDSCH fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" ); fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX ); @@ -408,6 +427,7 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { fl_set_object_color(fdui->button_0, FL_RED, FL_RED); fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 ); fl_hide_object(fdui->button_0); + */ fl_end_form( ); fdui->lte_phy_scope_ue->fdui = fdui; @@ -428,8 +448,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int16_t **rxsig_t; int16_t **chest_t; int16_t **chest_f; - int16_t *pdsch_llr; - int16_t *pdsch_comp; + int16_t *pdsch_llr,*pdsch_llr1; + int16_t *pdsch_comp,*pdsch_comp1; + int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1; int8_t *pdcch_llr; int16_t *pdcch_comp; int8_t *pbch_llr; @@ -444,19 +465,20 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx]; int frame = phy_vars_ue->frame_rx; uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id]; - int coded_bits_per_codeword = 0; - int mcs = 0; + int coded_bits_per_codeword=0,coded_bits_per_codeword1=1; + int mod,mod1; unsigned char harq_pid = 0; if (phy_vars_ue->dlsch_ue[eNB_id][0]!=NULL) { harq_pid = phy_vars_ue->dlsch_ue[eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs = phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 + /* if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { // we are in TM5 fl_show_object(form->button_0); } + */ } if (phy_vars_ue->lte_ue_pdcch_vars[eNB_id]!=NULL) { @@ -465,16 +487,32 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); if (phy_vars_ue->dlsch_ue[eNB_id][0]!=NULL) { - coded_bits_per_codeword = get_G(frame_parms, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc, - get_Qm(mcs), - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl, - num_pdcch_symbols, - frame, - subframe); + mod = get_Qm(phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs); + coded_bits_per_codeword = get_G(frame_parms, + phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc, + get_Qm(phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs), + phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe); } else { coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + mod=0; + } + if (phy_vars_ue->dlsch_ue[eNB_id][1]!=NULL) { + mod1 = get_Qm(phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->mcs); + coded_bits_per_codeword1 = get_G(frame_parms, + phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->rb_alloc, + get_Qm(phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->mcs), + phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe); + } else { + coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + mod1=0; } I = (float*) calloc(nsymb_ce*2,sizeof(float)); @@ -497,9 +535,19 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, pdcch_llr = (int8_t*) phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->llr; pdcch_comp = (int16_t*) phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0]; pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->llr[0]; // stream 0 - // pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0 + pdsch_llr1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->llr[1]; // stream 1 pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0]; + //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_ext[0]; + //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_ext[1]; + pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[0][0])[0]; + //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0]; + pdsch_mag0 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0[0]; + pdsch_mag1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[0]; + pdsch_magb0 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0[0]; + pdsch_magb1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[0]; + fl_freeze_form(form); + // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { if (rxsig_t[0] != NULL) { @@ -590,6 +638,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } } + /* // PBCH LLRs if (pbch_llr != NULL) { for (i=0; i<1920;i++) { @@ -630,16 +679,17 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); } + */ // PDSCH LLRs if (pdsch_llr != NULL) { - for (i=0; ipdsch_llr,0,coded_bits_per_codeword/4); - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword/4,"","",""); + fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword/mod); + fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword/mod,"","",""); } // PDSCH I/Q of MF Output @@ -654,7 +704,116 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","",""); } + + if (pdsch_mag0 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN); + } + if (pdsch_magb0 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED); + } + if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = + (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+ + pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])* + cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = + (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ + pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* + sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE); + } + + + // PDSCH LLRs + if (pdsch_llr1 != NULL) { + for (i=0; ipdsch_llr1,0,coded_bits_per_codeword1/mod1); + fl_set_xyplot_data(form->pdsch_llr1,bit,llr,coded_bits_per_codeword1/mod1,"","",""); + } + // PDSCH I/Q of MF Output + if (pdsch_comp1!=NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i]; + Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; + ind++; + } + } + fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","",""); + } + + if (pdsch_mag1 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN); + } + + if (pdsch_magb1 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED); + } + + if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = + (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+ + pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])* + cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = + (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ + pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* + sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE); + } + + + /* // PDSCH Throughput memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); @@ -669,6 +828,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","",""); fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); + */ + + fl_unfreeze_form(form); fl_check_forms(); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.h b/openair1/PHY/TOOLS/lte_phy_scope.h index e5fe841e5a..11e1d9b180 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.h +++ b/openair1/PHY/TOOLS/lte_phy_scope.h @@ -62,6 +62,8 @@ typedef struct { FL_OBJECT * pdcch_llr; FL_OBJECT * pdsch_comp; FL_OBJECT * pdsch_llr; + FL_OBJECT * pdsch_comp1; + FL_OBJECT * pdsch_llr1; FL_OBJECT * pdsch_tput; FL_OBJECT * button_0; } FD_lte_phy_scope_ue; diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index 8b657fac2f..2121c96259 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -795,19 +795,22 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ int32_t **rxdataF_comp0; - /// \brief Received frequency-domain signal after extraction and channel compensation. - /// - first index: ? [0..7] (hard coded) accessed via \c round - /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - third index: ? [0..168*N_RB_DL[ - int32_t **rxdataF_comp1[8]; + /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp1[8][8]; /// \brief Downlink channel estimates extracted in PRBS. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ int32_t **dl_ch_estimates_ext; - /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_rho_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho_ext[8][8]; /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 63fd6a23f1..fa7a7f2070 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -53,7 +53,6 @@ #include "SCHED/defs.h" #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" - #include "OCG_vars.h" #include "UTIL/LOG/log.h" #include "UTIL/LISTS/list.h" @@ -65,7 +64,7 @@ extern unsigned char offset_mumimo_llr_drange_fix; #include "PHY/TOOLS/lte_phy_scope.h" #endif - +#define PRINT_BYTES //#define AWGN //#define NO_DCI @@ -248,17 +247,19 @@ int main(int argc, char **argv) { double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel double iqim=0.0; - uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx=1,n_rx=2; + uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; - int eNB_id = 0, eNB_id_i = 1; - unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round,dci_flag=0; + int8_t eNB_id = 0, eNB_id_i = 1; + unsigned char mcs1=0,mcs2=0,mcs_i=0,awgn_flag=0,round,dci_flag=0; unsigned char i_mod = 2; unsigned short NB_RB; unsigned char Ns,l,m; uint16_t tdd_config=3; uint16_t n_rnti=0x1234; int n_users = 1; + RX_type_t rx_type=rx_standard; + SCM_t channel_model=Rayleigh1; // unsigned char *input_data,*decoded_output; @@ -268,15 +269,15 @@ int main(int argc, char **argv) { unsigned int ret; unsigned int coded_bits_per_codeword=0,nsymb,dci_cnt,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]={0,0,0,0},errs2[4]={0,0,0,0},round_trials[4]={0,0,0,0},dci_errors=0,dlsch_active=0,num_layers; + unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[2][4],round_trials[4]={0,0,0,0},dci_errors=0,dlsch_active=0,num_layers; int re_allocated; char fname[32],vname[32]; FILE *bler_fd; char bler_fname[256]; FILE *time_meas_fd; char time_meas_fname[256]; - FILE *tikz_fd; - char tikz_fname[256]; + //FILE *tikz_fd; + //char tikz_fname[256]; FILE *input_trch_fd=NULL; unsigned char input_trch_file=0; @@ -302,7 +303,7 @@ int main(int argc, char **argv) { uint8_t rx_sample_offset = 0; //char stats_buffer[4096]; //int len; - uint8_t num_rounds = 4,fix_rounds=0; + uint8_t num_rounds = 4; uint8_t subframe=7; int u; int n=0; @@ -317,18 +318,19 @@ int main(int argc, char **argv) { // void *data; // int ii; int bler; - double blerr[4],uncoded_ber,avg_ber; + double blerr[2][4],uncoded_ber,avg_ber; short *uncoded_ber_bit=NULL; uint8_t N_RB_DL=25,osf=1; uint8_t fdd_flag = 0; #ifdef XFORMS FD_lte_phy_scope_ue *form_ue; char title[255]; + int xforms = 0; #endif uint32_t DLSCH_RB_ALLOC = 0x1fff; int numCCE=0; int dci_length_bytes=0,dci_length=0; - double BW = 5.0; + double BW = 7.68; int common_flag=0,TPC=0; double cpu_freq_GHz; @@ -341,7 +343,7 @@ int main(int argc, char **argv) { int llr8_flag=0; double effective_rate=0.0; - char channel_model_input[10]="I"; + char channel_model_input[17]="I"; int TB0_active = 1; uint32_t perfect_ce = 0; @@ -350,6 +352,7 @@ int main(int argc, char **argv) { LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; uint8_t Kmimo; + mod_sym_t **sic_buffer; opp_enabled=1; // to enable the time meas @@ -361,6 +364,7 @@ int main(int argc, char **argv) { //signal(SIGABRT, handler); logInit(); + set_glog(LOG_INFO, LOG_MED); // default parameters n_frames = 1000; @@ -368,7 +372,7 @@ int main(int argc, char **argv) { num_layers = 1; perfect_ce = 0; - while ((c = getopt (argc, argv, "ahdpZDe:m:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:Y")) != -1) { + while ((c = getopt (argc, argv, "aAb:B:c:C:dDe:f:F:g:hi:I:l:Lm:M:n:N:o:O:pPr:R:s:S:t:T:u:v:w:x:Xy:Yz:Z")) != -1) { switch (c) { case 'a': @@ -435,7 +439,7 @@ int main(int argc, char **argv) { num_pdcch_symbols=atoi(optarg); break; case 'g': - memcpy(channel_model_input,optarg,10); + memcpy(channel_model_input,optarg,17); switch((char)*optarg) { case 'A': channel_model=SCM_A; @@ -479,6 +483,24 @@ int main(int argc, char **argv) { case 'N': channel_model=AWGN; break; + case 'P': + channel_model=Rayleigh1_orthogonal; + break; + case 'Q': + channel_model=Rayleigh1_orth_eff_ch_TM4_prec_real; // for DUALSTREAM_UNIFORM_PRECODING1 when interf is precancelled + break; + case 'R': + channel_model=Rayleigh1_orth_eff_ch_TM4_prec_imag; // for DUALSTREAM_UNIFORM_PRECODINGj when interf is precancelled + break; + case 'S': + channel_model=Rayleigh8_orth_eff_ch_TM4_prec_real;//when interf is precancelled + break; + case 'T': + channel_model=Rayleigh8_orth_eff_ch_TM4_prec_imag;//when interf is precancelled + break; + case 'U': + channel_model = TS_SHIFT; + break; default: msg("Unsupported channel model!\n"); exit(-1); @@ -489,6 +511,7 @@ int main(int argc, char **argv) { if ((transmission_mode!=1) && (transmission_mode!=2) && (transmission_mode!=3) && + (transmission_mode!=4) && (transmission_mode!=5) && (transmission_mode!=6)) { msg("Unsupported transmission mode %d\n",transmission_mode); @@ -536,10 +559,9 @@ int main(int argc, char **argv) { n_rnti=atoi(optarg); break; case 'u': - dual_stream_UE=1; - openair_daq_vars.use_ia_receiver = 1; - if ((n_tx!=2) || (transmission_mode!=5)) { - msg("IA receiver only supported for TM5!"); + rx_type = (RX_type_t) atoi(optarg); + if (rx_typerx_IC_dual_stream) { + printf("Unsupported rx type %d\n",rx_type); exit(-1); } break; @@ -563,6 +585,9 @@ int main(int argc, char **argv) { test_perf=atoi(optarg); //print_perf =1; break; + case 'X': + xforms = 1; + break; case 'Z': dump_table=1; break; @@ -571,7 +596,7 @@ int main(int argc, char **argv) { break; case 'h': default: - printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); + printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); printf("-h This message\n"); printf("-a Use AWGN channel and not multipath\n"); printf("-c Number of PDCCH symbols\n"); @@ -584,18 +609,20 @@ int main(int argc, char **argv) { printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); printf("-f step size of SNR, default value is 1.\n"); printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); - printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n"); + printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T') \n"); + //printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real22 ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), \n"); + printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); printf("-x Transmission mode (1,2,6 for the moment)\n"); printf("-y Number of TX antennas used in eNB\n"); printf("-z Number of RX antennas used in UE\n"); printf("-t MCS of interfering UE\n"); printf("-R Number of HARQ rounds (fixed)\n"); - printf("-M Turns on calibration mode for abstraction.\n"); + printf("-A Turns on calibration mode for abstraction.\n"); printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); printf("-I Input filename for TrCH data (binary)\n"); - printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n"); + printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n"); exit(1); break; } @@ -605,20 +632,20 @@ int main(int argc, char **argv) { switch (N_RB_DL) { case 6: if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; - BW = 1.25; + BW = 30.72/16; num_pdcch_symbols = 3; break; case 25: if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; - BW = 5.00; + BW = 30.72/4; break; case 50: if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; - BW = 10.00; + BW = 30.72/2; break; case 100: if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; - BW = 20.00; + BW = 30.72; break; } NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); @@ -628,37 +655,55 @@ int main(int argc, char **argv) { NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); - if ((transmission_mode > 1) && (n_tx != 2)) + if ((transmission_mode > 1) && (n_tx != 2)) { printf("n_tx must be >1 for transmission_mode %d\n",transmission_mode); + exit(-1); + } + + if (((transmission_mode==1) || (transmission_mode==2)) && (rx_type != rx_standard)) { + printf("only standard rx available for TM1 and TM2\n"); + exit(-1); + } + if (((transmission_mode==5) || (transmission_mode==6)) && (rx_type == rx_IC_dual_stream)) { + printf("only standard rx or single stream IC available for TM5 and TM6\n"); + exit(-1); + } + #ifdef XFORMS + if (xforms==1) { fl_initialize (&argc, argv, NULL, 0, 0); form_ue = create_lte_phy_scope_ue(); sprintf (title, "LTE PHY SCOPE eNB"); fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - if (!dual_stream_UE==0) { + /* + if (rx_type==rx_IC_single_stream) { openair_daq_vars.use_ia_receiver = 1; fl_set_button(form_ue->button_0,1); fl_set_object_label(form_ue->button_0, "IA Receiver ON"); fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN); } + */ + } #endif - if (transmission_mode==5) { + if (transmission_mode==5) { n_users = 2; - printf("dual_stream_UE=%d\n", dual_stream_UE); + eNB_id_i = PHY_vars_UE->n_connected_eNB; } + else + eNB_id_i = eNB_id; + lte_param_init(n_tx,n_rx,transmission_mode,extended_prefix_flag,fdd_flag,Nid_cell,tdd_config,N_RB_DL,osf,perfect_ce); - eNB_id_i = PHY_vars_UE->n_connected_eNB; - printf("Setting mcs1 = %d\n",mcs1); printf("Setting mcs2 = %d\n",mcs2); printf("NPRB = %d\n",NB_RB); printf("n_frames = %d\n",n_frames); printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag); + printf("Using receiver type %d\n", rx_type); snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); @@ -675,26 +720,35 @@ int main(int argc, char **argv) { frame_parms = &PHY_vars_eNB->lte_frame_parms; - s_re = malloc(2*sizeof(double*)); + s_re = malloc(2*sizeof(double*)); //transmitted signal (Sent) s_im = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); + r_re = malloc(2*sizeof(double*)); //received signal r_im = malloc(2*sizeof(double*)); // r_re0 = malloc(2*sizeof(double*)); // r_im0 = malloc(2*sizeof(double*)); nsymb = (PHY_vars_eNB->lte_frame_parms.Ncp == 0) ? 14 : 12; + + printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); - printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n", - SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8); - + printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d, Rayleigh1_orthogonal=%d, Rayleigh1_orth_eff_ch_TM4_prec_real22=%d, Rayleigh1_orth_eff_ch_TM4_prec_imag=%d, Rayleigh8_orth_eff_ch_TM4_prec_real=%d, Rayleigh8_orth_eff_ch_TM4_prec_imag=%d , TS_SHIFT=%d\n", + SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); if(transmission_mode==5) - sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,channel_model,n_rx,mcs1,mcs_i,dual_stream_UE,i_mod); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); + else if (abstx == 1) + if (perfect_ce==1) + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + else + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); else - sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,n_rx,mcs1); + if (perfect_ce==1) + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + else + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); bler_fd = fopen(bler_fname,"w"); - fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; dci_err\n"); if (test_perf != 0) { char hostname[1024]; @@ -710,8 +764,18 @@ int main(int argc, char **argv) { } if(abstx){ - // CSV file - sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds); + // CSV file // add here second stream mcs + + if (transmission_mode == 5) + sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d_abstr.m",transmission_mode,rx_type,mcs1,channel_model,n_frames,num_rounds); + + else + if (perfect_ce==1) + sprintf(csv_fname,"dataout_tx%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_abstr_perf_ce.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); + else + sprintf(csv_fname,"dataout_tx%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_abstr.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); + + // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); } @@ -719,7 +783,8 @@ int main(int argc, char **argv) { /* //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames); sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames); - tikz_fd = fopen(tikz_fname,"w"); + tikz_fd = fopesprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old_perf_ce_llr.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); +n(tikz_fname,"w"); //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {"); switch (mcs) { @@ -835,7 +900,7 @@ int main(int argc, char **argv) { UL_alloc_pdu.ndi = 1; UL_alloc_pdu.TPC = 0; UL_alloc_pdu.cqi_req = 1; - + CCCH_alloc_pdu.type = 0; CCCH_alloc_pdu.vrb_type = 0; CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; @@ -891,14 +956,14 @@ int main(int argc, char **argv) { exit(-1); } - if ((transmission_mode == 3) || (transmission_mode==4)) + if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8)) Kmimo=2; else Kmimo=1; for (k=0;kdlsch_eNB[k][i] = new_eNB_dlsch(Kmimo,8,N_RB_DL,0); if (!PHY_vars_eNB->dlsch_eNB[k][i]) { printf("Can't get eNB dlsch structures\n"); @@ -932,6 +997,11 @@ int main(int argc, char **argv) { } + sic_buffer = (mod_sym_t **) malloc16(frame_parms->nb_antennas_tx*sizeof(mod_sym_t*) ); + for (i=0; inb_antennas_tx; i++) { + sic_buffer[i] = malloc16_clear(FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t)); + } + if (input_fd==NULL) { @@ -1005,7 +1075,7 @@ int main(int argc, char **argv) { break; } } - else { + else { //fdd switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1_1_5MHz_FDD_t; @@ -1076,7 +1146,7 @@ int main(int argc, char **argv) { num_dci++; num_ue_spec_dci++; } - else { + else { //common flag =1 if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { @@ -1134,7 +1204,7 @@ int main(int argc, char **argv) { break; } } - else { + else { // fdd switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_FDD_t; @@ -1212,10 +1282,10 @@ int main(int argc, char **argv) { } break; - case 3: + case 3: //LARGE CDD if (common_flag == 0) { - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) { + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) {// here DCI does not contain any precoder information. matrix is fixed as identity, but dont forget aboy cycling if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { @@ -1281,8 +1351,8 @@ int main(int argc, char **argv) { break; } } - - else { + + else { // fdd switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; @@ -1342,7 +1412,7 @@ int main(int argc, char **argv) { } } } - else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { + else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { //4 antenna, needs diff precoding codebook index depeneding on layers } @@ -1369,8 +1439,8 @@ int main(int argc, char **argv) { num_dci++; num_ue_spec_dci++; } - else { - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + else { //commonn flag 1 + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { //tdd switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: @@ -1427,7 +1497,7 @@ int main(int argc, char **argv) { break; } } - else { + else { //fdd switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_FDD_t; @@ -1507,7 +1577,7 @@ int main(int argc, char **argv) { printf("Generated DCI format 2A (Transmission Mode 3)\n"); break; - case 4: + case 4: // !!! this dci format contains precoder information if (common_flag == 0) { if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) { @@ -1516,7 +1586,7 @@ int main(int argc, char **argv) { switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; + dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; @@ -1528,14 +1598,16 @@ int main(int argc, char **argv) { ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; @@ -1543,6 +1615,9 @@ int main(int argc, char **argv) { ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + break; case 50: dci_length = sizeof_DCI2_10MHz_2A_TDD_t; @@ -1558,6 +1633,9 @@ int main(int argc, char **argv) { ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + break; case 100: ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; @@ -1571,6 +1649,8 @@ int main(int argc, char **argv) { ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; dci_length = sizeof_DCI2_20MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); break; @@ -1591,6 +1671,8 @@ int main(int argc, char **argv) { ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_FDD_t; @@ -1605,6 +1687,8 @@ int main(int argc, char **argv) { ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; case 50: dci_length = sizeof_DCI2_10MHz_2A_FDD_t; @@ -1619,6 +1703,8 @@ int main(int argc, char **argv) { ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; case 100: dci_length = sizeof_DCI2_20MHz_2A_FDD_t; @@ -1633,6 +1719,8 @@ int main(int argc, char **argv) { ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; } } @@ -1664,7 +1752,7 @@ int main(int argc, char **argv) { num_dci++; num_ue_spec_dci++; } - else { + else { //common_flag==1 if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { @@ -1895,18 +1983,6 @@ int main(int argc, char **argv) { } } - // this is for user 0 only - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0,subframe); - - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); - snr_step = input_snr_step; PHY_vars_UE->high_speed_flag = 1; PHY_vars_UE->ch_est_alpha=0; @@ -1918,19 +1994,11 @@ int main(int argc, char **argv) { for (SNR=snr0;SNRframe_rx=0; - errs[0]=0; - errs[1]=0; - errs[2]=0; - errs[3]=0; - errs2[0]=0; - errs2[1]=0; - errs2[2]=0; - errs2[3]=0; - round_trials[0] = 0; - round_trials[1] = 0; - round_trials[2] = 0; - round_trials[3] = 0; - + for (i=0; i<4; i++) { + errs[0][i]=0; + errs[1][i]=0; + round_trials[i] = 0; + } dci_errors=0; avg_ber = 0; @@ -2086,6 +2154,39 @@ int main(int argc, char **argv) { break; } break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); + break; + case 25: + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); + break; + case 50: + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); + break; + case 100: + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); + break; + } + break; + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; @@ -2152,6 +2253,38 @@ int main(int argc, char **argv) { break; } break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); + break; + case 25: + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); + break; + case 50: + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); + break; + case 100: + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); + break; + } + break; case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; @@ -2257,6 +2390,71 @@ int main(int argc, char **argv) { break; } break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); + break; + case 25: + if (TB0_active==1) { + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); + break; + case 50: + if (TB0_active==1) { + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); + break; + case 100: + if (TB0_active==1) { + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); + break; + } + break; + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; @@ -2355,6 +2553,72 @@ int main(int argc, char **argv) { break; } break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); + break; + case 25: + if (TB0_active==1) { + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); + break; + case 50: + if (TB0_active==1) { + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); + break; + case 100: + if (TB0_active==1) { + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); + break; + } + break; + + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; @@ -2398,12 +2662,12 @@ int main(int argc, char **argv) { if ((SNR==snr0) && (trials==0) && (round==0)) printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", - k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][0]->harq_processes[0]->mcs), + k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), coded_bits_per_codeword, tbs, - get_Qm(PHY_vars_eNB->dlsch_eNB[k][0]->harq_processes[0]->mcs), + get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), //changed dlsch_eNB[k][0] num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->round); + PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->round);//changed dlsch_eNB[k][0] // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { @@ -2454,10 +2718,11 @@ int main(int argc, char **argv) { 0, PHY_vars_eNB->dlsch_eNB[k][cw], coded_bits_per_codeword, - 0, + cw, subframe<<1); stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); +#ifdef PRINT_BYTES if (n_frames==1) { for (s=0;sdlsch_eNB[k][cw]->harq_processes[0]->C;s++) { if (sdlsch_eNB[k][cw]->harq_processes[0]->Cminus) @@ -2468,9 +2733,10 @@ int main(int argc, char **argv) { Kr_bytes = Kr>>3; for (i=0;idlsch_eNB[k][cw]->harq_processes[0]->c[s][i]); + printf("cw%d %d : (%x)\n",cw,i,PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->c[s][i]); } } +#endif } start_meas(&PHY_vars_eNB->dlsch_modulation_stats); @@ -2568,6 +2834,28 @@ int main(int argc, char **argv) { s_im[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); } else { + if (transmission_mode==4) { + r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + + r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + // printf("r_re0 = %d\n",r_re[0][i]); + //printf("r_im0 = %d\n",r_im[0][i]); + //printf("r_re1 = %d\n",r_re[1][i]); + //printf("r_im1 = %d\n",r_im[1][i]); + // r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + // r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + + // r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + // r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); +// printf("r_re0 = %d\n",r_re[0][i]); +// printf("r_im0 = %d\n",r_im[0][i]); +// printf("r_re1 = %d\n",r_re[1][i]); +// printf("r_im1 = %d\n",r_im[1][i]); + + } + else { for (aarx=0;aarxlte_frame_parms.nb_antennas_rx;aarx++) { if (aa==0) { r_re[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); @@ -2577,7 +2865,7 @@ int main(int argc, char **argv) { r_re[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); r_im[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); } - + } } } } @@ -2597,6 +2885,7 @@ int main(int argc, char **argv) { } + // freq_channel(eNB2UE[0], NB_RB,12*NB_RB + 1); if(abstx){ if (trials==0 && round==0) { // calculate freq domain representation to compute SINR @@ -2830,18 +3119,18 @@ int main(int argc, char **argv) { dci_alloc_rx,1, eNB_id, subframe); - //printf("dci_cnt %d\n",dci_cnt); + printf("dci_cnt %d\n",dci_cnt); if (dci_cnt==0) { dlsch_active = 0; if (round==0) { dci_errors++; round=5; - errs[0]++; + errs[0][0]++; //round_trials[0]++; if (n_frames==1) - printf("DCI error trial %d errs[0] %d\n",trials,errs[0]); + printf("DCI error trial %d errs[0][0] %d\n",trials,errs[0][0]); } // for (i=1;i<=round;i++) // round_trials[i]--; @@ -2850,7 +3139,10 @@ int main(int argc, char **argv) { for (i=0;idlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->first_tx=1; + if (round == 0) { + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->first_tx=1; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->first_tx=1; + } if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, dci_alloc_rx[i].dci_pdu, @@ -2862,13 +3154,13 @@ int main(int argc, char **argv) { SI_RNTI, 0, P_RNTI)==0)) { - //dump_dci(&PHY_vars_UE->lte_frame_parms,&dci_alloc_rx[i]); + dump_dci(&PHY_vars_UE->lte_frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb, PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc, get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl, -PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, 0,subframe); /* rate = (double)dlsch_tbs25[get_I_TBS(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs)][PHY_vars_UE->dlsch_ue[0][0]->nb_rb-1]/(coded_bits_per_codeword); @@ -2882,7 +3174,7 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, dlsch_active = 0; if (round==0) { dci_errors++; - errs[0]++; + errs[0][0]++; //round_trials[0]++; round=5; @@ -2900,7 +3192,10 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = n_rnti; PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; - if (round == 0) PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx=1; + if (round == 0) { + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx=1; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->first_tx=1; + } switch (transmission_mode) { case 1: case 2: @@ -2933,13 +3228,14 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, generate_ue_dlsch_params_from_dci(0, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, - (common_flag==0)? format2 : format1A, + (common_flag==0)? format2 : format1A,//format1A only for a codeblock PHY_vars_UE->dlsch_ue[0], &PHY_vars_UE->lte_frame_parms, PHY_vars_UE->pdsch_config_dedicated, SI_RNTI, 0, P_RNTI); + break; case 5: case 6: @@ -2963,12 +3259,14 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, if (dlsch_active == 1) { if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix) - if ((transmission_mode == 5) && - (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->dl_power_off==0) && - (openair_daq_vars.use_ia_receiver ==1)) { - dual_stream_UE = 1; - } else { - dual_stream_UE = 0; + + if (transmission_mode == 5) { + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->dl_power_off==0) && + (openair_daq_vars.use_ia_receiver ==1)) { + rx_type = rx_IC_single_stream; + } else { + rx_type = rx_standard; + } } @@ -2985,7 +3283,7 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, subframe, m, (m==PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols)?1:0, - dual_stream_UE, + rx_type, i_mod, PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1) { @@ -3010,7 +3308,7 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, subframe, m, 0, - dual_stream_UE, + rx_type, i_mod, PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1) { @@ -3035,7 +3333,7 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, subframe, m, 0, - dual_stream_UE, + rx_type, i_mod, PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1) { @@ -3047,10 +3345,33 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, } if (test_perf ==0 ) { if ((n_frames==1) && (Ns==(2+(2*subframe))) && (l==0)) { - write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + + + write_output("chanF11.m","chF11",eNB2UE[0]->chF[0],12*NB_RB,1,8); + write_output("chan11.m","ch11",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx==2 && PHY_vars_eNB->lte_frame_parms.nb_antennas_tx==1 ){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + } + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1){ + write_output("chan12.m","ch12",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx>1){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[2],eNB2UE[0]->channel_length,1,8); + write_output("chan22.m","ch22",eNB2UE[0]->ch[3],eNB2UE[0]->channel_length,1,8); + } + + } + + + /*for (aarx=0;aarxlte_frame_parms.nb_antennas_rx; aarx++) { + for (aa=0;aalte_frame_parms.nb_antennas_tx; aa++) { + sprintf(fname,"ch%d%d.m",(aarx+1), (aa+1)); + write_output(fname,"ch",eNB2UE[0]->ch[2*aarx+aa],eNB2UE[0]->channel_length,1,8); + } + } */ + /*write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) - write_output("ch1.m","ch1",eNB2UE[0]->ch[PHY_vars_eNB->lte_frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8); - + write_output("ch1.m","ch1",eNB2UE[0]->ch[PHY_vars_eNB->lte_frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);*/ + //common vars write_output("rxsig0.m","rxs0", &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); write_output("rxsigF0.m","rxsF0", &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); @@ -3076,9 +3397,10 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); //pdsch_vars - dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round); + dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round,PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid ); //dump_dlsch2(PHY_vars_UE,eNB_id_i,coded_bits_per_codeword); - write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + // write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + //pdcch_vars write_output("pdcchF0_ext.m","pdcchF_ext", PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,1,1); @@ -3105,211 +3427,303 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, } } - for (int cw=Kmimo-1;cw>=0;cw--){ - PHY_vars_UE->dlsch_ue[0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0,subframe); + for (int cw=0; cwdlsch_ue[0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0,subframe); + PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->G = coded_bits_per_codeword; - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->G = coded_bits_per_codeword; - - - /* - // calculate uncoded BLER - uncoded_ber=0; - for (i=0;idlsch_eNB[0][0]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[0][i]<0)) { - uncoded_ber_bit[i] = 1; - uncoded_ber++; - } - else - uncoded_ber_bit[i] = 0; - - uncoded_ber/=coded_bits_per_codeword; - avg_ber += uncoded_ber; - - if (n_frames==1) - write_output("uncoded_ber_bit.m","uncoded_ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); - */ - - start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_ue[0][cw], - coded_bits_per_codeword, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw], - 0, - subframe<<1); - stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - - start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw], - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid], - subframe, - PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid, - 1,llr8_flag); - stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - - if (cw==1) { - if (ret <= PHY_vars_UE->dlsch_ue[0][cw]->max_turbo_iterations) { - } - else { - errs2[round]++; - } - } - } - - - stop_meas(&PHY_vars_UE->phy_proc_rx); - - - if (ret <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) { - - avg_iter += ret; - iter_trials++; - if (n_frames==1) - printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); - - PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->TBS; - TB0_active = 0; - if (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC - /* - for (round = 0 ; round < PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round ; round++) { - // re-encoding of first stream - dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq->mimo_mode = LARGE_CDD; - dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; - dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; - dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; - dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; - dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; - - dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; - dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; - dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - - PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; - PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; - - dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_UE->dlsch_eNB[0], - 0,subframe, - &PHY_vars_UE->dlsch_rate_matching_stats, - &PHY_vars_UE->dlsch_turbo_encoding_stats, - &PHY_vars_UE->dlsch_interleaving_stats - ); - - //scrambling - - //modulation - - //stripping (from matched filter output?) - - //detection of second stream - } - */ - } - } - else { - errs[round]++; - - avg_iter += ret-1; - iter_trials++; - if (n_frames==1) { - //if ((n_frames==1) || (SNR>=30)) { - printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); - for (s=0;sdlsch_ue[0][0]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][0]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->Kminus; + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw,coded_bits_per_codeword, + PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->TBS); + + // calculate uncoded BER + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw],coded_bits_per_codeword,1,0); + sprintf(fname,"dlsch_cw%d_e.m", cw); + sprintf(vname,"dlsch_cw%d_e", cw); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + uncoded_ber=0; + for (i=0;idlsch_eNB[0][cw]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } else - Kr = PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][0]->harq_processes[0]->c[s][i],PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->c[s][i]); + uncoded_ber_bit[i] = 0; + + uncoded_ber/=coded_bits_per_codeword; + avg_ber += uncoded_ber; + sprintf(fname,"cw%d_uncoded_ber_bit.m", cw); + sprintf(vname,"uncoded_ber_bit_cw%d", cw); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); + printf("cw %d, uncoded ber %f\n",cw,uncoded_ber); + + + free(uncoded_ber_bit); + uncoded_ber_bit = NULL; + + } + + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_ue[0][cw], + coded_bits_per_codeword, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw], + cw, + subframe<<1); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + + start_meas(&PHY_vars_UE->dlsch_decoding_stats); + ret = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][cw], + PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid, + 1,llr8_flag); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + + + if (ret <= PHY_vars_UE->dlsch_ue[0][cw]->max_turbo_iterations ) { + + if (cw==0) { + avg_iter += ret; + iter_trials++; } - sprintf(fname,"rxsig0_r%d.m",round); - sprintf(vname,"rxs0_r%d.m",round); - write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); - sprintf(fname,"rxsigF0_r%d.m",round); - sprintf(vname,"rxs0F_r%d.m",round); - write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); - if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { - sprintf(fname,"rxsig1_r%d.m",round); - sprintf(vname,"rxs1_r%d.m",round); - write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdata[1],PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); - sprintf(fname,"rxsig1F_r%d.m",round); - sprintf(vname,"rxs1F_r%d.m",round); - write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdataF[1],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); + + if (n_frames==1) { + printf("cw %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->c[s][i]); + } +#endif } - sprintf(fname,"dlsch00_r%d.m",round); - sprintf(vname,"dl00_r%d.m",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][0][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { - sprintf(fname,"dlsch01_r%d.m",round); - sprintf(vname,"dl01_r%d.m",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][1][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); - } - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) { - sprintf(fname,"dlsch10_r%d.m",round); - sprintf(vname,"dl10_r%d.m",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][2][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); - } - if ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) && (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)) { - sprintf(fname,"dlsch11_r%d.m",round); - sprintf(vname,"dl11_r%d.m",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][3][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); - } - //pdsch_vars - dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round); + + PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw]->current_harq_pid]->TBS; + + if (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* + //for (round = 0 ; round < PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round ; round++) { + // we assume here that the second stream has a lower MCS and is thus more likely to be decoded + // re-encoding of second stream + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][1]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq->mimo_mode = LARGE_CDD; + dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; + dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; + dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; + dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; + dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; + dlsch0_eNB_harq->round = dlsch0_ue_harq->round; + + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; + dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; + dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][1]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][1]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid; + + dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][1]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0,subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats + ); + + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0,subframe); + + + //scrambling + dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword, + 0, + subframe<<1); + + + //modulation + re_allocated = dlsch_modulation(sic_buffer, + AMP, + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL); + // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding + // precoding is contained in effective channel estimate + // compute the norm of the effective channel for both receive antennas -> alphha[0], alphha[2] + // multiply with the norm of the effective channnel + */ + + //stripping (from matched filter output of first stream = rxdataF_comp0) + // this is pseudocode + /* + for (i=0; inb_antennas_rx; i++) { + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext[i] -= alpha[i].*sic_buffer[i]; + } + */ + + //apply rho to output + /* + dlsch_channel_compensation(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].dl_ch_rho_ext[harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1, + NULL, + frame_parms, + symbol, + first_symbol_flag, + i_mod, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + phy_measurements); // log2_maxh+I0_shift + */ + + + //detection of second stream + //} + + } + } + else { + errs[cw][round]++; + + if (cw==0) { + avg_iter += ret-1; + iter_trials++; + } + + if (cw==1) { + avg_iter += ret-1; + iter_trials++; + } + + if (n_frames==1) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->c[s][i]); + } +#endif + } + } + } + + stop_meas(&PHY_vars_UE->phy_proc_rx); + + if (n_frames==1) { + sprintf(fname,"rxsig0_r%d.m",round); + sprintf(vname,"rxs0_r%d",round); + write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsigF0_r%d.m",round); + sprintf(vname,"rxs0F_r%d",round); + write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); + if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { + sprintf(fname,"rxsig1_r%d.m",round); + sprintf(vname,"rxs1_r%d",round); + write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdata[1],PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsig1F_r%d.m",round); + sprintf(vname,"rxs1F_r%d",round); + write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdataF[1],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); + } + sprintf(fname,"dlsch00_r%d.m",round); + sprintf(vname,"dl00_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][0][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { + sprintf(fname,"dlsch01_r%d.m",round); + sprintf(vname,"dl01_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][1][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); + } + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) { + sprintf(fname,"dlsch10_r%d.m",round); + sprintf(vname,"dl10_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][2][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); + } + if ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) && (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)) { + sprintf(fname,"dlsch11_r%d.m",round); + sprintf(vname,"dl11_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][3][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); + } + //pdsch_vars + dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round,PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid); + /* write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("dlsch_eNB_w.m","w",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); write_output("dlsch_UE_w.m","w",PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); - */ - - if (round == 3) exit(-1); - } - // printf("round %d errors %d/%d\n",round,errs[round],trials); - - round++; - // PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round++; + */ + + if (round == 3) exit(-1); } + #ifdef XFORMS - phy_scope_UE(form_ue, - PHY_vars_UE, - eNB_id, - 0,// UE_id - subframe); + if (xforms==1) { + phy_scope_UE(form_ue, + PHY_vars_UE, + eNB_id, + 0,// UE_id + subframe); + } #endif - + + round++; } //round - // printf("\n"); - if ((errs[0]>=n_frames/10) && (trials>(n_frames/2))) - break; + //if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) + // break; //len = chbch_stats_read(stats_buffer,NULL,0,4096); //printf("%s\n\n",stats_buffer); @@ -3327,34 +3741,34 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, * get the max, min, and number of packets that exceed t>2000us */ double t_tx = (double)PHY_vars_eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)PHY_vars_eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)PHY_vars_eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)PHY_vars_eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - - - double t_rx = (double)PHY_vars_UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)PHY_vars_UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)PHY_vars_UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)PHY_vars_UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_ifft = (double)PHY_vars_eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_mod = (double)PHY_vars_eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_enc = (double)PHY_vars_eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; + + + double t_rx = (double)PHY_vars_UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)PHY_vars_UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_demod = (double)PHY_vars_UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_dec = (double)PHY_vars_UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; if (t_tx > t_tx_max) - t_tx_max = t_tx; + t_tx_max = t_tx; if (t_tx < t_tx_min) - t_tx_min = t_tx; + t_tx_min = t_tx; if (t_rx > t_rx_max) - t_rx_max = t_rx; + t_rx_max = t_rx; if (t_rx < t_rx_min) - t_rx_min = t_rx; + t_rx_min = t_rx; if (t_tx > 2000) - n_tx_dropped++; + n_tx_dropped++; if (t_rx > 2000) - n_rx_dropped++; + n_rx_dropped++; push_front(&time_vector_tx, t_tx); push_front(&time_vector_tx_ifft, t_tx_ifft); push_front(&time_vector_tx_mod, t_tx_mod); push_front(&time_vector_tx_enc, t_tx_enc); - + push_front(&time_vector_rx, t_rx); push_front(&time_vector_rx_fft, t_rx_fft); push_front(&time_vector_rx_demod, t_rx_demod); @@ -3451,20 +3865,27 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), sigma2_dB); - printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f)\n", - errs[0], - errs2[0], + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e)), dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f)\n", + errs[0][0], + errs[1][0], round_trials[0], - errs[1], - round_trials[0], - errs[2], - round_trials[0], - errs[3], - round_trials[0], - (double)errs[0]/(round_trials[0]), - (double)errs[1]/(round_trials[0]), - (double)errs[2]/(round_trials[0]), - (double)errs[3]/(round_trials[0]), + errs[0][1], + errs[1][1], + round_trials[1], + errs[0][2], + errs[1][2], + round_trials[2], + errs[0][3], + errs[1][3], + round_trials[3], + (double)errs[0][0]/(round_trials[0]), + (double)errs[1][0]/(round_trials[0]), + (double)errs[0][1]/(round_trials[1]), + (double)errs[1][1]/(round_trials[1]), + (double)errs[0][2]/(round_trials[2]), + (double)errs[1][2]/(round_trials[2]), + (double)errs[0][3]/(round_trials[3]), + (double)errs[1][3]/(round_trials[3]), dci_errors, round_trials[0], (double)dci_errors/(round_trials[0]), @@ -3472,8 +3893,8 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, 100*effective_rate, rate, rate*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), - (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); if (print_perf==1) { printf("eNB TX function statistics (per 1ms subframe)\n\n"); @@ -3547,54 +3968,80 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, PHY_vars_UE->dlsch_tc_intl2_stats.trials); } - if ((transmission_mode != 3) && (transmission_mode != 4)) { + if ((transmission_mode != 3) && (transmission_mode != 4)) { fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", SNR, mcs1, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, rate, - errs[0], + errs[0][0], round_trials[0], - errs[1], + errs[0][1], round_trials[1], - errs[2], + errs[0][2], round_trials[2], - errs[3], + errs[0][3], round_trials[3], dci_errors); } else { - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", SNR, mcs1,mcs2, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, rate, - errs[0], + errs[0][0], + errs[1][0], round_trials[0], - errs[1], + errs[0][1], + errs[1][1], round_trials[1], - errs[2], + errs[0][2], + errs[1][2], round_trials[2], - errs[3], + errs[0][3], + errs[1][3], round_trials[3], dci_errors); } - if(abstx){ //ABSTRACTION - blerr[0] = (double)errs[0]/(round_trials[0]); - if(num_rounds>1){ - blerr[1] = (double)errs[1]/(round_trials[1]); - blerr[2] = (double)errs[2]/(round_trials[2]); - blerr[3] = (double)errs[3]/(round_trials[3]); - fprintf(csv_fd,"%e,%e,%e,%e;\n",blerr[0],blerr[1],blerr[2],blerr[3]); + if(abstx){ //ABSTRACTION + if ((transmission_mode != 3)&& (transmission_mode != 4)) { + blerr[0][0] = (double)errs[0][0]/(round_trials[0]); + + if(num_rounds>1){ + blerr[0][1] = (double)errs[0][1]/(round_trials[1]); + + blerr[0][2] = (double)errs[0][2]/(round_trials[2]); + + blerr[0][3] = (double)errs[0][3]/(round_trials[3]); + + fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]); + } + else { + fprintf(csv_fd,"%e;\n",blerr[0][0]); + } } else { - fprintf(csv_fd,"%e;\n",blerr[0]); + blerr[0][0] = (double)errs[0][0]/(round_trials[0]); + blerr[1][0] = (double)errs[1][0]/(round_trials[0]); + if(num_rounds>1){ + blerr[0][1] = (double)errs[0][1]/(round_trials[1]); + blerr[1][1] = (double)errs[1][1]/(round_trials[1]); + blerr[0][2] = (double)errs[0][2]/(round_trials[2]); + blerr[1][2] = (double)errs[1][2]/(round_trials[2]); + blerr[0][3] = (double)errs[0][3]/(round_trials[3]); + blerr[1][3] = (double)errs[1][3]/(round_trials[3]); + fprintf(csv_fd,"%e;%e;%e;%e;%e;%e;%e;%e;\n",blerr[0][0],blerr[1][0],blerr[0][1],blerr[1][1],blerr[0][2],blerr[1][2], blerr[0][3], blerr[1][3]); + } + else { + fprintf(csv_fd,"%e,%e;\n",blerr[0][0], blerr[1][0]); + } } - } //ABStraction - + } + if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); if ((transmission_mode != 3) && (transmission_mode != 4)) { @@ -3603,13 +4050,13 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, mcs1, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, rate, - errs[0], + errs[0][0], round_trials[0], - errs[1], + errs[0][1], round_trials[1], - errs[2], + errs[0][2], round_trials[2], - errs[3], + errs[0][3], round_trials[3], dci_errors); @@ -3622,23 +4069,23 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, 100*effective_rate, rate, (double)avg_iter/iter_trials, - errs[0], + errs[0][0], round_trials[0], - errs[1], + errs[0][1], round_trials[1], - errs[2], + errs[0][2], round_trials[2], - errs[3], + errs[0][3], round_trials[3], - (double)errs[0]/(round_trials[0]), - (double)errs[1]/(round_trials[0]), - (double)errs[2]/(round_trials[0]), - (double)errs[3]/(round_trials[0]), + (double)errs[0][0]/(round_trials[0]), + (double)errs[0][1]/(round_trials[0]), + (double)errs[0][2]/(round_trials[0]), + (double)errs[0][3]/(round_trials[0]), dci_errors, round_trials[0], (double)dci_errors/(round_trials[0]), - (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); } else { fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", @@ -3647,13 +4094,13 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, rate, - errs[0], + errs[0][0], round_trials[0], - errs[1], + errs[0][1], round_trials[1], - errs[2], + errs[0][2], round_trials[2], - errs[3], + errs[0][3], round_trials[3], dci_errors); @@ -3667,23 +4114,23 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, 100*effective_rate, rate, (double)avg_iter/iter_trials, - errs[0], + errs[0][0], round_trials[0], - errs[1], + errs[0][1], round_trials[1], - errs[2], + errs[0][2], round_trials[2], - errs[3], + errs[0][3], round_trials[3], - (double)errs[0]/(round_trials[0]), - (double)errs[1]/(round_trials[0]), - (double)errs[2]/(round_trials[0]), - (double)errs[3]/(round_trials[0]), + (double)errs[0][0]/(round_trials[0]), + (double)errs[0][1]/(round_trials[0]), + (double)errs[0][2]/(round_trials[0]), + (double)errs[0][3]/(round_trials[0]), dci_errors, round_trials[0], (double)dci_errors/(round_trials[0]), - (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); } //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", @@ -3738,7 +4185,7 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - /* + /* fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", PHY_vars_eNB->phy_proc_tx.trials, PHY_vars_eNB->ofdm_mod_stats.trials, @@ -3754,16 +4201,19 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, */ printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); break; - } else if (test_perf !=0 ){ - printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); - } + } else if (test_perf !=0 ){ + printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); + } - if (((double)errs[0]/(round_trials[0]))<1e-2) - break; + if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) + break; + + if (n_frames==1) + break; + }// SNR - - } //ch_realization + } //ch_realization fclose(bler_fd); @@ -3781,9 +4231,6 @@ PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, fclose(csv_fd); } - if (uncoded_ber_bit) - free(uncoded_ber_bit); - uncoded_ber_bit = NULL; for (k=0;kR_sqrt = R_sqrt; + chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); + for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); + //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; + chan_desc->R_sqrt[i] = R_sqrt[0]; + } } for (i = 0; iricean_factor); + + break; + case Rice1_corr: nb_taps = 1; Td = 0; @@ -779,7 +847,176 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, path_loss_dB, 1); break; + + case Rayleigh1_orthogonal: + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = 0.03; + maxDoppler = 0; + + if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_orthogonal; + } + else + R_sqrt_ptr2 = NULL; + + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; + + case Rayleigh1_orth_eff_ch_TM4_prec_real: + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = 0.03; + maxDoppler = 0; + + + if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; + } + else + R_sqrt_ptr2 = NULL; + + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; + + case Rayleigh1_orth_eff_ch_TM4_prec_imag: + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = 0.03; + maxDoppler = 0; + + + if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; + } + else + R_sqrt_ptr2 = NULL; + + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; + + case Rayleigh8_orth_eff_ch_TM4_prec_real: + + if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; + //R_sqrt_ptr2 = NULL; + } + else + R_sqrt_ptr2 = NULL; + + + nb_taps = 8; + Td = 0.8; + channel_length = (int)11+2*BW*Td; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; + + fill_channel_desc(chan_desc, + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + + break; + + case Rayleigh8_orth_eff_ch_TM4_prec_imag: + nb_taps = 8; + Td = 0.8; + channel_length = (int)11+2*BW*Td; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; + + if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; + } + else + R_sqrt_ptr2 = NULL; + + fill_channel_desc(chan_desc, + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; + default: LOG_W(OCM,"channel model not yet supported\n"); free(chan_desc); @@ -906,6 +1143,11 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { if (desc->channel_length == 1) { desc->ch[aarx+(aatx*desc->nb_rx)][0].x = desc->a[0][aarx+(aatx*desc->nb_rx)].x; desc->ch[aarx+(aatx*desc->nb_rx)][0].y = desc->a[0][aarx+(aatx*desc->nb_rx)].y; +#ifdef DEBUG_CH + k=0; + printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); +#endif + } else { diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index 7d46648e45..1a12f4c13a 100755 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -134,7 +134,7 @@ int logInit (void) } g_log->log_component[PHY].name = "PHY"; - g_log->log_component[PHY].level = LOG_EMERG; + g_log->log_component[PHY].level = LOG_DEBUG; g_log->log_component[PHY].flag = LOG_MED; g_log->log_component[PHY].interval = 1; g_log->log_component[PHY].fd = 0; @@ -142,7 +142,7 @@ int logInit (void) g_log->log_component[PHY].filelog_name = "/tmp/phy.log"; g_log->log_component[MAC].name = "MAC"; - g_log->log_component[MAC].level = LOG_EMERG; + g_log->log_component[MAC].level = LOG_DEBUG; g_log->log_component[MAC].flag = LOG_MED; g_log->log_component[MAC].interval = 1; g_log->log_component[MAC].fd = 0; @@ -150,7 +150,7 @@ int logInit (void) g_log->log_component[MAC].filelog_name = "/tmp/mac.log"; g_log->log_component[OPT].name = "OPT"; - g_log->log_component[OPT].level = LOG_EMERG; + g_log->log_component[OPT].level = LOG_DEBUG; g_log->log_component[OPT].flag = LOG_MED; g_log->log_component[OPT].interval = 1; g_log->log_component[OPT].fd = 0; @@ -158,7 +158,7 @@ int logInit (void) g_log->log_component[OPT].filelog_name = ""; g_log->log_component[RLC].name = "RLC"; - g_log->log_component[RLC].level = LOG_INFO; + g_log->log_component[RLC].level = LOG_DEBUG; g_log->log_component[RLC].flag = LOG_MED; g_log->log_component[RLC].interval = 1; g_log->log_component[RLC].fd = 0; @@ -166,7 +166,7 @@ int logInit (void) g_log->log_component[RLC].filelog_name = "/tmp/rlc.log"; g_log->log_component[PDCP].name = "PDCP"; - g_log->log_component[PDCP].level = LOG_INFO; + g_log->log_component[PDCP].level = LOG_DEBUG; g_log->log_component[PDCP].flag = LOG_MED; g_log->log_component[PDCP].interval = 1; g_log->log_component[PDCP].fd = 0; @@ -174,7 +174,7 @@ int logInit (void) g_log->log_component[PDCP].filelog_name = "/tmp/pdcp.log"; g_log->log_component[RRC].name = "RRC"; - g_log->log_component[RRC].level = LOG_TRACE; + g_log->log_component[RRC].level = LOG_DEBUG; g_log->log_component[RRC].flag = LOG_MED; g_log->log_component[RRC].interval = 1; g_log->log_component[RRC].fd = 0; @@ -182,7 +182,7 @@ int logInit (void) g_log->log_component[RRC].filelog_name = "/tmp/rrc.log"; g_log->log_component[NAS].name = "NAS"; - g_log->log_component[NAS].level = LOG_TRACE; + g_log->log_component[NAS].level = LOG_DEBUG; g_log->log_component[NAS].flag = LOG_MED; g_log->log_component[NAS].interval = 1; g_log->log_component[NAS].fd = 0; @@ -190,7 +190,7 @@ int logInit (void) g_log->log_component[NAS].filelog_name = "/tmp/nas.log"; g_log->log_component[EMU].name = "EMU"; - g_log->log_component[EMU].level = LOG_EMERG; + g_log->log_component[EMU].level = LOG_DEBUG; g_log->log_component[EMU].flag = LOG_MED; g_log->log_component[EMU].interval = 1; g_log->log_component[EMU].fd = 0; @@ -198,7 +198,7 @@ int logInit (void) g_log->log_component[EMU].filelog_name = ""; g_log->log_component[OMG].name = "OMG"; - g_log->log_component[OMG].level = LOG_EMERG; + g_log->log_component[OMG].level = LOG_DEBUG; g_log->log_component[OMG].flag = LOG_MED; g_log->log_component[OMG].interval = 1; g_log->log_component[OMG].fd = 0; @@ -206,7 +206,7 @@ int logInit (void) g_log->log_component[OMG].filelog_name = "/tmp/omg.csv"; g_log->log_component[OTG].name = "OTG"; - g_log->log_component[OTG].level = LOG_EMERG; + g_log->log_component[OTG].level = LOG_DEBUG; g_log->log_component[OTG].flag = LOG_MED; g_log->log_component[OTG].interval = 1; g_log->log_component[OTG].fd = 0; @@ -214,7 +214,7 @@ int logInit (void) g_log->log_component[OTG].filelog_name = "/tmp/otg.log"; g_log->log_component[OTG_LATENCY].name = "OTG_LATENCY"; - g_log->log_component[OTG_LATENCY].level = LOG_EMERG; + g_log->log_component[OTG_LATENCY].level = LOG_DEBUG; g_log->log_component[OTG_LATENCY].flag = LOG_MED; g_log->log_component[OTG_LATENCY].interval = 1; g_log->log_component[OTG_LATENCY].fd = 0; @@ -222,7 +222,7 @@ int logInit (void) g_log->log_component[OTG_LATENCY].filelog_name = "/tmp/otg_latency.dat"; g_log->log_component[OTG_LATENCY_BG].name = "OTG_LATENCY_BG"; - g_log->log_component[OTG_LATENCY_BG].level = LOG_EMERG; + g_log->log_component[OTG_LATENCY_BG].level = LOG_DEBUG; g_log->log_component[OTG_LATENCY_BG].flag = LOG_MED; g_log->log_component[OTG_LATENCY_BG].interval = 1; g_log->log_component[OTG_LATENCY_BG].fd = 0; @@ -230,7 +230,7 @@ int logInit (void) g_log->log_component[OTG_LATENCY_BG].filelog_name = "/tmp/otg_latency_bg.dat"; g_log->log_component[OTG_GP].name = "OTG_GP"; - g_log->log_component[OTG_GP].level = LOG_EMERG; + g_log->log_component[OTG_GP].level = LOG_DEBUG; g_log->log_component[OTG_GP].flag = LOG_MED; g_log->log_component[OTG_GP].interval = 1; g_log->log_component[OTG_GP].fd = 0; @@ -238,7 +238,7 @@ int logInit (void) g_log->log_component[OTG_GP].filelog_name = "/tmp/otg_goodput.dat"; g_log->log_component[OTG_GP_BG].name = "OTG_GP_BG"; - g_log->log_component[OTG_GP_BG].level = LOG_EMERG; + g_log->log_component[OTG_GP_BG].level = LOG_DEBUG; g_log->log_component[OTG_GP_BG].flag = LOG_MED; g_log->log_component[OTG_GP_BG].interval = 1; g_log->log_component[OTG_GP_BG].fd = 0; @@ -246,7 +246,7 @@ int logInit (void) g_log->log_component[OTG_GP_BG].filelog_name = "/tmp/otg_goodput_bg.dat"; g_log->log_component[OTG_JITTER].name = "OTG_JITTER"; - g_log->log_component[OTG_JITTER].level = LOG_EMERG; + g_log->log_component[OTG_JITTER].level = LOG_DEBUG; g_log->log_component[OTG_JITTER].flag = LOG_MED; g_log->log_component[OTG_JITTER].interval = 1; g_log->log_component[OTG_JITTER].fd = 0; @@ -254,7 +254,7 @@ int logInit (void) g_log->log_component[OTG_JITTER].filelog_name = "/tmp/otg_jitter.dat"; g_log->log_component[OCG].name = "OCG"; - g_log->log_component[OCG].level = LOG_EMERG; + g_log->log_component[OCG].level = LOG_DEBUG; g_log->log_component[OCG].flag = LOG_MED; g_log->log_component[OCG].interval = 1; g_log->log_component[OCG].fd = 0; @@ -262,7 +262,7 @@ int logInit (void) g_log->log_component[OCG].filelog_name = ""; g_log->log_component[PERF].name = "PERF"; - g_log->log_component[PERF].level = LOG_EMERG; + g_log->log_component[PERF].level = LOG_DEBUG; g_log->log_component[PERF].flag = LOG_MED; g_log->log_component[PERF].interval = 1; g_log->log_component[PERF].fd = 0; @@ -270,7 +270,7 @@ int logInit (void) g_log->log_component[PERF].filelog_name = ""; g_log->log_component[OIP].name = "OIP"; - g_log->log_component[OIP].level = LOG_EMERG; + g_log->log_component[OIP].level = LOG_DEBUG; g_log->log_component[OIP].flag = LOG_MED; g_log->log_component[OIP].interval = 1; g_log->log_component[OIP].fd = 0; @@ -278,7 +278,7 @@ int logInit (void) g_log->log_component[OIP].filelog_name = ""; g_log->log_component[CLI].name = "CLI"; - g_log->log_component[CLI].level = LOG_EMERG; + g_log->log_component[CLI].level = LOG_DEBUG; g_log->log_component[CLI].flag = LOG_MED; g_log->log_component[CLI].interval = 1; g_log->log_component[CLI].fd = 0; @@ -286,7 +286,7 @@ int logInit (void) g_log->log_component[CLI].filelog_name = ""; g_log->log_component[MSC].name = "MSC"; - g_log->log_component[MSC].level = LOG_EMERG; + g_log->log_component[MSC].level = LOG_DEBUG; g_log->log_component[MSC].flag = LOG_MED; g_log->log_component[MSC].interval = 1; g_log->log_component[MSC].fd = 0; @@ -294,7 +294,7 @@ int logInit (void) g_log->log_component[MSC].filelog_name = "/tmp/msc.log"; g_log->log_component[OCM].name = "OCM"; - g_log->log_component[OCM].level = LOG_EMERG; + g_log->log_component[OCM].level = LOG_DEBUG; g_log->log_component[OCM].flag = LOG_MED; g_log->log_component[OCM].interval = 1; g_log->log_component[OCM].fd = 0; @@ -302,7 +302,7 @@ int logInit (void) g_log->log_component[OCM].filelog_name = "/tmp/ocm.log"; g_log->log_component[UDP_].name = "UDP"; - g_log->log_component[UDP_].level = LOG_EMERG; + g_log->log_component[UDP_].level = LOG_DEBUG; g_log->log_component[UDP_].flag = LOG_FULL; g_log->log_component[UDP_].interval = 1; g_log->log_component[UDP_].fd = 0; @@ -310,7 +310,7 @@ int logInit (void) g_log->log_component[UDP_].filelog_name = ""; g_log->log_component[GTPU].name = "GTPV1U"; - g_log->log_component[GTPU].level = LOG_EMERG; + g_log->log_component[GTPU].level = LOG_DEBUG; g_log->log_component[GTPU].flag = LOG_FULL; g_log->log_component[GTPU].interval = 1; g_log->log_component[GTPU].fd = 0; @@ -318,7 +318,7 @@ int logInit (void) g_log->log_component[GTPU].filelog_name = ""; g_log->log_component[S1AP].name = "S1AP"; - g_log->log_component[S1AP].level = LOG_EMERG; + g_log->log_component[S1AP].level = LOG_DEBUG; g_log->log_component[S1AP].flag = LOG_FULL; g_log->log_component[S1AP].interval = 1; g_log->log_component[S1AP].fd = 0; @@ -326,7 +326,7 @@ int logInit (void) g_log->log_component[S1AP].filelog_name = ""; g_log->log_component[SCTP].name = "SCTP"; - g_log->log_component[SCTP].level = LOG_EMERG; + g_log->log_component[SCTP].level = LOG_DEBUG; g_log->log_component[SCTP].flag = LOG_MED; g_log->log_component[SCTP].interval = 1; g_log->log_component[SCTP].fd = 0; @@ -334,7 +334,7 @@ int logInit (void) g_log->log_component[SCTP].filelog_name = ""; g_log->log_component[HW].name = "HW"; - g_log->log_component[HW].level = LOG_EMERG; + g_log->log_component[HW].level = LOG_DEBUG; g_log->log_component[HW].flag = LOG_MED; g_log->log_component[HW].interval = 1; g_log->log_component[HW].fd = 0; @@ -342,7 +342,7 @@ int logInit (void) g_log->log_component[HW].filelog_name = ""; g_log->log_component[OSA].name = "OSA"; - g_log->log_component[OSA].level = LOG_EMERG; + g_log->log_component[OSA].level = LOG_DEBUG; g_log->log_component[OSA].flag = LOG_MED; g_log->log_component[OSA].interval = 1; g_log->log_component[OSA].fd = 0; @@ -350,7 +350,7 @@ int logInit (void) g_log->log_component[OSA].filelog_name = ""; g_log->log_component[RAL_ENB].name = "eRAL"; - g_log->log_component[RAL_ENB].level = LOG_EMERG; + g_log->log_component[RAL_ENB].level = LOG_DEBUG; g_log->log_component[RAL_ENB].flag = LOG_MED; g_log->log_component[RAL_ENB].interval = 1; g_log->log_component[RAL_ENB].fd = 0; @@ -358,7 +358,7 @@ int logInit (void) g_log->log_component[RAL_ENB].filelog_name = ""; g_log->log_component[RAL_UE].name = "mRAL"; - g_log->log_component[RAL_UE].level = LOG_EMERG; + g_log->log_component[RAL_UE].level = LOG_DEBUG; g_log->log_component[RAL_UE].flag = LOG_MED; g_log->log_component[RAL_UE].interval = 1; g_log->log_component[RAL_UE].fd = 0; @@ -366,7 +366,7 @@ int logInit (void) g_log->log_component[RAL_UE].filelog_name = ""; g_log->log_component[ENB_APP].name = "ENB_APP"; - g_log->log_component[ENB_APP].level = LOG_EMERG; + g_log->log_component[ENB_APP].level = LOG_DEBUG; g_log->log_component[ENB_APP].flag = LOG_MED; g_log->log_component[ENB_APP].interval = 1; g_log->log_component[ENB_APP].fd = 0; @@ -374,7 +374,7 @@ int logInit (void) g_log->log_component[ENB_APP].filelog_name = ""; g_log->log_component[TMR].name = "TMR"; - g_log->log_component[TMR].level = LOG_EMERG; + g_log->log_component[TMR].level = LOG_DEBUG; g_log->log_component[TMR].flag = LOG_MED; g_log->log_component[TMR].interval = 1; g_log->log_component[TMR].fd = 0; @@ -391,7 +391,7 @@ int logInit (void) /* following log component are used for the localization*/ g_log->log_component[LOCALIZE].name = "LOCALIZE"; - g_log->log_component[LOCALIZE].level = LOG_EMERG; + g_log->log_component[LOCALIZE].level = LOG_DEBUG; g_log->log_component[LOCALIZE].flag = LOG_MED; g_log->log_component[LOCALIZE].interval = 1; g_log->log_component[LOCALIZE].fd = 0; From 9bd28ec1376277eba625381f2afff360d1748703 Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 24 Nov 2015 20:40:35 +0100 Subject: [PATCH 002/571] merge with master --- openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 6 +++--- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 14 ++++++++------ openair1/SIMULATION/LTE_PHY/dlsim.c | 3 ++- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 7c19fef966..d131d524db 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -428,8 +428,8 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, phy_vars_ue->PHY_measurements.rank[eNB_id] = 0; else phy_vars_ue->PHY_measurements.rank[eNB_id] = 1; - printf ("tx mode %d\n", phy_vars_ue->transmission_mode[eNB_id]); - printf ("rank %d\n", phy_vars_ue->PHY_measurements.rank[eNB_id]); + // printf ("tx mode %d\n", phy_vars_ue->transmission_mode[eNB_id]); + // printf ("rank %d\n", phy_vars_ue->PHY_measurements.rank[eNB_id]); switch (N_RB_DL) { case 6: diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index b2e93c8b1d..7d6069b6dc 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4631,7 +4631,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } } else { - LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); } break; @@ -4694,7 +4694,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } } else { - LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); } break; @@ -4921,7 +4921,7 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->mcs = mcs2; if (dlsch1_harq->nb_rb>1) { - dlsch1_harq->TBS = TBStable[dlsch1_harq->mcs][dlsch1_harq->nb_rb-1]; + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; if (mcs2 <= 28) dlsch1_harq->Qm = get_Qm(mcs2); else if (mcs1<=31) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index bc5887a726..5bac69f8da 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -344,7 +344,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, frame_parms, symbol, first_symbol_flag, - get_Qm(dlsch0_harq->mcs), + dlsch0_harq->Qm, nb_rb, lte_ue_pdsch_vars[eNB_id]->log2_maxh, phy_measurements); // log2_maxh+I0_shift @@ -407,16 +407,18 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // effective channel of desired user is always stronger than interfering eff. channel dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, - avg, symbol, nb_rb, + avg, + symbol, + nb_rb, dlsch0_harq->mimo_mode); - /* + if (rx_type>rx_standard) { // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]); lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } else - */ + lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; } @@ -426,8 +428,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, phy_measurements, eNB_id, symbol, - get_Qm(dlsch0_harq->mcs), - get_Qm(dlsch1_harq->mcs), + dlsch0_harq->Qm, + dlsch1_harq->Qm, harq_pid, dlsch0_harq->round, dlsch0_harq->mimo_mode, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f636be5104..3d4c140ce5 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -410,6 +410,7 @@ int main(int argc, char **argv) case 'M': mcs2 = atoi(optarg); + i_mod = get_Qm(mcs2); /// think here again!!! break; case 't': @@ -1782,7 +1783,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; } } From c26f9fea3d4fcd38dba3d3051701bb3660e6631c Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 25 Nov 2015 20:32:30 +0100 Subject: [PATCH 003/571] Enabling XFORMS --- cmake_targets/lte-simulators/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index 7a0e84b425..0b706c8748 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8) set(PACKAGE_NAME "unitary_tests_simulators") set(PHYSIM True) set(RF_BOARD None) -set(XFORMS False) +set(XFORMS True) set(DEBUG_PHY False) set(MU_RECIEVER False) From 95762833810d3d5bd4f50ab8e899e1d2b55cb71c Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 25 Nov 2015 20:38:52 +0100 Subject: [PATCH 004/571] feature-59-tm4: fixing merge bugs in lte_phy_scope --- openair1/PHY/TOOLS/lte_phy_scope.c | 229 +++++++++++++++------------- openair1/PHY/TOOLS/lte_phy_scope.h | 3 - openair1/SIMULATION/LTE_PHY/dlsim.c | 2 +- 3 files changed, 121 insertions(+), 113 deletions(-) diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index b32477873f..f40377c85b 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -521,16 +521,17 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx]; int frame = phy_vars_ue->frame_rx; uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id]; - int coded_bits_per_codeword=0,coded_bits_per_codeword1=1; - int mod,mod1; - int mcs = 0; + int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1; + int mod0,mod1; + int mcs0 = 0; + int mcs1=0; unsigned char harq_pid = 0; if (phy_vars_ue->dlsch_ue[eNB_id][0]!=NULL) { harq_pid = phy_vars_ue->dlsch_ue[eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs = phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs; + mcs0 = phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 /* @@ -539,7 +540,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, fl_show_object(form->button_0); } */ - } + } + + + if (phy_vars_ue->dlsch_ue[eNB_id][1]!=NULL) { + harq_pid = phy_vars_ue->dlsch_ue[eNB_id][1]->current_harq_pid; + if (harq_pid>=8) + return; + + mcs1 = phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->mcs; + } if (phy_vars_ue->lte_ue_pdcch_vars[eNB_id]!=NULL) { num_pdcch_symbols = phy_vars_ue->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols; @@ -547,25 +557,25 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); if (phy_vars_ue->dlsch_ue[eNB_id][0]!=NULL) { - mod = get_Qm(phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs); - coded_bits_per_codeword = get_G(frame_parms, + mod0 = get_Qm(mcs0); + coded_bits_per_codeword0 = get_G(frame_parms, phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc, - get_Qm(phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs), + phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs0), phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe); } else { - coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - mod=0; + coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + mod0=0; } if (phy_vars_ue->dlsch_ue[eNB_id][1]!=NULL) { - mod1 = get_Qm(phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->mcs); + mod1 = get_Qm(mcs1); coded_bits_per_codeword1 = get_G(frame_parms, phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->rb_alloc, - get_Qm(phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->mcs), + phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs1), phy_vars_ue->dlsch_ue[eNB_id][1]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, @@ -582,8 +592,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, chest_t_abs[arx] = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float)); } chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); - llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero - bit = malloc(coded_bits_per_codeword*sizeof(float)); + llr = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // init to zero + bit = malloc(coded_bits_per_codeword0*sizeof(float)); llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); @@ -626,11 +636,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]); } } - - fl_add_xyplot_overlay(form->rxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]); - } } - } // Channel Impulse Response (still repeated format) if (chest_t != NULL) { @@ -660,83 +666,118 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT); } } - - - /* + // Avoid flickering effect + // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); + fl_set_xyplot_ybounds(form->chest_t,0,ymax); + } + + // Channel Frequency Response (includes 5 complex sample for filter) + if (chest_f != NULL) { + ind = 0; + for (atx=0;atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); + //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2); + // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2); + fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); + fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); + + for (arx=1;arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + // other tx antennas + if (nb_antennas_tx > 1) { + if (nb_antennas_rx > 1) { + for (atx=1;atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + } + } else { // 1 rx antenna + atx=1; arx=0; + fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + } + } + /* // PBCH LLRs if (pbch_llr != NULL) { for (i=0; i<1920;i++) { llr_pbch[i] = (float) pbch_llr[i]; bit_pbch[i] = (float) i; } - } + + fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","",""); } - // tx antenna 0 - fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); - //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2); - // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2); - fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); - fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); - - for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); - } - - // other tx antennas - if (nb_antennas_tx > 1) { - if (nb_antennas_rx > 1) { - for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); - } + // PBCH I/Q of MF Output + if (pbch_comp!=NULL) { + for (i=0; i<72*2; i++) { + I[i] = pbch_comp[2*i]; + Q[i] = pbch_comp[2*i+1]; } - } else { // 1 rx antenna - atx=1; - arx=0; - fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); - } - } - } - - // PBCH LLRs - if (pbch_llr != NULL) { - for (i=0; i<1920; i++) { - llr_pbch[i] = (float) pbch_llr[i]; - bit_pbch[i] = (float) i; + + fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","",""); } - fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","",""); - } + // PDCCH LLRs + if (pdcch_llr != NULL) { + for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) { + llr_pdcch[i] = (float) pdcch_llr[i]; + bit_pdcch[i] = (float) i; + } - // PBCH I/Q of MF Output - if (pbch_comp!=NULL) { - for (i=0; i<72*2; i++) { - I[i] = pbch_comp[2*i]; - Q[i] = pbch_comp[2*i+1]; + fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); + fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); + } + + // PDCCH I/Q of MF Output + if (pdcch_comp!=NULL) { + for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) { + I[i] = pdcch_comp[2*i]; + Q[i] = pdcch_comp[2*i+1]; + } + + fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); } */ - // PDSCH LLRs + // PDSCH LLRs CW0 if (pdsch_llr != NULL) { - for (i=0; ipdsch_llr,0,coded_bits_per_codeword/mod); - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword/mod,"","",""); + fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword0/mod0); + fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword0/mod0,"","",""); } - fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); - fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); - } - - // PDCCH I/Q of MF Output - if (pdcch_comp!=NULL) { - for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) { - I[i] = pdcch_comp[2*i]; - Q[i] = pdcch_comp[2*i+1]; + // PDSCH I/Q of MF Output + if (pdsch_comp!=NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i]; + Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; + ind++; + } + } + fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","",""); } @@ -751,6 +792,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN); } + + if (pdsch_magb0 != NULL) { ind=0; for (k=0; ksymbols_per_tti; k++) { @@ -781,7 +824,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } - // PDSCH LLRs + // PDSCH LLRs CW1 if (pdsch_llr1 != NULL) { for (i=0; ipdsch_comp,I,Q,ind,"","",""); } - // PDSCH Throughput - memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); - memmove( tput_ue[UE_id], &tput_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); - - tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; - tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; - - if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) { - tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1]; - } - - fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","",""); - - fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); - - fl_check_forms(); - - free(I); - free(Q); - free(chest_f_abs); - free(llr); - free(bit); - free(bit_pdcch); - free(llr_pdcch); - - for (arx=0; arx Date: Wed, 25 Nov 2015 22:52:42 +0100 Subject: [PATCH 005/571] feature-59-tm4: fixing dci_tools.c tmpi0 all channels all mod orders works --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 7 +++++++ openair1/SIMULATION/LTE_PHY/dlsim.c | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 7d6069b6dc..90fd2b8a79 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4765,6 +4765,13 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->rvidx = rv1; dlsch1_harq->rvidx = rv2; + // assume both TBs are active + dlsch0_harq->Nl = 1; + dlsch1_harq->Nl = 1; + dlsch0->active = 1; + dlsch1->active = 1; + + // check if either TB is disabled (see 36-213 V8.6 p. 26) if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 2db6cc46f8..3a392c01be 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -410,7 +410,7 @@ int main(int argc, char **argv) case 'M': mcs2 = atoi(optarg); - i_mod = get_Qm(mcs2); /// think here again!!! + //i_mod = get_Qm(mcs2); /// think here again!!! break; case 't': @@ -2747,9 +2747,9 @@ n(tikz_fname,"w"); k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), coded_bits_per_codeword, tbs, - get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), //changed dlsch_eNB[k][0] + get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->round);//changed dlsch_eNB[k][0] + PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->round); // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { @@ -3521,7 +3521,7 @@ n(tikz_fname,"w"); num_pdcch_symbols, 0,subframe); PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->G = coded_bits_per_codeword; - + PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->mcs); if (n_frames==1) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw,coded_bits_per_codeword, PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->TBS); From cf2b532a798699f8996721e4c3b171d8d3c53de8 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 26 Nov 2015 12:22:59 +0100 Subject: [PATCH 006/571] changes in dci_tools.c for TM4 to support tpmi2 --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 43 +++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 90fd2b8a79..dc4db92e2b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1551,7 +1551,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; dlsch0_harq->pmi_alloc = DL_pmi_single; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = DL_pmi_single; + dlsch1_harq->pmi_alloc = DL_pmi_single^ 0x1555; //opposite; this is just random assignment for first trial break; default: break; @@ -4806,9 +4806,9 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch0_harq->pmi_alloc = 0; //TODO: DL_pmi_single; + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = 0; //TODO: DL_pmi_single; + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; break; default: break; @@ -5774,7 +5774,7 @@ uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, ui } -uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands) +uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) { int i, aarx; @@ -5782,6 +5782,25 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subba uint16_t pmivect = 0; uint8_t rank = meas->rank[eNB_id]; int pmi_re,pmi_im; + int nb_subbands=0; + + + switch (nb_rb) { + case 6: + nb_subbands = 6; + break; + default: + case 25: + nb_subbands = 7; + break; + case 50: + nb_subbands = 9; + break; + case 100: + nb_subbands = 13; + break; + } + for (i=0; inb_antennas_rx; aarx++) { + pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; + pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; + } + if (pmi_re > pmi_im) + pmiq = PMI_2A_11; + else if (pmi_re < pmi_im) + pmiq = PMI_2A_1m1; + printf("subband %d, pmi%d \n",i,pmiq); + pmivect |= (pmiq<<(2*i)); + printf("subband %d pmivect %d \n",i, pmivect); + } + else { // This needs to be done properly!!! msg("PMI feedback for rank>1 not supported!\n"); pmivect = 0; From a9c3b9b4834df7617262470236532710e1b63c53 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 26 Nov 2015 17:02:30 +0100 Subject: [PATCH 007/571] config files for 2 antennas for usrp and exmimo --- .../CONF/enb.band38.exmimo2.conf | 169 ++++++++++++++++++ .../CONF/enb.band7.usrpb210.conf | 8 +- 2 files changed, 173 insertions(+), 4 deletions(-) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.exmimo2.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.exmimo2.conf new file mode 100644 index 0000000000..68bd3a10ec --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.exmimo2.conf @@ -0,0 +1,169 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2580000000L; + uplink_frequency_offset = 0; //-120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 2; + nb_antennas_rx = 2; + tx_gain = 10; //25; + rx_gain = 10; //20; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -26; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 0; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -85; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 2; + rach_preambleInitialReceivedTargetPower = -100; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.70"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.212/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.212/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="debug"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="debug"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf index 57a43fb414..af9baf9e7a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.usrpb210.conf @@ -17,7 +17,7 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "92"; + mobile_network_code = "93"; ////////// Physical parameters: @@ -132,7 +132,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.13.11"; + mme_ip_address = ( { ipv4 = "192.168.12.70"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -142,10 +142,10 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.13.10/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.212/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.13.10/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.212/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; From 13752a67680c1daf21d4102f156dde937acc2186 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 27 Nov 2015 17:13:48 +0100 Subject: [PATCH 008/571] fixing pmi_extend --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 75 ++++++++++++++++---------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 90fd2b8a79..192c95b375 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1538,20 +1538,20 @@ int generate_eNB_dlsch_params_from_dci(int frame, case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1,1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; dlsch0_harq->pmi_alloc = DL_pmi_single; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = DL_pmi_single; + dlsch1_harq->pmi_alloc = DL_pmi_single; //this is actually never used, since the PMI for the second codeword is always the opposote of the first one break; default: break; @@ -1566,19 +1566,19 @@ int generate_eNB_dlsch_params_from_dci(int frame, break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; @@ -2557,22 +2557,22 @@ int generate_eNB_dlsch_params_from_dci(int frame, case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); break; case 5: @@ -4795,14 +4795,14 @@ int generate_ue_dlsch_params_from_dci(int frame, case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1,1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; @@ -4822,19 +4822,19 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; @@ -5523,22 +5523,22 @@ int generate_ue_dlsch_params_from_dci(int frame, case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); break; case 5: @@ -6249,14 +6249,31 @@ void reset_cba_uci(void *o) ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = 0x0; } -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi) +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, unit8_t rank) { - uint8_t i,wideband_pmi2=wideband_pmi&3; + uint8_t i,wideband_pmi2; uint32_t pmi_ex = 0; - for (i=0; i<14; i+=2) - pmi_ex|=(wideband_pmi2<N_RB_DL!=25) { + LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n"); + return(-1); + } + + if (rank==0) { + wideband_pmi2=wideband_pmi&3; + for (i=0; i<14; i+=2) + pmi_ex|=(wideband_pmi2< Date: Mon, 30 Nov 2015 16:58:08 +0100 Subject: [PATCH 009/571] extrac_cqi translates pmi_dual into pmi_single --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/uci_tools.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 111f507fea..b3d6ed92c7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1257,9 +1257,9 @@ uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) // printf("Getting pmi for RB %d => %d\n",rb,(pmi_alloc>>((rb>>2)<<1))&3); switch (N_RB_DL) { case 6: // 1 PRB per subband - if (mode <= PUSCH_PRECODING1) + if (mode <= PUSCH_PRECODING1) //single layer return((pmi_alloc>>(rb<<1))&3); - else + else //two layer return((pmi_alloc>>rb)&1); break; diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index 1cccc4aaac..9719a8f3c1 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -285,6 +285,10 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_ stats->DL_cqi[1] = 24; stats->DL_pmi_dual = ((wideband_cqi_rank2_2A_5MHz *)o)->pmi; + //this translates the 2-layer PMI into a single layer PMI for the first codeword + //the PMI for the second codeword will be stats->DL_pmi_single^0x1555 + for (i=0;i<7;i++) + stats->DL_pmi_single&(1<<(2*i)) = (stats->DL_pmi_dual&(1 Date: Wed, 2 Dec 2015 11:04:00 +0100 Subject: [PATCH 010/571] extension to tmpi 2 for TM4 --- cmake_targets/CMakeLists.txt | 1 + openair1/PHY/LTE_TRANSPORT/dci_tools.c | 103 +- openair1/PHY/LTE_TRANSPORT/defs.h | 12 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 190 +++- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 8 +- openair1/PHY/LTE_TRANSPORT/proto.h | 6 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 32 +- openair1/SIMULATION/TOOLS/random_channel.c | 886 ++++++++---------- 8 files changed, 676 insertions(+), 562 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 90929d563b..95250297a5 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -119,6 +119,7 @@ endmacro(add_list_string_option) #################################################### # compilation flags ############################################# +set (CMAKE_BUILD_TYPE "Debug") if (CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index dc4db92e2b..cad71e4a8f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -872,7 +872,8 @@ int generate_eNB_dlsch_params_from_dci(int frame, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, - uint16_t DL_pmi_single) + uint16_t DL_pmi_single + ) { uint8_t harq_pid = UINT8_MAX; @@ -1538,14 +1539,14 @@ int generate_eNB_dlsch_params_from_dci(int frame, case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; @@ -1566,19 +1567,19 @@ int generate_eNB_dlsch_params_from_dci(int frame, break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; @@ -2108,12 +2109,13 @@ int generate_eNB_dlsch_params_from_dci(int frame, rballoc, frame_parms->N_RB_DL, dlsch0_harq->rb_alloc); - dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; + + dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + dlsch0_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; dlsch0_harq->mcs = mcs1; dlsch1_harq->mcs = mcs2; @@ -2557,27 +2559,27 @@ int generate_eNB_dlsch_params_from_dci(int frame, case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - dlsch0_harq->pmi_alloc = DL_pmi_single; + dlsch0_harq->pmi_alloc = DL_pmi_single; break; case 6: @@ -4795,14 +4797,14 @@ int generate_ue_dlsch_params_from_dci(int frame, case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; @@ -4822,19 +4824,19 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; @@ -5523,28 +5525,28 @@ int generate_ue_dlsch_params_from_dci(int frame, case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); break; @@ -5779,7 +5781,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) int i, aarx; uint16_t pmiq=0; - uint16_t pmivect = 0; + uint32_t pmivect = 0; // work with tyoe uint8_t rank = meas->rank[eNB_id]; int pmi_re,pmi_im; int nb_subbands=0; @@ -5827,18 +5829,20 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) // printf("subband %d, pmi%d \n",i,pmiq); pmivect |= (pmiq<<(2*i)); - } + } + else if (rank==1) { for (aarx=0; aarxnb_antennas_rx; aarx++) { pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; } if (pmi_re > pmi_im) - pmiq = PMI_2A_11; + pmiq = PMI_2A_R1_11; else if (pmi_re < pmi_im) - pmiq = PMI_2A_1m1; + pmiq = PMI_2A_R1_1j; printf("subband %d, pmi%d \n",i,pmiq); - pmivect |= (pmiq<<(2*i)); + //According to Section 7.2.4 of 36.213 + pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit printf("subband %d pmivect %d \n",i, pmivect); } else { @@ -6282,14 +6286,31 @@ void reset_cba_uci(void *o) ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = 0x0; } -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi) +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank) { - uint8_t i,wideband_pmi2=wideband_pmi&3; + uint8_t i,wideband_pmi2; uint32_t pmi_ex = 0; - for (i=0; i<14; i+=2) - pmi_ex|=(wideband_pmi2<N_RB_DL!=25) { + LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n"); + return(-1); + } + + if (rank==0) { + wideband_pmi2=wideband_pmi&3; + for (i=0; i<14; i+=2) + pmi_ex|=(wideband_pmi2<lte_ue_pdsch_vars_SI[eNB_id]; @@ -167,10 +172,13 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else rballoc = dlsch0_harq->rb_alloc_even; - if (dlsch0_harq->mimo_mode>DUALSTREAM_UNIFORM_PRECODINGj) { + if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) { LOG_E(PHY,"This transmission mode is not yet supported!\n"); return(-1); } + + + if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING))) { DevAssert(dlsch1_harq); if (eNB_id!=eNB_id_i) { @@ -182,9 +190,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //printf("rx_pdsch: harq_pid=%d, round=%d\n",harq_pid,round); if (frame_parms->nb_antennas_tx_eNB>1) { -#ifdef DEBUG_DLSCH_MOD - LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch_ue[0],dlsch0_harq->rb_alloc_even[0]); -#endif +//#ifdef DEBUG_DLSCH_MOD + //printf("dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch_ue[0],dlsch0_harq->rb_alloc_even[0]); +//#endif nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, @@ -195,7 +203,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, subframe, phy_vars_ue->high_speed_flag, - frame_parms); + frame_parms, + dlsch0_harq->mimo_mode); if (rx_type==rx_IC_single_stream) { if (eNB_id_in_connected_eNB) // we are in TM5 @@ -209,7 +218,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, subframe, phy_vars_ue->high_speed_flag, - frame_parms); + frame_parms, + dlsch0_harq->mimo_mode); else nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], @@ -221,7 +231,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, subframe, phy_vars_ue->high_speed_flag, - frame_parms); + frame_parms, + dlsch0_harq->mimo_mode); } } // if n_tx>1 else { @@ -406,7 +417,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (first_symbol_flag==1) { // effective channel of desired user is always stronger than interfering eff. channel dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, + frame_parms, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb, @@ -418,8 +430,6 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } else - - lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; } @@ -488,7 +498,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (first_symbol_flag==1) { // effective channel of desired user is always stronger than interfering eff. channel - dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb); + dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + avg, + symbol, + nb_rb); // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; @@ -949,7 +964,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); return(-1); break; - } + } return(0); } @@ -1388,7 +1403,8 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 - + _mm_empty(); + _m_empty(); // print_shorts("prec2A_TM4 ch0 (end):",ch0); //print_shorts("prec2A_TM4 ch1 (end):",ch1); } @@ -1814,6 +1830,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; + unsigned char **pmi_ext = lte_ue_pdsch_vars->pmi_ext; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -1884,6 +1901,17 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); } } + + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); + + if (pilots==0) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + } + } + + else { LOG_E(PHY,"Unknown MIMO mode\n"); return; @@ -2984,8 +3012,119 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, #endif } +//compute average channel_level of effective (precoded) channel + //compute average channel_level of effective (precoded) channel void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, + LTE_DL_FRAME_PARMS *frame_parms, + unsigned char *pmi_ext, + int *avg, + uint8_t symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode){ + +#if defined(__x86_64__)||defined(__i386__) + + + short rb; + unsigned char aarx,nre=12,symbol_mod; + __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + //clear average level + avg128D = _mm_setzero_si128(); + avg[0] = 0; + avg[1] = 0; + // 5 is always a symbol with no pilots for both normal and extended prefix + + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) + nre=8; + else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1)) + nre=10; + else + nre=12; + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + + for (rb=0; rbNcp-1)))&&(frame_parms->mode1_flag==0)) { + dl_ch0_128+=2; + dl_ch1_128+=2; + } + else { + dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); + dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); + + if (mimo_mode==LARGE_CDD) + prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) + prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) + prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); + // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + dl_ch0_128+=3; + dl_ch1_128+=3; + } + } + + avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + + (((int*)&avg128D)[1])/(nb_rb*nre) + + (((int*)&avg128D)[2])/(nb_rb*nre) + + (((int*)&avg128D)[3])/(nb_rb*nre); + } + + // choose maximum of the 2 effective channels + avg[0] = cmax(avg[0],avg[1]); + + _mm_empty(); + _m_empty(); + +#elif defined(__arm__) + +#endif +} + + + +/*void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, int *avg, uint8_t symbol, @@ -3084,7 +3223,7 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, #elif defined(__arm__) #endif -} +}*/ //compute average channel_level of effective (precoded) channel void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, @@ -3874,10 +4013,17 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, unsigned char symbol, unsigned char subframe, uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms) { + LTE_DL_FRAME_PARMS *frame_parms, + MIMO_mode_t mimo_mode) { +/*uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) +{ + MIMO_mode_t mode = dlsch_harq->mimo_mode;*/ + +//PHY_VARS_UE *phy_vars_ue, + int prb,nb_rb=0; int prb_off,prb_off2; int rb_alloc_ind,skip_half=0,sss_symb,pss_symb=0,nsymb,l; @@ -3885,7 +4031,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, int32_t *dl_ch0,*dl_ch0p,*dl_ch0_ext,*dl_ch1,*dl_ch1p,*dl_ch1_ext,*rxF,*rxF_ext; int symbol_mod,pilots=0,j=0; unsigned char *pmi_loc; - + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; // printf("extract_rbs: symbol_mod %d\n",symbol_mod); @@ -3999,7 +4145,12 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } + + if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; + else + *pmi_loc=(pmi>>prb)&1; + pmi_loc++; @@ -4136,8 +4287,11 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, #ifdef DEBUG_DLSCH_DEMOD printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); #endif - *pmi_loc = (pmi>>((prb>>2)<<1))&3; - // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,rb,rb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); + if (mimo_mode <= PUSCH_PRECODING1) + *pmi_loc = (pmi>>((prb>>2)<<1))&3; + else + *pmi_loc=(pmi>>prb)&1; + // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); pmi_loc++; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 111f507fea..c4e706b5a7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -786,7 +786,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, precoder_index1 = 3; //[1 -j] } else { - LOG_E(PHY,"problem with precoder in TM4\n"); + printf("problem with precoder in TM4\n"); return(-1); } @@ -1254,7 +1254,7 @@ uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) MIMO_mode_t mode = dlsch_harq->mimo_mode; uint32_t pmi_alloc = dlsch_harq->pmi_alloc; - // printf("Getting pmi for RB %d => %d\n",rb,(pmi_alloc>>((rb>>2)<<1))&3); + printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>rb)&1)); switch (N_RB_DL) { case 6: // 1 PRB per subband if (mode <= PUSCH_PRECODING1) @@ -1369,10 +1369,10 @@ int dlsch_modulation(mod_sym_t **txdataF, for (l=num_pdcch_symbols; lmimo_mode, - pmi2hex_2Ar1(dlsch0_harq->pmi_alloc), + pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), mod_order0, mod_order1, rb_alloc[0], diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index a12a6f6743..79d68ab066 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -909,7 +909,8 @@ uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF, uint8_t symbol, uint8_t subframe, uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms); + LTE_DL_FRAME_PARMS *frame_parms, + MIMO_mode_t mimo_mode); /** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation) @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated @@ -994,6 +995,7 @@ void dlsch_channel_level(int32_t **dl_ch_estimates_ext, void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, + unsigned char *pmi_ext, int *avg, uint8_t symbol, unsigned short nb_rb, @@ -1587,7 +1589,7 @@ uint64_t cqi2hex(uint32_t cqi); uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi); +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank); uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3a392c01be..a72ab6a01e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -450,7 +450,7 @@ int main(int argc, char **argv) case 'w': snr_int = atof(optarg); break; - + case 'f': input_snr_step= atof(optarg); break; @@ -1529,7 +1529,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; case 50: dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; @@ -1662,7 +1662,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_TDD_t; @@ -1679,7 +1679,7 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 50: @@ -1697,7 +1697,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 100: @@ -1713,7 +1713,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; dci_length = sizeof_DCI2_20MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); break; @@ -1791,6 +1791,12 @@ n(tikz_fname,"w"); else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { } + + if (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) { // not a nice way to do it, fix later + + PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); + + } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -2765,6 +2771,14 @@ n(tikz_fname,"w"); } */ } + + + if (transmission_mode==4 && (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)){ + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + start_meas(&PHY_vars_eNB->dlsch_encoding_stats); @@ -2929,10 +2943,6 @@ n(tikz_fname,"w"); // r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); // r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); -// printf("r_re0 = %d\n",r_re[0][i]); -// printf("r_im0 = %d\n",r_im[0][i]); -// printf("r_re1 = %d\n",r_re[1][i]); -// printf("r_im1 = %d\n",r_im[1][i]); } else { @@ -3165,7 +3175,7 @@ n(tikz_fname,"w"); PHY_vars_UE->PHY_measurements.wideband_cqi_avg[0]); */ - if (transmission_mode==5 || transmission_mode==6) { + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) { if (pmi_feedback == 1) { pmi_feedback = 0; hold_channel = 1; diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 027dc84cf5..a378a56c76 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -1,5 +1,5 @@ /******************************************************************************* - OpenAirInterface + OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify @@ -14,15 +14,15 @@ 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, + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, see . Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - + OpenAirInterface Dev : openair4g-devel@eurecom.fr + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ @@ -42,29 +42,28 @@ extern void print_shorts(char *s,__m128i *x); void fill_channel_desc(channel_desc_t *chan_desc, - uint8_t nb_tx, - uint8_t nb_rx, - uint8_t nb_taps, - uint8_t channel_length, - double *amps, - double *delays, - struct complex** R_sqrt, - double Td, - double BW, - double ricean_factor, - double aoa, - double forgetting_factor, - double max_Doppler, - int32_t channel_offset, - double path_loss_dB, - uint8_t random_aoa) -{ - + uint8_t nb_tx, + uint8_t nb_rx, + uint8_t nb_taps, + uint8_t channel_length, + double *amps, + double *delays, + struct complex** R_sqrt, + double Td, + double BW, + double ricean_factor, + double aoa, + double forgetting_factor, + double max_Doppler, + int32_t channel_offset, + double path_loss_dB, + uint8_t random_aoa) { + uint16_t i,j; double delta_tau; LOG_I(OCM,"[CHANNEL] Getting new channel descriptor, nb_tx %d, nb_rx %d, nb_taps %d, channel_length %d\n", - nb_tx,nb_rx,nb_taps,channel_length); + nb_tx,nb_rx,nb_taps,channel_length); chan_desc->nb_tx = nb_tx; chan_desc->nb_rx = nb_rx; @@ -72,14 +71,13 @@ void fill_channel_desc(channel_desc_t *chan_desc, chan_desc->channel_length = channel_length; chan_desc->amps = amps; LOG_D(OCM,"[CHANNEL] Doing delays ...\n"); - if (delays==NULL) { chan_desc->delays = (double*) malloc(nb_taps*sizeof(double)); delta_tau = Td/nb_taps; - for (i=0; idelays[i] = ((double)i)*delta_tau; - } else + } + else chan_desc->delays = delays; chan_desc->Td = Td; @@ -99,30 +97,26 @@ void fill_channel_desc(channel_desc_t *chan_desc, LOG_D(OCM,"[CHANNEL] Filling ch \n"); - for (i = 0; ich[i] = (struct complex*) malloc(channel_length * sizeof(struct complex)); + for (i = 0; ich[i] = (struct complex*) malloc(channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); // allocate for up to 100 RBs, 12 samples per RB LOG_D(OCM,"[CHANNEL] Filling a (nb_taps %d)\n",nb_taps); - for (i = 0; ia[i],nb_tx*nb_rx * sizeof(struct complex)); chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); } LOG_D(OCM,"[CHANNEL] Doing R_sqrt ...\n"); - if (R_sqrt == NULL) { - chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); - + chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); - + chan_desc->R_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; + chan_desc->R_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; } } } @@ -142,8 +136,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, } LOG_D(OCM,"[CHANNEL] RF %f\n",chan_desc->ricean_factor); - - for (i=0; inb_taps; i++) + for (i=0;inb_taps;i++) LOG_D(OCM,"[CHANNEL] tap %d: amp %f, delay %f\n",i,chan_desc->amps[i],chan_desc->delays[i]); chan_desc->nb_paths=10; @@ -181,23 +174,21 @@ struct complex R_sqrt_22_corr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {0.70711,0}, { {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {0.70711,0}}; - struct complex *R_sqrt_22_corr[1] = {R_sqrt_22_corr_tap}; //correlation matrix for a fully correlated 2x1 channel (h1==h2) -struct complex R_sqrt_21_corr_tap[4] = {{0.70711,0}, {0.70711,0}, {0.70711,0}, {0.70711,0}}; +struct complex R_sqrt_21_corr_tap[4] = {{0.70711,0}, {0.70711,0}, {0.70711,0}, {0.70711,0}}; struct complex *R_sqrt_21_corr[1] = {R_sqrt_21_corr_tap}; -//correlation matrix for a 2x2 channel with full Tx anti-correlation -struct complex R_sqrt_22_anticorr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0}, - {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, - {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0} -}; +//correlation matrix for a 2x2 channel with full Tx anti-correlation +struct complex R_sqrt_22_anticorr_tap[16] = {{0.70711,0}, {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, + {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, {-0.70711,0}, + {-0.70711,0}, {0.0, 0.0}, {0.70711,0}, {0.0, 0.0}, + {0.0, 0.0}, {-0.70711,0}, {0.0, 0.0}, {0.70711,0}}; struct complex *R_sqrt_22_anticorr[1] = {R_sqrt_22_anticorr_tap}; //correlation matrix for a fully anti-correlated 2x1 channel (h1==-h2) -struct complex R_sqrt_21_anticorr_tap[4] = {{0.70711,0}, {-0.70711,0}, {-0.70711,0}, {0.70711,0}}; +struct complex R_sqrt_21_anticorr_tap[4] = {{0.70711,0}, {-0.70711,0}, {-0.70711,0}, {0.70711,0}}; struct complex *R_sqrt_21_anticorr[1] = {R_sqrt_21_anticorr_tap}; struct complex **R_sqrt_ptr2; @@ -233,14 +224,13 @@ struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_imag[1] = {R_sqrt_22_orth_eff //Rayleigh1_orth_eff_ch_TM4 -channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, - uint8_t nb_rx, - SCM_t channel_model, - double BW, - double forgetting_factor, - int32_t channel_offset, - double path_loss_dB) -{ +channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, + uint8_t nb_rx, + SCM_t channel_model, + double BW, + double forgetting_factor, + int32_t channel_offset, + double path_loss_dB) { channel_desc_t *chan_desc = (channel_desc_t *)malloc(sizeof(channel_desc_t)); uint16_t i,j; @@ -264,27 +254,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, LOG_W(OCM,"channel model not yet supported\n"); free(chan_desc); return(NULL); - case SCM_B: LOG_W(OCM,"channel model not yet supported\n"); free(chan_desc); return(NULL); - case SCM_C: chan_desc->nb_taps = 18; chan_desc->Td = 4.625; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = scm_c_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -292,42 +277,37 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; - } else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else if (nb_tx==2 && nb_rx==1) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; + } + else if (nb_tx==1 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; + } + else { for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); } } - break; - case SCM_D: LOG_W(OCM,"This is not the real SCM-D model! It is just SCM-C with an additional Rice factor!\n"); chan_desc->nb_taps = 18; @@ -335,15 +315,12 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = scm_c_delays; chan_desc->ricean_factor = 0.1; chan_desc->aoa = 0; @@ -351,57 +328,49 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; - } else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else if (nb_tx==2 && nb_rx==1) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; + } + else if (nb_tx==1 && nb_rx==2) { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; + } + else { for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); } } - break; - case EPA: chan_desc->nb_taps = 7; chan_desc->Td = .410; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = epa_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -409,53 +378,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } - break; - case EVA: chan_desc->nb_taps = 9; chan_desc->Td = 2.51; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = eva_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -463,53 +420,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } - break; - case ETU: chan_desc->nb_taps = 9; chan_desc->Td = 5.0; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = etu_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -517,53 +462,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); - if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; - } else { + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + } + else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } - break; - case MBSFN: chan_desc->nb_taps = 18; chan_desc->Td = 28.58; chan_desc->channel_length = (int) (2*chan_desc->BW*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->BW*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); - for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); sum_amps += chan_desc->amps[i]; } - for (i = 0; inb_taps; i++) chan_desc->amps[i] /= sum_amps; - chan_desc->delays = mbsfn_delays; chan_desc->ricean_factor = 1; chan_desc->aoa = 0; @@ -571,168 +504,162 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex*)); - for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; + chan_desc->R_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } - break; - case Rayleigh8: - nb_taps = 8; - Td = 0.8; - channel_length = (int)11+2*BW*Td; - ricean_factor = 1; - aoa = .03; - maxDoppler = 0; + nb_taps = 8; + Td = 0.8; + channel_length = (int)11+2*BW*Td; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc, - nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc, + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rice8: - nb_taps = 8; - Td = 0.8; - channel_length = (int)11+2*BW*Td; - ricean_factor = 0.1; - aoa = .03; - maxDoppler = 0; + nb_taps = 8; + Td = 0.8; + channel_length = (int)11+2*BW*Td; + ricean_factor = 0.1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); + break; case Rayleigh1: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rayleigh1_800: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 1; - aoa = .03; - maxDoppler = 800; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = .03; + maxDoppler = 800; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rayleigh1_corr: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 1; + aoa = .03; + maxDoppler = 0; - if ((nb_tx==2) && (nb_rx==1)) { - R_sqrt_ptr2 = R_sqrt_21_corr; - } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_corr; - } else - R_sqrt_ptr2 = NULL; + if ((nb_tx==2) && (nb_rx==1)) { + R_sqrt_ptr2 = R_sqrt_21_corr; + } + else if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_corr; + } + else + R_sqrt_ptr2 = NULL; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case Rayleigh1_anticorr: nb_taps = 1; @@ -770,58 +697,58 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, break; case Rice1: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 0.1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 0.1; + aoa = .03; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; case AWGN: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 0.0; - aoa = 0.0; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 0.0; + aoa = 0.0; + maxDoppler = 0; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - printf("AWGN: ricean_factor %f\n",chan_desc->ricean_factor); + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + printf("AWGN: ricean_factor %f\n",chan_desc->ricean_factor); - break; + break; case TS_SHIFT: nb_taps = 2; @@ -852,40 +779,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, break; case Rice1_corr: - nb_taps = 1; - Td = 0; - channel_length = 1; - ricean_factor = 0.1; - aoa = .03; - maxDoppler = 0; + nb_taps = 1; + Td = 0; + channel_length = 1; + ricean_factor = 0.1; + aoa = .03; + maxDoppler = 0; - if ((nb_tx==2) && (nb_rx==1)) { - R_sqrt_ptr2 = R_sqrt_21_corr; - } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_corr; - } else - R_sqrt_ptr2 = NULL; + if ((nb_tx==2) && (nb_rx==1)) { + R_sqrt_ptr2 = R_sqrt_21_corr; + } + else if ((nb_tx==2) && (nb_rx==2)) { + R_sqrt_ptr2 = R_sqrt_22_corr; + } + else + R_sqrt_ptr2 = NULL; - fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - BW, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); - break; + fill_channel_desc(chan_desc,nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + BW, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); + break; case Rice1_anticorr: - nb_taps = 1; Td = 0; channel_length = 1; @@ -1094,10 +1022,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, free(chan_desc); return(NULL); } - LOG_D(OCM,"[CHANNEL] RF %f\n",chan_desc->ricean_factor); - - for (i=0; inb_taps; i++) + for (i=0;inb_taps;i++) LOG_D(OCM,"[CHANNEL] tap %d: amp %f, delay %f\n",i,chan_desc->amps[i],chan_desc->delays[i]); chan_desc->nb_paths = 10; @@ -1106,46 +1032,43 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } -int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) -{ - +int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { + double s; int i,k,l,aarx,aatx; struct complex anew[NB_ANTENNAS_TX*NB_ANTENNAS_RX],acorr[NB_ANTENNAS_TX*NB_ANTENNAS_RX]; struct complex phase, alpha, beta; - + if ((desc->nb_tx>NB_ANTENNAS_TX) || (desc->nb_rx > NB_ANTENNAS_RX)) { msg("random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); return(-1); } start_meas(&desc->random_channel); + for (i=0;i<(int)desc->nb_taps;i++) { + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { - for (i=0; i<(int)desc->nb_taps; i++) { - for (aarx=0; aarxnb_rx; aarx++) { - for (aatx=0; aatxnb_tx; aatx++) { + anew[aarx+(aatx*desc->nb_rx)].x = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); + anew[aarx+(aatx*desc->nb_rx)].y = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - anew[aarx+(aatx*desc->nb_rx)].x = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - anew[aarx+(aatx*desc->nb_rx)].y = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - - if ((i==0) && (desc->ricean_factor != 1.0)) { - if (desc->random_aoa==1) { - desc->aoa = uniformrandom()*2*M_PI; - } - - // this assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. - // Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so - // that we can safely assume plane wave propagation. - phase.x = cos(M_PI*((aarx-aatx)*sin(desc->aoa))); - phase.y = sin(M_PI*((aarx-aatx)*sin(desc->aoa))); - - anew[aarx+(aatx*desc->nb_rx)].x += phase.x * sqrt(1.0-desc->ricean_factor); - anew[aarx+(aatx*desc->nb_rx)].y += phase.y * sqrt(1.0-desc->ricean_factor); - } + if ((i==0) && (desc->ricean_factor != 1.0)) { + if (desc->random_aoa==1) { + desc->aoa = uniformrandom()*2*M_PI; + } + // this assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. + // Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so + // that we can safely assume plane wave propagation. + phase.x = cos(M_PI*((aarx-aatx)*sin(desc->aoa))); + phase.y = sin(M_PI*((aarx-aatx)*sin(desc->aoa))); + + anew[aarx+(aatx*desc->nb_rx)].x += phase.x * sqrt(1.0-desc->ricean_factor); + anew[aarx+(aatx*desc->nb_rx)].y += phase.y * sqrt(1.0-desc->ricean_factor); + } #ifdef DEBUG_CH - printf("(%d,%d,%d) %f->(%f,%f) (%f,%f) phase (%f,%f)\n",aarx,aatx,i,desc->amps[i],anew[aarx+(aatx*desc->nb_rx)].x,anew[aarx+(aatx*desc->nb_rx)].y,desc->aoa,desc->ricean_factor,phase.x,phase.y); -#endif + printf("(%d,%d,%d) %f->(%f,%f) (%f,%f) phase (%f,%f)\n",aarx,aatx,i,desc->amps[i],anew[aarx+(aatx*desc->nb_rx)].x,anew[aarx+(aatx*desc->nb_rx)].y,desc->aoa,desc->ricean_factor,phase.x,phase.y); +#endif } //aatx } //aarx @@ -1153,9 +1076,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) // for debugging set a=anew; for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - desc->a[i][aarx+(aatx*desc->nb_rx)].x = anew[aarx+(aatx*desc->nb_rx)].x; - desc->a[i][aarx+(aatx*desc->nb_rx)].y = anew[aarx+(aatx*desc->nb_rx)].y; - printf("anew(%d,%d) = %f+1j*%f\n",aatx,aarx,anew[aarx+(aatx*desc->nb_rx)].x, anew[aarx+(aatx*desc->nb_rx)].y); + desc->a[i][aarx+(aatx*desc->nb_rx)].x = anew[aarx+(aatx*desc->nb_rx)].x; + desc->a[i][aarx+(aatx*desc->nb_rx)].y = anew[aarx+(aatx*desc->nb_rx)].y; + printf("anew(%d,%d) = %f+1j*%f\n",aatx,aarx,anew[aarx+(aatx*desc->nb_rx)].x, anew[aarx+(aatx*desc->nb_rx)].y); } } */ @@ -1166,23 +1089,24 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) beta.x = 0.0; beta.y = 0.0; - cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx, - (void*) &alpha, (void*) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, - (void*) anew, 1, (void*) &beta, (void*) acorr, 1); + cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx, + (void*) &alpha, (void*) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, + (void*) anew, 1, (void*) &beta, (void*) acorr, 1); /* for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; - desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; - printf("tap %d, acorr1(%d,%d) = %f+1j*%f\n",i,aatx,aarx,acorr[aarx+(aatx*desc->nb_rx)].x, acorr[aarx+(aatx*desc->nb_rx)].y); + desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; + desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; + printf("tap %d, acorr1(%d,%d) = %f+1j*%f\n",i,aatx,aarx,acorr[aarx+(aatx*desc->nb_rx)].x, acorr[aarx+(aatx*desc->nb_rx)].y); } } */ - if (desc->first_run==1) { + if (desc->first_run==1){ cblas_zcopy(desc->nb_tx*desc->nb_rx, (void*) acorr, 1, (void*) desc->a[i], 1); - } else { + } + else { // a = alpha*acorr+beta*a // a = beta*a // a = a+alpha*acorr @@ -1200,19 +1124,18 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) /* for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - //desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; - //desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; - printf("tap %d, a(%d,%d) = %f+1j*%f\n",i,aatx,aarx,desc->a[i][aarx+(aatx*desc->nb_rx)].x, desc->a[i][aarx+(aatx*desc->nb_rx)].y); + //desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; + //desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; + printf("tap %d, a(%d,%d) = %f+1j*%f\n",i,aatx,aarx,desc->a[i][aarx+(aatx*desc->nb_rx)].x, desc->a[i][aarx+(aatx*desc->nb_rx)].y); } } */ - } //nb_taps - + } //nb_taps stop_meas(&desc->random_channel); //memset((void *)desc->ch[aarx+(aatx*desc->nb_rx)],0,(int)(desc->channel_length)*sizeof(struct complex)); - + if (abstraction_flag==0) { start_meas(&desc->interp_time); for (aarx=0;aarxnb_rx;aarx++) { @@ -1243,16 +1166,14 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) // printf("l %d : desc->ch.x %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x); } //nb_taps - #ifdef DEBUG_CH - printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); + printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); #endif - } - } //channel_length - } //aatx - } //aarx - - stop_meas(&desc->interp_time); + } + } //channel_length + } //aatx + } //aarx + stop_meas(&desc->interp_time); } if (desc->first_run==1) @@ -1264,13 +1185,12 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) #ifdef RANDOM_CHANNEL_MAIN #define BW 5.0 #define Td 2.0 -main(int argc,char **argv) -{ +main(int argc,char **argv) { double amps[8] = {.8,.2,.1,.04,.02,.01,.005}; struct complex ch[(int)(1+2*BW*Td)],phase; int i; - + randominit(); phase.x = 1.0; phase.y = 0; @@ -1282,4 +1202,4 @@ main(int argc,char **argv) */ } -#endif +#endif \ No newline at end of file From 6143779c63af4eba22576c6e97030e0e28f0d6e7 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 2 Dec 2015 11:13:47 +0100 Subject: [PATCH 011/571] documentation --- openair1/PHY/LTE_TRANSPORT/proto.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index a12a6f6743..d7effff3c9 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1574,10 +1574,18 @@ void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL); void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode); void fill_CQI(LTE_UE_ULSCH_t *ulsch,PHY_MEASUREMENTS *meas,uint8_t eNB_id, uint8_t harq_pid,int N_RB_DL, rnti_t rnti, uint8_t trans_mode,double sinr_eff); + void reset_cba_uci(void *o); +/** \brief This routine computes the subband PMI bitmap based on measurements (0,1,2,3 for rank 0 and 0,1 for rank 1) in the format needed for UCI + @param meas pointer to measurements + @param eNB_id eNB_id + @param nb_subbands number of subbands + @returns subband PMI bitmap +*/ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands); -uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands); + +//uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands); uint64_t pmi2hex_2Ar1(uint32_t pmi); @@ -1587,7 +1595,21 @@ uint64_t cqi2hex(uint32_t cqi); uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi); +/** \brief This routine expands a single (wideband) PMI to subband PMI bitmap similar to the one used in the UCI and in the dlsch_modulation routine + @param frame_parms Pointer to DL frame configuration parameters + @param wideband_pmi (0,1,2,3 for rank 0 and 0,1 for rank 1) + @param rank (0 or 1) + @returns subband PMI bitmap +*/ +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, unit8_t rank); + +/** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function + @param N_RB_DL number of resource blocks + @param dlsch_harq pointer to dlsch structure (containing mimo_mode and pmi_alloc) + @param rb resource block for which to extract PMI + @returns subband PMI +*/ +uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb); uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi); From e24847b1300f90355dcfc0265af7a0ae59c07a30 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 2 Dec 2015 11:25:16 +0100 Subject: [PATCH 012/571] fixing last commit --- openair1/PHY/LTE_TRANSPORT/proto.h | 2 +- openair1/PHY/LTE_TRANSPORT/uci_tools.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index a790070efa..87f494e826 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1603,7 +1603,7 @@ uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); @param rank (0 or 1) @returns subband PMI bitmap */ -uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, unit8_t rank); +uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank); /** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function @param N_RB_DL number of resource blocks diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c index 9719a8f3c1..cd6a4cdef2 100644 --- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c @@ -178,6 +178,7 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_ //unsigned char rank; //UCI_format fmt; //uint8_t N_RB_DL = 25; + uint8_t i; LOG_D(PHY,"[eNB][UCI] N_RB_DL %d uci format %d\n", N_RB_DL,uci_format); switch(N_RB_DL) { @@ -287,8 +288,9 @@ void extract_CQI(void *o,UCI_format_t uci_format,LTE_eNB_UE_stats *stats, uint8_ stats->DL_pmi_dual = ((wideband_cqi_rank2_2A_5MHz *)o)->pmi; //this translates the 2-layer PMI into a single layer PMI for the first codeword //the PMI for the second codeword will be stats->DL_pmi_single^0x1555 + stats->DL_pmi_single = 0; for (i=0;i<7;i++) - stats->DL_pmi_single&(1<<(2*i)) = (stats->DL_pmi_dual&(1DL_pmi_single = stats->DL_pmi_single | (((stats->DL_pmi_dual&(1>i)*2)<<2*i; break; case HLC_subband_cqi_nopmi: From cce0b45f97cc73f7e06bdd21bf8ad2be54699fd2 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 2 Dec 2015 13:02:45 +0100 Subject: [PATCH 013/571] a few small bugfixes, but not yet finished --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 21 +++++++++---------- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 16 ++++---------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 8 +++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 16 +++++++------- 4 files changed, 26 insertions(+), 35 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index a7ce2b2e00..cfb250b7ca 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5841,22 +5841,21 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; } - if (pmi_re > pmi_im) - pmiq = PMI_2A_R1_11; - else if (pmi_re < pmi_im) - pmiq = PMI_2A_R1_1j; - printf("subband %d, pmi%d \n",i,pmiq); - //According to Section 7.2.4 of 36.213 - pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit - printf("subband %d pmivect %d \n",i, pmivect); + if (pmi_re > pmi_im) + pmiq = PMI_2A_R1_11; + else //if (pmi_re < pmi_im) + pmiq = PMI_2A_R1_1j; + printf("subband %d, pmi_re %d, pmi_in %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); + //According to Section 7.2.4 of 36.213 + pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit } - else { - // This needs to be done properly!!! - msg("PMI feedback for rank>1 not supported!\n"); + else { + LOG_E(PHY,"PMI feedback for rank>1 not supported!\n"); pmivect = 0; } } + printf("subband %d pmivect %d \n",i, pmivect); return(pmivect); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 303fdd0a4f..12958f07bd 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -190,9 +190,6 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //printf("rx_pdsch: harq_pid=%d, round=%d\n",harq_pid,round); if (frame_parms->nb_antennas_tx_eNB>1) { -//#ifdef DEBUG_DLSCH_MOD - //printf("dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch_ue[0],dlsch0_harq->rb_alloc_even[0]); -//#endif nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, @@ -205,6 +202,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, phy_vars_ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); +//#ifdef DEBUG_DLSCH_MOD + printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc,*lte_ue_pdsch_vars[eNB_id]->pmi_ext); +//#endif if (rx_type==rx_IC_single_stream) { if (eNB_id_in_connected_eNB) // we are in TM5 @@ -1830,7 +1830,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; - unsigned char **pmi_ext = lte_ue_pdsch_vars->pmi_ext; + unsigned char *pmi_ext = lte_ue_pdsch_vars->pmi_ext; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -4016,14 +4016,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, LTE_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode) { -/*uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) -{ - - - MIMO_mode_t mode = dlsch_harq->mimo_mode;*/ - -//PHY_VARS_UE *phy_vars_ue, - int prb,nb_rb=0; int prb_off,prb_off2; int rb_alloc_ind,skip_half=0,sss_symb,pss_symb=0,nsymb,l; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 5323dbbcdd..0c40569f3b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1254,7 +1254,6 @@ uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) MIMO_mode_t mode = dlsch_harq->mimo_mode; uint32_t pmi_alloc = dlsch_harq->pmi_alloc; - printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>rb)&1)); switch (N_RB_DL) { case 6: // 1 PRB per subband if (mode <= PUSCH_PRECODING1) //single layer @@ -1268,9 +1267,10 @@ uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) case 25: // 4 PRBs per subband if (mode <= PUSCH_PRECODING1) return((pmi_alloc>>((rb>>2)<<1))&3); - else + else { + printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); return((pmi_alloc>>(rb>>2))&1); - + } break; case 50: // 6 PRBs per subband @@ -1369,7 +1369,7 @@ int dlsch_modulation(mod_sym_t **txdataF, for (l=num_pdcch_symbols; lmimo_mode, pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a72ab6a01e..efbc7ba99e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1712,8 +1712,8 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; dci_length = sizeof_DCI2_20MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); break; @@ -1735,7 +1735,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_FDD_t; @@ -1751,7 +1751,7 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; case 50: dci_length = sizeof_DCI2_10MHz_2A_FDD_t; @@ -1767,7 +1767,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; case 100: dci_length = sizeof_DCI2_20MHz_2A_FDD_t; @@ -1783,7 +1783,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; break; } } @@ -2149,7 +2149,7 @@ n(tikz_fname,"w"); // printf("Trial %d, round %d\n",trials,round); round_trials[round]++; - if(transmission_mode>=5) + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) pmi_feedback=1; else pmi_feedback=0; @@ -2773,7 +2773,7 @@ n(tikz_fname,"w"); } - if (transmission_mode==4 && (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)){ + if (transmission_mode==4 && (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)){ PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); } From 8d85ca9c78d4fd03b796602ee94c63538c4ad0ee Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 2 Dec 2015 14:28:30 +0100 Subject: [PATCH 014/571] fixed cor matrix for tpmi=1, -gR works now --- openair1/SIMULATION/TOOLS/random_channel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index a378a56c76..d4c1d45a75 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -217,7 +217,7 @@ struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_real[1] = {R_sqrt_22_orth_eff struct complex R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap[16] = {{0.70711,0.0}, {0.0,0.0}, {0.0, -0.70711}, {0.0,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.0,0.70711}, {0.0,-0.70711}, {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {0.0,0.70711}, {0.0, 0.70711}, {-0.70711,0.0}}; + {0.0, 0.0}, {0.0,0.70711}, {0.0, 0.0}, {-0.70711,0.0}}; struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_imag[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap}; From 7d27d45d02b34a6979dead469db62e146fe4cda3 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 2 Dec 2015 15:57:25 +0100 Subject: [PATCH 015/571] few more fixes --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 38 ++++--- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 10 +- openair1/PHY/LTE_TRANSPORT/proto.h | 5 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 102 ++++++------------ 4 files changed, 62 insertions(+), 93 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 12958f07bd..a27c0f1d1a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -203,7 +203,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, frame_parms, dlsch0_harq->mimo_mode); //#ifdef DEBUG_DLSCH_MOD - printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc,*lte_ue_pdsch_vars[eNB_id]->pmi_ext); + printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); + for (rb=0;rbpmi_ext[rb]); + printf("\n"); //#endif if (rx_type==rx_IC_single_stream) { @@ -1381,17 +1384,19 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_adds_epi16(tmp0,tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); } - else { + else { //[1 j; 1 -j] tmp0 = ch0[0]; - tmp1 = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); - tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); - tmp1 = _mm_shufflehi_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); - ch0[0] = _mm_subs_epi16(tmp0,tmp1); + tmp1 = ch1[0]; + ch0[0] = _mm_adds_epi16(tmp0,tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); - } + + //print_shorts("prec2A_TM4 ch0 (middle):",ch0); + //print_shorts("prec2A_TM4 ch1 (middle):",ch1); - //print_shorts("prec2A_TM4 ch0 (middle):",ch0); - //print_shorts("prec2A_TM4 ch1 (middle):",ch1); + ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate2[0]); + ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + } //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); //ch0[0] = _mm_slli_epi16(ch0[0],1); @@ -1902,7 +1907,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } } - else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); @@ -4137,14 +4142,16 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } - + + /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; else *pmi_loc=(pmi>>prb)&1; - + */ + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; - + if (pilots == 0) { @@ -4279,14 +4286,17 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, #ifdef DEBUG_DLSCH_DEMOD printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); #endif + /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; else *pmi_loc=(pmi>>prb)&1; - // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); + */ + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; + if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC if (pilots==0) { if (skip_half==1) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 0c40569f3b..439da50f90 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1247,12 +1247,12 @@ int allocate_REs_in_RB_MCH(mod_sym_t **txdataF, return(0); } -uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) +uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb) { - - + /* MIMO_mode_t mode = dlsch_harq->mimo_mode; uint32_t pmi_alloc = dlsch_harq->pmi_alloc; + */ switch (N_RB_DL) { case 6: // 1 PRB per subband @@ -1268,7 +1268,7 @@ uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb) if (mode <= PUSCH_PRECODING1) return((pmi_alloc>>((rb>>2)<<1))&3); else { - printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); + //printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); return((pmi_alloc>>(rb>>2))&1); } break; @@ -1572,7 +1572,7 @@ int dlsch_modulation(mod_sym_t **txdataF, (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid], pilots, ((pilots) ? amp_rho_b : amp_rho_a), - get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid],rb), + get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), qam_table_s0, qam_table_s1, &re_allocated, diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 87f494e826..5a51de8588 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1607,11 +1607,12 @@ uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_ /** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function @param N_RB_DL number of resource blocks - @param dlsch_harq pointer to dlsch structure (containing mimo_mode and pmi_alloc) + @param mimo_mode + @param pmi_alloc subband PMI bitmap @param rb resource block for which to extract PMI @returns subband PMI */ -uint8_t get_pmi(uint8_t N_RB_DL,LTE_DL_eNB_HARQ_t *dlsch_harq,uint16_t rb); +uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb); uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index efbc7ba99e..38c388c7cc 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -736,7 +736,7 @@ int main(int argc, char **argv) if (transmission_mode==5) { n_users = 2; //eNB_id_i = PHY_vars_UE->n_connected_eNB; - eNB_id_i=1; + eNB_id_i=1; } else @@ -3437,74 +3437,6 @@ n(tikz_fname,"w"); } stop_meas(&PHY_vars_UE->dlsch_llr_stats); } - if (test_perf ==0 ) { - if ((n_frames==1) && (Ns==(2+(2*subframe))) && (l==0)) { - - - write_output("chanF11.m","chF11",eNB2UE[0]->chF[0],12*NB_RB,1,8); - write_output("chan11.m","ch11",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); - if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx==2 && PHY_vars_eNB->lte_frame_parms.nb_antennas_tx==1 ){ - write_output("chan21.m","ch21",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); - } - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1){ - write_output("chan12.m","ch12",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); - if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx>1){ - write_output("chan21.m","ch21",eNB2UE[0]->ch[2],eNB2UE[0]->channel_length,1,8); - write_output("chan22.m","ch22",eNB2UE[0]->ch[3],eNB2UE[0]->channel_length,1,8); - } - - } - - - /*for (aarx=0;aarxlte_frame_parms.nb_antennas_rx; aarx++) { - for (aa=0;aalte_frame_parms.nb_antennas_tx; aa++) { - sprintf(fname,"ch%d%d.m",(aarx+1), (aa+1)); - write_output(fname,"ch",eNB2UE[0]->ch[2*aarx+aa],eNB2UE[0]->channel_length,1,8); - } - } */ - /*write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) - write_output("ch1.m","ch1",eNB2UE[0]->ch[PHY_vars_eNB->lte_frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);*/ - - //common vars - write_output("rxsig0.m","rxs0", &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); - write_output("rxsigF0.m","rxsF0", &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { - write_output("rxsig1.m","rxs1", PHY_vars_UE->lte_ue_common_vars.rxdata[1],PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); - write_output("rxsigF1.m","rxsF1", PHY_vars_UE->lte_ue_common_vars.rxdataF[1],PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - } - - write_output("dlsch00_r0.m","dl00_r0", - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][0][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) - write_output("dlsch01_r0.m","dl01_r0", - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][1][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) - write_output("dlsch10_r0.m","dl10_r0", - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][2][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - if ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) && (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)) - write_output("dlsch11_r0.m","dl11_r0", - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][3][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); - - //pdsch_vars - dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round,PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid ); - //dump_dlsch2(PHY_vars_UE,eNB_id_i,coded_bits_per_codeword); - // write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); - - - //pdcch_vars - write_output("pdcchF0_ext.m","pdcchF_ext", PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->llr,2400,1,4); - - } - } } } } @@ -3751,6 +3683,8 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->phy_proc_rx); if (n_frames==1) { + + //rxsig sprintf(fname,"rxsig0_r%d.m",round); sprintf(vname,"rxs0_r%d",round); write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); @@ -3765,6 +3699,22 @@ n(tikz_fname,"w"); sprintf(vname,"rxs1F_r%d",round); write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdataF[1],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); } + + //channel + write_output("chanF11.m","chF11",eNB2UE[0]->chF[0],12*NB_RB,1,8); + write_output("chan11.m","ch11",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx==2 && PHY_vars_eNB->lte_frame_parms.nb_antennas_tx==1 ){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + } + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1){ + write_output("chan12.m","ch12",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx>1){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[2],eNB2UE[0]->channel_length,1,8); + write_output("chan22.m","ch22",eNB2UE[0]->ch[3],eNB2UE[0]->channel_length,1,8); + } + } + + //channel estimates sprintf(fname,"dlsch00_r%d.m",round); sprintf(vname,"dl00_r%d",round); write_output(fname,vname, @@ -3775,21 +3725,21 @@ n(tikz_fname,"w"); sprintf(vname,"dl01_r%d",round); write_output(fname,vname, &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][1][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); } if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) { sprintf(fname,"dlsch10_r%d.m",round); sprintf(vname,"dl10_r%d",round); write_output(fname,vname, &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][2][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); } if ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) && (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)) { sprintf(fname,"dlsch11_r%d.m",round); sprintf(vname,"dl11_r%d",round); write_output(fname,vname, &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][3][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb/2,1,1); + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); } //pdsch_vars dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round,PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid); @@ -3799,6 +3749,14 @@ n(tikz_fname,"w"); write_output("dlsch_eNB_w.m","w",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); write_output("dlsch_UE_w.m","w",PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); */ + + //pdcch_vars + write_output("pdcchF0_ext.m","pdcchF_ext", PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->llr,2400,1,4); + if (round == 3) exit(-1); } From 55c1f58192068101d21741bd6479e985808bd299 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 4 Dec 2015 11:54:42 +0100 Subject: [PATCH 016/571] Fixing prec2A_TM4_128 in dlsch_demodulation.c --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 42 +++++++------------ openair1/SIMULATION/LTE_PHY/dlsim.c | 8 ++-- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index a27c0f1d1a..945dc4d1d3 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -203,10 +203,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, frame_parms, dlsch0_harq->mimo_mode); //#ifdef DEBUG_DLSCH_MOD - printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); - for (rb=0;rbpmi_ext[rb]); - printf("\n"); + printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc,*lte_ue_pdsch_vars[eNB_id]->pmi_ext); //#endif if (rx_type==rx_IC_single_stream) { @@ -1384,20 +1381,18 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_adds_epi16(tmp0,tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); } - else { //[1 j; 1 -j] + else { tmp0 = ch0[0]; - tmp1 = ch1[0]; - ch0[0] = _mm_adds_epi16(tmp0,tmp1); - ch1[0] = _mm_subs_epi16(tmp0,tmp1); - - //print_shorts("prec2A_TM4 ch0 (middle):",ch0); - //print_shorts("prec2A_TM4 ch1 (middle):",ch1); - - ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate2[0]); - ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + tmp1 = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); + tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); + tmp1 = _mm_shufflehi_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); + ch0[0] = _mm_subs_epi16(tmp0,tmp1); + ch1[0] = _mm_adds_epi16(tmp0,tmp1); } + //print_shorts("prec2A_TM4 ch0 (middle):",ch0); + //print_shorts("prec2A_TM4 ch1 (middle):",ch1); + //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); //ch0[0] = _mm_slli_epi16(ch0[0],1); //ch1[0] = _mm_mulhi_epi16(ch1[0],amp); @@ -1907,7 +1902,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } } - else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); @@ -4142,16 +4137,14 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } - - /* + if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; else *pmi_loc=(pmi>>prb)&1; - */ - *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); + pmi_loc++; - + if (pilots == 0) { @@ -4286,17 +4279,14 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, #ifdef DEBUG_DLSCH_DEMOD printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); #endif - /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; else *pmi_loc=(pmi>>prb)&1; - */ + // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); - *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; - if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC if (pilots==0) { if (skip_half==1) { @@ -4573,4 +4563,4 @@ void print_ints(char *s,__m128i *x) tempb[0],tempb[1],tempb[2],tempb[3]); }*/ -#endif +#endif \ No newline at end of file diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 38c388c7cc..9a2a4d6723 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1234,7 +1234,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; case 50: dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; @@ -1662,7 +1662,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 1; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_TDD_t; @@ -1697,7 +1697,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 1; break; case 100: @@ -1713,7 +1713,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 1; dci_length = sizeof_DCI2_20MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); break; From 6df0e462459e27acf39724a234b9fa699331a173 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 4 Dec 2015 18:28:12 +0100 Subject: [PATCH 017/571] Fixed bug in lte_ue_measurements.c for subband pmi calculation --- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 1 + openair1/PHY/LTE_TRANSPORT/dci_tools.c | 12 ++++---- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 18 ++++++++---- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 4 ++- openair1/SIMULATION/LTE_PHY/dlsim.c | 28 +++++++++---------- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index d131d524db..fc80cd38f5 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -614,6 +614,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, // For each RE in subband perform ch0 * conj(ch1) // multiply by conjugated channel #if defined(__x86_64__) || defined(__i386__) + mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]); mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1));//_MM_SHUFFLE(2,3,0,1) mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1)); mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate[0]); diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index cfb250b7ca..f7ccc16612 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5786,7 +5786,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) int i, aarx; uint16_t pmiq=0; - uint32_t pmivect = 0; // work with tyoe + uint32_t pmivect = 0; uint8_t rank = meas->rank[eNB_id]; int pmi_re,pmi_im; int nb_subbands=0; @@ -5841,21 +5841,23 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; } - if (pmi_re > pmi_im) + if (pmi_re >= pmi_im) pmiq = PMI_2A_R1_11; else //if (pmi_re < pmi_im) pmiq = PMI_2A_R1_1j; - printf("subband %d, pmi_re %d, pmi_in %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); + // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); + // printf("subband %d, pmi%d \n",i,pmiq); //According to Section 7.2.4 of 36.213 pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit } else { LOG_E(PHY,"PMI feedback for rank>1 not supported!\n"); pmivect = 0; - } + } + } + //printf( "pmivect %d \n", pmivect); - printf("subband %d pmivect %d \n",i, pmivect); return(pmivect); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 945dc4d1d3..dd708804fc 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -203,7 +203,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, frame_parms, dlsch0_harq->mimo_mode); //#ifdef DEBUG_DLSCH_MOD - printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc,*lte_ue_pdsch_vars[eNB_id]->pmi_ext); + /* printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); + for (rb=0;rbpmi_ext[rb]); + printf("\n");*/ //#endif if (rx_type==rx_IC_single_stream) { @@ -4137,12 +4140,14 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } - + + /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; else - *pmi_loc=(pmi>>prb)&1; - + *pmi_loc=(pmi>>prb)&1;*/ + + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; @@ -4279,12 +4284,13 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, #ifdef DEBUG_DLSCH_DEMOD printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); #endif - if (mimo_mode <= PUSCH_PRECODING1) + /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; else *pmi_loc=(pmi>>prb)&1; // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); - +*/ + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 439da50f90..135552f279 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -242,6 +242,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, first_re=6; for (re=first_re; re>((rb>>2)<<1))&3); else { - //printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); + // printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); return((pmi_alloc>>(rb>>2))&1); } break; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 9a2a4d6723..0d67003db3 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1651,18 +1651,18 @@ n(tikz_fname,"w"); case 6: dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_TDD_t; @@ -1697,7 +1697,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 100: @@ -1713,7 +1713,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; dci_length = sizeof_DCI2_20MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); break; From 790ba35688d2d6079f2c6cda98147e763e1e18e3 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 4 Dec 2015 19:04:59 +0100 Subject: [PATCH 018/571] one more bug in measurements --- openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index fc80cd38f5..9f7ae5fcbc 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -596,8 +596,10 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, // pmi #if defined(__x86_64__) || defined(__i386__) - pmi128_re = _mm_setzero_si128(); - pmi128_im = _mm_setzero_si128(); + + + pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); + pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); #elif defined(__arm__) pmi128_re = vdupq_n_s32(0); pmi128_im = vdupq_n_s32(0); @@ -610,6 +612,9 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, limit = last_subband_size>>2; for (i=0; i Date: Tue, 8 Dec 2015 16:18:44 +0100 Subject: [PATCH 019/571] Changes: 1. Fixing precoder selection criteria for TM4 for tpmi2. TPMI 2 works now. 2. Temporarily replacing abstraction.c with an old version till fix the bug in init_freq_channel. 3. Commenting some extra printouts. --- cmake_targets/lte-simulators/CMakeLists.txt | 2 +- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 32 +-- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 8 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 10 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- openair1/PHY/LTE_TRANSPORT/pcfich.c | 4 +- openair1/PHY/LTE_TRANSPORT/phich.c | 8 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 44 ++--- openair1/SIMULATION/TOOLS/abstraction.c | 187 +++++++++++++++++- openair1/SIMULATION/TOOLS/random_channel.c | 2 +- 10 files changed, 247 insertions(+), 52 deletions(-) diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index 0b706c8748..5ed4d93d80 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -8,7 +8,7 @@ set(DEBUG_PHY False) set(MU_RECIEVER False) set(RANDOM_BF False) set(PBS_SIM False) -set(PERFECT_CE False) +set(PERFECT_CE True) set(NAS_UE False) set(MESSAGE_CHART_GENERATOR False) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 9f7ae5fcbc..b43fc8b9ef 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -422,7 +422,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms; int nb_subbands,subband_size,last_subband_size; int N_RB_DL = frame_parms->N_RB_DL; - phy_vars_ue->PHY_measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; + phy_vars_ue->PHY_measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; if (phy_vars_ue->transmission_mode[eNB_id]!=4) phy_vars_ue->PHY_measurements.rank[eNB_id] = 0; @@ -597,10 +597,10 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, // pmi #if defined(__x86_64__) || defined(__i386__) - - pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); - pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); + pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); + pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); #elif defined(__arm__) + pmi128_re = vdupq_n_s32(0); pmi128_im = vdupq_n_s32(0); #endif @@ -613,22 +613,32 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, for (i=0; isubband_pmi_re[eNB_id][i][aarx]; pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; } - if (pmi_re >= pmi_im) + if (((pmi_re > pmi_im) && (pmi_re > -pmi_im)) || ((pmi_re < pmi_im) && (pmi_re < -pmi_im))) pmiq = PMI_2A_R1_11; - else //if (pmi_re < pmi_im) + else pmiq = PMI_2A_R1_1j; + // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); // printf("subband %d, pmi%d \n",i,pmiq); //According to Section 7.2.4 of 36.213 + pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit } else { @@ -5856,7 +5858,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) } } - //printf( "pmivect %d \n", pmivect); + // printf( "pmivect %d \n", pmivect); return(pmivect); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index dd708804fc..6f1a05ed4f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -428,11 +428,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch0_harq->mimo_mode); - if (rx_type>rx_standard) { + /*if (rx_type>rx_standard) { // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]); lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } - else + else */ lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; } @@ -1371,6 +1371,7 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { + // printf ("demod pmi=%d\n", pmi); // __m128i amp; // amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); __m128i tmp0,tmp1; @@ -1384,7 +1385,7 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_adds_epi16(tmp0,tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); } - else { + else { //ch0+j*ch1 ch0-j*ch1 tmp0 = ch0[0]; tmp1 = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); @@ -1620,9 +1621,6 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, // phy_measurements->precoded_cqi_dB[eNB_id][0]); - _mm_empty(); - _m_empty(); - #elif defined(__arm__) uint32_t rb,Nre; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 135552f279..48bbc51c3e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1270,7 +1270,7 @@ uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb if (mode <= PUSCH_PRECODING1) return((pmi_alloc>>((rb>>2)<<1))&3); else { - // printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); + // printf("Getting pmi for RB %d => %d\n",rb,((pmi_alloc>>(rb>>2))&1)); return((pmi_alloc>>(rb>>2))&1); } break; diff --git a/openair1/PHY/LTE_TRANSPORT/pcfich.c b/openair1/PHY/LTE_TRANSPORT/pcfich.c index f289fd3bd0..5f55a5c4c6 100644 --- a/openair1/PHY/LTE_TRANSPORT/pcfich.c +++ b/openair1/PHY/LTE_TRANSPORT/pcfich.c @@ -78,9 +78,9 @@ void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) first_reg = pcfich_reg[3]; } - //#ifdef DEBUG_PCFICH + #ifdef DEBUG_PCFICH printf("pcfich_reg : %d,%d,%d,%d\n",pcfich_reg[0],pcfich_reg[1],pcfich_reg[2],pcfich_reg[3]); - //#endif + #endif } void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index e08ad239bd..a7c375b6ae 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -300,7 +300,7 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) Ngroup_PHICH<<=1; } - //#ifdef DEBUG_PHICH + #ifdef DEBUG_PHICH printf("Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n", ((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)), frame_parms->phich_config_common.phich_resource, @@ -310,7 +310,7 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) n0, n1, ((frame_parms->Nid_cell))%n0); - //#endif + #endif // This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ... @@ -364,9 +364,9 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) frame_parms->phich_reg[mprime][2]++; - //#ifdef DEBUG_PHICH + #ifdef DEBUG_PHICH printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); - //#endif + #endif } else { // extended PHICH duration frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0; frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 0d67003db3..eee78da23d 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -776,8 +776,6 @@ int main(int argc, char **argv) nsymb = (PHY_vars_eNB->lte_frame_parms.Ncp == 0) ? 14 : 12; - - printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d, Rayleigh1_orthogonal=%d, Rayleigh1_orth_eff_ch_TM4_prec_real22=%d, Rayleigh1_orth_eff_ch_TM4_prec_imag=%d, Rayleigh8_orth_eff_ch_TM4_prec_real=%d, Rayleigh8_orth_eff_ch_TM4_prec_imag=%d , TS_SHIFT=%d\n", SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); @@ -788,17 +786,17 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); else sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); - else + else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); - else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + else + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); bler_fd = fopen(bler_fname,"w"); fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; dci_err\n"); - - if (test_perf != 0) { + if (test_perf != 0) { char hostname[1024]; + hostname[1023] = '\0'; gethostname(hostname, 1023); printf("Hostname: %s\n", hostname); @@ -1792,6 +1790,7 @@ n(tikz_fname,"w"); } + printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); if (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) { // not a nice way to do it, fix later PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); @@ -1850,7 +1849,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; case 50: dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; @@ -2748,7 +2747,7 @@ n(tikz_fname,"w"); #endif rate = (double)tbs/(double)coded_bits_per_codeword; - if ((SNR==snr0) && (trials==0) && (round==0)) + if ((SNR==snr0) && (trials==0) && (round==0) && (pmi_feedback==0)) printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), coded_bits_per_codeword, @@ -2930,19 +2929,18 @@ n(tikz_fname,"w"); else { if (transmission_mode==4) { r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - // printf("r_re0 = %d\n",r_re[0][i]); - //printf("r_im0 = %d\n",r_im[0][i]); - //printf("r_re1 = %d\n",r_re[1][i]); - //printf("r_im1 = %d\n",r_im[1][i]); - // r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - // r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - - // r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - // r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + //printf("r_re0 = %d\n",r_re[0][i]); + //printf("r_im0 = %d\n",r_im[0][i]); + //printf("r_re1 = %d\n",r_re[1][i]); + //printf("r_im1 = %d\n",r_im[1][i]); + //r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + //r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + //r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + //r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); } else { @@ -3152,6 +3150,7 @@ n(tikz_fname,"w"); subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti, 1, 0); + // printf ("Trial %d, Measurements are done \n", trials); /* debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n", PHY_vars_UE->PHY_measurements.rx_rssi_dBm[0] - ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx==2) ? 3 : 0), @@ -3179,6 +3178,7 @@ n(tikz_fname,"w"); if (pmi_feedback == 1) { pmi_feedback = 0; hold_channel = 1; + // printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback); goto PMI_FEEDBACK; } } diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c index d63d0b0fe9..03c3e59d4e 100644 --- a/openair1/SIMULATION/TOOLS/abstraction.c +++ b/openair1/SIMULATION/TOOLS/abstraction.c @@ -26,7 +26,7 @@ Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ -#include +/*#include #include #include #include @@ -309,3 +309,188 @@ double pbch_bler(double sinr) return(bler); } +*/ +#include +#include +#include +#include +#include + + +#include "PHY/TOOLS/defs.h" +#include "defs.h" + +void freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { + + double delta_f,freq; // 90 kHz spacing + double delay; + int16_t f; + uint8_t aarx,aatx,l; + + delta_f = nb_rb*180000/(n_samples-1); + //write_output("channel.m","a",desc->a[0],desc->nb_taps,1,8); + for (f=-n_samples/2;fnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f].x=0.0; + desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f].y=0.0; + for (l=0;l<(int)desc->nb_taps;l++) { + if (desc->nb_taps==1) + delay = desc->delays[l]; + else + delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->BW; + desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*cos(2*M_PI*freq*delay)+ + desc->a[l][aarx+(aatx*desc->nb_rx)].y*sin(2*M_PI*freq*delay)); + desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*sin(2*M_PI*freq*delay)+ + desc->a[l][aarx+(aatx*desc->nb_rx)].y*cos(2*M_PI*freq*delay)); + } + // printf("chF(%d) => (%f,%f)\n",n_samples/2+f, + // desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].x, + // desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].y); + } + } + } +} + +double compute_pbch_sinr(channel_desc_t *desc, + channel_desc_t *desc_i1, + channel_desc_t *desc_i2, + double snr_dB,double snr_i1_dB, + double snr_i2_dB, + uint16_t nb_rb) { + + double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); + uint16_t f; + uint8_t aarx,aatx; + double S; + struct complex S_i1; + struct complex S_i2; + + avg_sinr=0.0; + // printf("nb_rb %d\n",nb_rb); + for (f=(nb_rb-6);f<(nb_rb+6);f++) { + S = 0.0; + S_i1.x =0.0; + S_i1.y =0.0; + S_i2.x =0.0; + S_i2.y =0.0; + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y); + // printf("%d %d chF[%d] => (%f,%f)\n",aarx,aatx,f,desc->chF[aarx+(aatx*desc->nb_rx)][f].x,desc->chF[aarx+(aatx*desc->nb_rx)][f].y); + + if (desc_i1) { + S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + if (desc_i2) { + S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + } + } + // printf("snr %f f %d : S %f, S_i1 %f, S_i2 %f\n",snr,f-nb_rb,S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)); + avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y))); + } + // printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2); + return(10*log10(avg_sinr/12.0)); +} + + +double compute_sinr(channel_desc_t *desc, + channel_desc_t *desc_i1, + channel_desc_t *desc_i2, + double snr_dB,double snr_i1_dB, + double snr_i2_dB, + uint16_t nb_rb) { + + double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); + uint16_t f; + uint8_t aarx,aatx; + double S; + struct complex S_i1; + struct complex S_i2; + + avg_sinr=0.0; + // printf("nb_rb %d\n",nb_rb); + for (f=0;f<2*nb_rb;f++) { + S = 0.0; + S_i1.x =0.0; + S_i1.y =0.0; + S_i2.x =0.0; + S_i2.y =0.0; + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y); + if (desc_i1) { + S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + if (desc_i2) { + S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x + + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y); + S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y - + desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x); + } + } + } + // printf("f %d : S %f, S_i1 %f, S_i2 %f\n",f-nb_rb,snr*S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)); + avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y))); + } + // printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2); + return(10*log10(avg_sinr/(nb_rb*2))); +} + + uint8_t pbch_polynomial_degree; +double a[7]; + +void load_pbch_desc(FILE *pbch_file_fd) { + + int i; + char dummy[25]; + + fscanf(pbch_file_fd,"%d",&pbch_polynomial_degree); + if (pbch_polynomial_degree>6) { + printf("Illegal degree for pbch interpolation polynomial %d\n",pbch_polynomial_degree); + exit(-1); + } + + printf("PBCH polynomial : "); + + for (i=0;i<=pbch_polynomial_degree;i++) { + fscanf(pbch_file_fd,"%s",dummy); + a[i] = strtod(dummy,NULL); + printf("%f ",a[i]); + } + printf("\n"); +} + +double pbch_bler(double sinr) { + + int i; + double log10_bler=a[pbch_polynomial_degree]; + double sinrpow=sinr; + // printf("log10bler %f\n",log10_bler); + if (sinr<-7.9) + return(1.0); + else if (sinr>=0.0) + return(1e-4); + + for (i=1;i<=pbch_polynomial_degree;i++) { + // printf("sinrpow %f\n",sinrpow); + log10_bler += (a[pbch_polynomial_degree-i]*sinrpow); + sinrpow *= sinr; + // printf("log10bler %f\n",log10_bler); + } + return(pow(10.0,log10_bler)); +} diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index d4c1d45a75..528402a2f2 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -209,7 +209,7 @@ struct complex *R_sqrt_22_orthogonal[1] = {R_sqrt_22_orthogonal_tap}; struct complex R_sqrt_22_orth_eff_ch_TM4_prec_real_tap[16] = {{0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, {-0.70711,0.0}, {0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}, {0.0, 0.0}, - {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}}; + {0.0, 0.0}, {-0.70711,0.0}, {0.0, 0.0}, {0.70711,0.0}}; struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_real[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_real_tap}; From d765d1f2ab812243f7ffe94a8e8e179c46720c3c Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 9 Dec 2015 15:27:50 +0100 Subject: [PATCH 020/571] Fixing previous commit --- openair1/SIMULATION/TOOLS/abstraction.c | 2 +- openair1/SIMULATION/TOOLS/random_channel.c | 65 +++++++++++----------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c index 08a0d6c06a..5d06f7c638 100644 --- a/openair1/SIMULATION/TOOLS/abstraction.c +++ b/openair1/SIMULATION/TOOLS/abstraction.c @@ -340,7 +340,7 @@ void freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { if (desc->nb_taps==1) delay = desc->delays[l]; else - delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->BW; + delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->sampling_rate; desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*cos(2*M_PI*freq*delay)+ desc->a[l][aarx+(aatx*desc->nb_rx)].y*sin(2*M_PI*freq*delay)); desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*sin(2*M_PI*freq*delay)+ diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 6c3116001b..856367eff3 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -81,23 +81,22 @@ void fill_channel_desc(channel_desc_t *chan_desc, chan_desc->delays[i] = ((double)i)*delta_tau; } else - chan_desc->delays = delays; - - chan_desc->Td = Td; - chan_desc->sampling_rate = sampling_rate; - chan_desc->channel_bandwidth = channel_bandwidth; - chan_desc->ricean_factor = ricean_factor; - chan_desc->aoa = aoa; - chan_desc->random_aoa = random_aoa; - chan_desc->forgetting_factor = forgetting_factor; - chan_desc->channel_offset = channel_offset; - chan_desc->path_loss_dB = path_loss_dB; - chan_desc->first_run = 1; - chan_desc->ip = 0.0; - chan_desc->max_Doppler = max_Doppler; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(nb_taps*sizeof(struct complex*)); + chan_desc->delays = delays; + chan_desc->Td = Td; + chan_desc->sampling_rate = sampling_rate; + chan_desc->channel_bandwidth = channel_bandwidth; + chan_desc->ricean_factor = ricean_factor; + chan_desc->aoa = aoa; + chan_desc->random_aoa = random_aoa; + chan_desc->forgetting_factor = forgetting_factor; + chan_desc->channel_offset = channel_offset; + chan_desc->path_loss_dB = path_loss_dB; + chan_desc->first_run = 1; + chan_desc->ip = 0.0; + chan_desc->max_Doppler = max_Doppler; + chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->a = (struct complex**) malloc(nb_taps*sizeof(struct complex*)); LOG_D(OCM,"[CHANNEL] Filling ch \n"); @@ -548,7 +547,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, NULL, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -575,7 +574,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, NULL, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -602,7 +601,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, NULL, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -629,7 +628,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, NULL, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -665,7 +664,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -701,7 +700,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -728,7 +727,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, NULL, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -755,7 +754,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, NULL, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -784,7 +783,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, NULL, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -822,7 +821,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -858,7 +857,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -892,7 +891,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -926,7 +925,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -960,7 +959,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -997,7 +996,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, @@ -1032,7 +1031,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, R_sqrt_ptr2, Td, sampling_rate, - BW, + channel_bandwidth, ricean_factor, aoa, forgetting_factor, From 20a6f9785b85ccdb20d9ec8d29a5f2aff88bc16a Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 10 Dec 2015 13:12:00 +0100 Subject: [PATCH 021/571] Small changes for writing precoder in data_out file. Please note that to test precoder it is necessary to run Perfect_CE --- openair1/SIMULATION/LTE_PHY/dlsim.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 86feb4d3c6..f2c1d184e6 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -3454,11 +3454,11 @@ n(tikz_fname,"w"); //saving PMI in case of Transmission Mode > 5 if(abstx){ - if (trials==0 && round==0 && transmission_mode>=5){ + if (trials==0 && round==0 && transmission_mode>=4){ for (iii=0; iiilte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[iii])); - fprintf(csv_fd,"%x,%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); - printf("%x ",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + fprintf(csv_fd,"%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + //printf("%x ",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); } } } From 0d9f417f7b7632ffa8bf19e51848514e71594761 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 14 Dec 2015 12:32:52 +0100 Subject: [PATCH 022/571] Small changes in dlsch_demodulation.c and in dlsim.c condition to stop simulation depending on rx_type. dr_offset must be calibrated for tm4 again. --- cmake_targets/CMakeLists.txt | 2 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 23 ++++++++++++------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 519d31dedc..bb5048821b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -119,7 +119,7 @@ endmacro(add_list_string_option) #################################################### # compilation flags ############################################# -set (CMAKE_BUILD_TYPE "Debug") +#set (CMAKE_BUILD_TYPE "Debug") if (CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 6f1a05ed4f..85f05a8be4 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -428,11 +428,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch0_harq->mimo_mode); - /*if (rx_type>rx_standard) { + if (rx_type>rx_standard) { // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]); lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } - else */ + else lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f2c1d184e6..5ca6565666 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -820,9 +820,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dataout_tx%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_abstr_perf_ce.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_ab_perf_ce.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds); else - sprintf(csv_fname,"dataout_tx%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_abstr.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_ab.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds); // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); @@ -2947,10 +2947,10 @@ n(tikz_fname,"w"); //printf("r_im0 = %d\n",r_im[0][i]); //printf("r_re1 = %d\n",r_re[1][i]); //printf("r_im1 = %d\n",r_im[1][i]); - //r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - //r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - //r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - //r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + // r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + // r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + // r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + // r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); } else { @@ -4306,8 +4306,15 @@ n(tikz_fname,"w"); printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); } - if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) - break; + if (rx_type Date: Mon, 14 Dec 2015 19:01:29 +0100 Subject: [PATCH 023/571] Introducing an offset for I-UA receiver intefr_unaw_shift and calibrating this value for each mcs (u=0 only). --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3 ++- openair1/SIMULATION/LTE_PHY/dlsim.c | 24 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 85f05a8be4..024b0cd2ac 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -61,6 +61,7 @@ int avg[4]; // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; +uint8_t intefr_unaw_shift; /* //original values from sebastion + same hand tuning unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{6,6,6},{6,6,6},{6,6,6},{5,5,5},{4,4,4},{1,2,4}, // QPSK @@ -433,7 +434,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } else - lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0])/2; + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avg[0])/2)+intefr_unaw_shift; } dlsch_channel_compensation_TM34(frame_parms, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 5ca6565666..169656776c 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -59,7 +59,7 @@ extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; extern unsigned char offset_mumimo_llr_drange_fix; - +extern uint8_t intefr_unaw_shift; #ifdef XFORMS #include "PHY/TOOLS/lte_phy_scope.h" #endif @@ -384,7 +384,7 @@ int main(int argc, char **argv) num_layers = 1; perfect_ce = 0; - while ((c = getopt (argc, argv, "ahdpZDe:m:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:Y:X")) != -1) { + while ((c = getopt (argc, argv, "ahdpZDe:m:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:YXJ:")) != -1) { switch (c) { case 'a': awgn_flag = 1; @@ -631,6 +631,9 @@ int main(int argc, char **argv) case 'Y': perfect_ce=1; break; + case 'J': + intefr_unaw_shift=atoi(optarg); + break; case 'h': default: printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); @@ -745,6 +748,7 @@ int main(int argc, char **argv) printf("n_frames = %d\n",n_frames); printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag); printf("Using receiver type %d\n", rx_type); + printf("Using I_UA rec shift %d\n", intefr_unaw_shift); snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); @@ -777,14 +781,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, intefr_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_abstr.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, intefr_unaw_shift); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, intefr_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2,intefr_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -820,9 +824,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_ab_perf_ce.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, intefr_unaw_shift); else - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_nsimus%d_R%d_ab.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, intefr_unaw_shift); // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); @@ -4307,11 +4311,11 @@ n(tikz_fname,"w"); } if (rx_type Date: Mon, 14 Dec 2015 19:07:23 +0100 Subject: [PATCH 024/571] Changing the level of target BLER on dlsim.c --- openair1/SIMULATION/LTE_PHY/dlsim.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 169656776c..3545e92b9a 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -4310,13 +4310,13 @@ n(tikz_fname,"w"); printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); } - if (rx_type Date: Tue, 15 Dec 2015 15:57:45 +0100 Subject: [PATCH 025/571] Introducing different shifts for channel compensation log2_maxh0 and log2_maxh1 as well as mcs-dependent offset coefficients interf_unaw_shift_mcs for I-UA receiver and interference-free case TM4. Coeeficients for 64 QAM must be revised. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 59 +++++++++++-------- openair1/PHY/LTE_TRANSPORT/proto.h | 3 +- openair1/PHY/impl_defs_lte.h | 4 ++ openair1/SIMULATION/LTE_PHY/dlsim.c | 30 ++++++---- 4 files changed, 58 insertions(+), 38 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 024b0cd2ac..9a61b7f48e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -61,7 +61,12 @@ int avg[4]; // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; -uint8_t intefr_unaw_shift; +uint8_t intefr_unaw_shift0; +uint8_t intefr_unaw_shift1; +//inferference-free case +unsigned char interf_unaw_shift_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; + /* //original values from sebastion + same hand tuning unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{6,6,6},{6,6,6},{6,6,6},{5,5,5},{4,4,4},{1,2,4}, // QPSK @@ -434,7 +439,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; } else - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avg[0])/2)+intefr_unaw_shift; + // to avoid tails in SNR/BLER curves + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2)+interf_unaw_shift_mcs[dlsch0_harq->mcs]; + //printf("I-UA shift layer1 = %d\n",interf_unaw_shift_mcs[dlsch0_harq->mcs]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2)+interf_unaw_shift_mcs[dlsch1_harq->mcs]; + //printf("I-UA shift layer2 = %d\n",interf_unaw_shift_mcs[dlsch1_harq->mcs] ); } dlsch_channel_compensation_TM34(frame_parms, @@ -448,7 +457,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch0_harq->round, dlsch0_harq->mimo_mode, nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0, + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); /* if (symbol == 5) { @@ -467,7 +477,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->log2_maxh); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //to be optimized (just take complex conjugate) @@ -477,7 +487,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->log2_maxh); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); } @@ -1814,7 +1824,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int round, MIMO_mode_t mimo_mode, unsigned short nb_rb, - unsigned char output_shift) { + unsigned char output_shift0, + unsigned char output_shift1) { #if defined(__x86_64__) || defined(__i386__) @@ -1924,10 +1935,10 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // get channel amplitude if not QPSK mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); @@ -1946,7 +1957,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); @@ -1975,10 +1986,10 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // get channel amplitude if not QPSK mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); @@ -1996,7 +2007,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); @@ -2033,10 +2044,10 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // print_ints("im",&mmtmpD1); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); // printf("Shift: %d\n",output_shift); // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2056,8 +2067,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2075,8 +2086,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2100,9 +2111,9 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2121,8 +2132,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2140,8 +2151,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 7d0fc356fa..25d77b25f7 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -979,7 +979,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int round, MIMO_mode_t mimo_mode, unsigned short nb_rb, - unsigned char output_shift); + unsigned char output_shift0, + unsigned char output_shift1); /** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index c1e9229c32..a4d3b0ea6c 100644 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -841,6 +841,10 @@ typedef struct { int16_t *llr[2]; /// \f$\log_2(\max|H_i|^2)\f$ int16_t log2_maxh; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation + int16_t log2_maxh0; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation + int16_t log2_maxh1; /// \brief LLR shifts for subband scaling. /// - first index: ? [0..168*N_RB_DL[ uint8_t *llr_shifts; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3545e92b9a..d69b64d82c 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -59,7 +59,8 @@ extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; extern unsigned char offset_mumimo_llr_drange_fix; -extern uint8_t intefr_unaw_shift; +extern uint8_t interf_unaw_shift0=0; +extern uint8_t interf_unaw_shift1=0; #ifdef XFORMS #include "PHY/TOOLS/lte_phy_scope.h" #endif @@ -384,7 +385,7 @@ int main(int argc, char **argv) num_layers = 1; perfect_ce = 0; - while ((c = getopt (argc, argv, "ahdpZDe:m:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:YXJ:")) != -1) { + while ((c = getopt (argc, argv, "ahdpZDe:m:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:YXV:W:")) != -1) { switch (c) { case 'a': awgn_flag = 1; @@ -631,9 +632,12 @@ int main(int argc, char **argv) case 'Y': perfect_ce=1; break; - case 'J': - intefr_unaw_shift=atoi(optarg); - break; + case 'V': + interf_unaw_shift0=atoi(optarg); + break; + case 'W': + interf_unaw_shift1=atoi(optarg); + break; case 'h': default: printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); @@ -748,8 +752,8 @@ int main(int argc, char **argv) printf("n_frames = %d\n",n_frames); printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag); printf("Using receiver type %d\n", rx_type); - printf("Using I_UA rec shift %d\n", intefr_unaw_shift); - + printf("Using I_UA rec shift layer 1 %d\n", interf_unaw_shift0); + printf("Using I_UA rec shift layer 2 %d\n", interf_unaw_shift1); snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); @@ -781,14 +785,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, intefr_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift0 ); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, intefr_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift0); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, intefr_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift0); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2,intefr_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2,interf_unaw_shift0); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -824,9 +828,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, intefr_unaw_shift); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0); else - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, intefr_unaw_shift); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0); // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); From 51af1a19f0adf22c7824ad184275cb20c6a165f3 Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 15 Dec 2015 16:09:53 +0100 Subject: [PATCH 026/571] Now BLER goes to 10^(-2) in case of abstraction and 10^-3 in regular mode. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index d69b64d82c..d3ce51ed73 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -4313,16 +4313,31 @@ n(tikz_fname,"w"); } else if (test_perf !=0 ){ printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); } - - if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { - if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) - break; + if (abstx == 1) { + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { + if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) + break; + } + else{ + if (((double)errs[0][0]/(round_trials[0]))<1e-2) + break; + + } } - else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-2) - break; + else { + + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { + if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) + break; + } + else{ + if (((double)errs[0][0]/(round_trials[0]))<1e-3) + break; + + } } + if (n_frames==1) break; From c2460ee36ad5f82ebae52ed87b175d61a2607d58 Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 15 Dec 2015 23:14:08 +0100 Subject: [PATCH 027/571] Verifying if offset LUT for TM4 works for TM1. -J is responsible for shift. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3 ++- openair1/SIMULATION/LTE_PHY/dlsim.c | 18 +++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 9a61b7f48e..dd15f51e9e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -63,6 +63,7 @@ int avg[4]; unsigned char offset_mumimo_llr_drange_fix=0; uint8_t intefr_unaw_shift0; uint8_t intefr_unaw_shift1; +uint8_t intefr_unaw_shift; //inferference-free case unsigned char interf_unaw_shift_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; @@ -319,7 +320,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avgs = cmax(avgs,avg[(aatx<<1)+aarx]); // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2); + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + intefr_unaw_shift; // + log2_approx(frame_parms->nb_antennas_tx_eNB-1) //-1 because log2_approx counts the number of bits // + log2_approx(frame_parms->nb_antennas_rx-1); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index d3ce51ed73..2ca5d83307 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -61,6 +61,7 @@ extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; extern unsigned char offset_mumimo_llr_drange_fix; extern uint8_t interf_unaw_shift0=0; extern uint8_t interf_unaw_shift1=0; +extern uint8_t interf_unaw_shift=0; #ifdef XFORMS #include "PHY/TOOLS/lte_phy_scope.h" #endif @@ -385,7 +386,7 @@ int main(int argc, char **argv) num_layers = 1; perfect_ce = 0; - while ((c = getopt (argc, argv, "ahdpZDe:m:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:YXV:W:")) != -1) { + while ((c = getopt (argc, argv, "ahdpZDe:m:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:YXV:W:J:")) != -1) { switch (c) { case 'a': awgn_flag = 1; @@ -638,6 +639,9 @@ int main(int argc, char **argv) case 'W': interf_unaw_shift1=atoi(optarg); break; + case 'J': + interf_unaw_shift=atoi(optarg); + break; case 'h': default: printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); @@ -785,14 +789,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift0 ); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift0); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift0); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2,interf_unaw_shift0); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2,interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -828,9 +832,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift); else - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift); // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); From d6503bdd473580132353d922fd4ebf3962585ffe Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 15 Dec 2015 23:21:13 +0100 Subject: [PATCH 028/571] typo --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index dd15f51e9e..9f236f9e82 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -61,9 +61,9 @@ int avg[4]; // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; -uint8_t intefr_unaw_shift0; -uint8_t intefr_unaw_shift1; -uint8_t intefr_unaw_shift; +uint8_t interf_unaw_shift0; +uint8_t interf_unaw_shift1; +uint8_t interf_unaw_shift; //inferference-free case unsigned char interf_unaw_shift_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; @@ -320,7 +320,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avgs = cmax(avgs,avg[(aatx<<1)+aarx]); // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + intefr_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift; // + log2_approx(frame_parms->nb_antennas_tx_eNB-1) //-1 because log2_approx counts the number of bits // + log2_approx(frame_parms->nb_antennas_rx-1); From 1673ba3dfbd31661ed30b40c5f56f40bdb1c913b Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 16 Dec 2015 12:51:43 +0100 Subject: [PATCH 029/571] Fix global var for shift --- openair1/SIMULATION/LTE_PHY/dlsim.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 2ca5d83307..0e8fbb42a3 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -59,9 +59,9 @@ extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; extern unsigned char offset_mumimo_llr_drange_fix; -extern uint8_t interf_unaw_shift0=0; -extern uint8_t interf_unaw_shift1=0; -extern uint8_t interf_unaw_shift=0; +extern uint8_t interf_unaw_shift0; +extern uint8_t interf_unaw_shift1; +extern uint8_t interf_unaw_shift; #ifdef XFORMS #include "PHY/TOOLS/lte_phy_scope.h" #endif @@ -756,8 +756,9 @@ int main(int argc, char **argv) printf("n_frames = %d\n",n_frames); printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag); printf("Using receiver type %d\n", rx_type); - printf("Using I_UA rec shift layer 1 %d\n", interf_unaw_shift0); - printf("Using I_UA rec shift layer 2 %d\n", interf_unaw_shift1); + printf("TM1 shift %d\n", interf_unaw_shift); + //printf("Using I_UA rec shift layer 1 %d\n", interf_unaw_shift0); + //printf("Using I_UA rec shift layer 2 %d\n", interf_unaw_shift1); snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); From 877d7b3bf9c16231fef48fde7fc7ac1fdb0d11d6 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 16 Dec 2015 13:43:50 +0100 Subject: [PATCH 030/571] Fixing global shifts --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 9f236f9e82..3cc15c6fc8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -61,9 +61,9 @@ int avg[4]; // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; -uint8_t interf_unaw_shift0; -uint8_t interf_unaw_shift1; -uint8_t interf_unaw_shift; +uint8_t interf_unaw_shift0=0; +uint8_t interf_unaw_shift1=0; +uint8_t interf_unaw_shift=0; //inferference-free case unsigned char interf_unaw_shift_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; From 513ed46e562e6514ced39f68783eb7fb65ce1640 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 16 Dec 2015 15:46:56 +0100 Subject: [PATCH 031/571] Calibrating offset for TM1 and introducing LUT interf_unaw_shift_tm1_mcs. LUT valid for mcs<=13, to be completed in the next commit. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 3cc15c6fc8..c72b1e5f77 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -65,8 +65,10 @@ uint8_t interf_unaw_shift0=0; uint8_t interf_unaw_shift1=0; uint8_t interf_unaw_shift=0; //inferference-free case -unsigned char interf_unaw_shift_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; +unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; +unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 0, 0, + 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; // this is valid only till mcs13 /* //original values from sebastion + same hand tuning @@ -320,7 +322,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avgs = cmax(avgs,avg[(aatx<<1)+aarx]); // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + // printf(" TM1 shift = %d\n",interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]); // + log2_approx(frame_parms->nb_antennas_tx_eNB-1) //-1 because log2_approx counts the number of bits // + log2_approx(frame_parms->nb_antennas_rx-1); @@ -441,10 +444,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else // to avoid tails in SNR/BLER curves - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2)+interf_unaw_shift_mcs[dlsch0_harq->mcs]; - //printf("I-UA shift layer1 = %d\n",interf_unaw_shift_mcs[dlsch0_harq->mcs]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2)+interf_unaw_shift_mcs[dlsch1_harq->mcs]; - //printf("I-UA shift layer2 = %d\n",interf_unaw_shift_mcs[dlsch1_harq->mcs] ); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2)+interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; + //printf("TM4 I-UA shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2)+interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; + //printf("TM4 I-UA shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs] ); } dlsch_channel_compensation_TM34(frame_parms, From e44851306d47fb3e667de43a95cb7bb159c1b49e Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 17 Dec 2015 15:33:27 +0100 Subject: [PATCH 032/571] 1.Fixing a bug with qam tables in dlsch_demodulation.c for tm4. 2.Fixing shift LUT for TM1. Mcs 21, 26 and 28 show erroneous performance. (see attachement in commit) --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 16 ++++++++-------- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index c72b1e5f77..ff78339286 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -67,8 +67,8 @@ uint8_t interf_unaw_shift=0; //inferference-free case unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; -unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 0, 0, - 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; // this is valid only till mcs13 +unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1, + 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous /* //original values from sebastion + same hand tuning diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 48bbc51c3e..dd6d26668b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -832,8 +832,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj=*jj+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));//>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));//>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; @@ -870,8 +870,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam64_table_offset_im+=1; *jj=*jj+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));//>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));//>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; @@ -925,8 +925,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj2=*jj2+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re]));//>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im]));//>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; @@ -963,8 +963,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam64_table_offset_im+=1; *jj2=*jj2+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re]));//>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im]));//>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 0e8fbb42a3..73d2e824c5 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_lut.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_ab_lut.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_perf_ce_lut.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_sh%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2,interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi_lut%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1, mcs2); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds); else - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds); // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); From b21b87df28548987fad4041c19a54d5bf62674e8 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 18 Dec 2015 17:08:21 +0100 Subject: [PATCH 033/571] Fixing perfect channel estimation for TM4 --- openair1/SIMULATION/LTE_PHY/dlsim.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 73d2e824c5..06ba7cc1f3 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2986,7 +2986,12 @@ n(tikz_fname,"w"); if (awgn_flag == 0) { multipath_channel(eNB2UE[0],s_re,s_im,r_re,r_im, 2*frame_parms->samples_per_tti,hold_channel); - // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); + if (PHY_vars_UE->perfect_ce==1){ + freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); + // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); + } + // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); if(abstx==1 && num_rounds>1) if(round==0 && hold_channel==0){ random_channel(eNB2UE[1],0); @@ -3138,11 +3143,7 @@ n(tikz_fname,"w"); if (PHY_vars_UE->perfect_ce==1) { if (awgn_flag==0) { - // fill in perfect channel estimates - freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); - - //write_output("channel.m","ch",desc1->ch[0],desc1->channel_length,1,8); - //write_output("channelF.m","chF",desc1->chF[0],nb_samples,1,8); + //fill the channel estimates for(k=0; knb_antennas_tx; aa++) { for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -3159,9 +3160,24 @@ n(tikz_fname,"w"); for(aa=0; aanb_antennas_tx; aa++) { for (aarx=0; aarxnb_antennas_rx; aarx++) { for (i=0; iN_RB_DL*12; i++) { + + if (transmission_mode==4) { + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + + } + else{ ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; } + + } } } } From 9c41f88a5659a5dbc9b7fe524a5d8ab45228cb2e Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 21 Dec 2015 12:05:40 +0100 Subject: [PATCH 034/571] Improving previuos commit: awgn TM4 for perfect CE. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 16 ++++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 55 ++++++++----------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index ff78339286..7a88835387 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -439,15 +439,21 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (rx_type>rx_standard) { - // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->mcs>>1)-1]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; + // interf_unaw_shift_tm4_mcs is to avoid tails in SNR/BLER curves + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs];//+offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs];//+offset_mumimo_llr_drange[dlsch1_harq->mcs][(get_Qm(dlsch0_harq->mcs)>>1)-1]; + //printf("TM4 I-A shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); + //printf("TM4 I-A shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs] ); + + + } else // to avoid tails in SNR/BLER curves - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2)+interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; //printf("TM4 I-UA shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2)+interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; - //printf("TM4 I-UA shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs] ); + //printf("TM4 I-UA shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]); } dlsch_channel_compensation_TM34(frame_parms, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 06ba7cc1f3..fd0204b7ae 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -700,7 +700,7 @@ int main(int argc, char **argv) } else NB_RB = 4; - NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); ///?? + NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); if ((transmission_mode > 1) && (n_tx != 2)) { @@ -2960,11 +2960,7 @@ n(tikz_fname,"w"); //printf("r_im0 = %d\n",r_im[0][i]); //printf("r_re1 = %d\n",r_re[1][i]); //printf("r_im1 = %d\n",r_im[1][i]); - // r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - // r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - // r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - // r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - + } else { for (aarx=0;aarxlte_frame_parms.nb_antennas_rx;aarx++) { @@ -3157,33 +3153,30 @@ n(tikz_fname,"w"); } } } else { - for(aa=0; aanb_antennas_tx; aa++) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { - for (i=0; iN_RB_DL*12; i++) { - - if (transmission_mode==4) { + if (transmission_mode==4) { + for (i=0; iN_RB_DL*12; i++) { ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;//(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - - } - else{ - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; - } - + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + } + } + else{ + for(aa=0; aanb_antennas_tx; aa++) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (i=0; iN_RB_DL*12; i++) { + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; + } } - } - } - } - } - - + } + } + } + } if ((Ns==((2*subframe))) && (l==0)) { lte_ue_measurements(PHY_vars_UE, subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti, From 170291413d0df97fb693e86e78a42855572109a4 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 4 Jan 2016 14:33:01 +0100 Subject: [PATCH 035/571] Going back to fixed shift in log2_approx for TM4. Playing with computing the channel average in order to find optimal shift. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 15 ++++++++++----- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 7a88835387..e5b01f2ebd 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -420,11 +420,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // scaling interfering channel (following for TM56) - dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + /*dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, - nb_rb); + nb_rb);*/ if (first_symbol_flag==1) { @@ -440,6 +440,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (rx_type>rx_standard) { // interf_unaw_shift_tm4_mcs is to avoid tails in SNR/BLER curves + avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->Qm>>1)-1]; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs];//+offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs];//+offset_mumimo_llr_drange[dlsch1_harq->mcs][(get_Qm(dlsch0_harq->mcs)>>1)-1]; //printf("TM4 I-A shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); @@ -450,8 +451,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else // to avoid tails in SNR/BLER curves - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; + avg[0] = log2_approx(avg[0]) - 13 + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); + printf("TM4 I-UA shift = %d\n",interf_unaw_shift); + //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; + //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; //printf("TM4 I-UA shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); //printf("TM4 I-UA shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]); } @@ -3073,7 +3077,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb Date: Mon, 4 Jan 2016 14:37:26 +0100 Subject: [PATCH 036/571] Minor change in dlsch_demod --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index e5b01f2ebd..b7439260b6 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -452,7 +452,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else // to avoid tails in SNR/BLER curves avg[0] = log2_approx(avg[0]) - 13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); printf("TM4 I-UA shift = %d\n",interf_unaw_shift); //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; From eeaf2c1596815377186fa5a71808977b248df7b0 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 4 Jan 2016 14:54:13 +0100 Subject: [PATCH 037/571] Cleaning up some comments --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index b7439260b6..680b08919b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -454,7 +454,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avg[0] = log2_approx(avg[0]) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); - printf("TM4 I-UA shift = %d\n",interf_unaw_shift); + //printf("TM4 I-UA shift = %d\n",interf_unaw_shift); //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; //printf("TM4 I-UA shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a5a9901cc9..faf6037eb1 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -4341,11 +4341,11 @@ n(tikz_fname,"w"); else { if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { - if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) + if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) break; } else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-3) + if (((double)errs[0][0]/(round_trials[0]))<1e-2) break; } From 404814f706d55ed0d43269d1e0cf936ab01bb48d Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 4 Jan 2016 15:30:02 +0100 Subject: [PATCH 038/571] In demod removing -13 to play with absolute value of shift --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 680b08919b..57bb26f0a4 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -451,7 +451,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else // to avoid tails in SNR/BLER curves - avg[0] = log2_approx(avg[0]) - 13 + interf_unaw_shift; + avg[0] = log2_approx(avg[0]) + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); //printf("TM4 I-UA shift = %d\n",interf_unaw_shift); From 6e839bf82c47204e055bb0d6ff698db0e00201df Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 4 Jan 2016 15:31:49 +0100 Subject: [PATCH 039/571] Minor change in dlsim.c --- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index faf6037eb1..a5a9901cc9 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -4341,11 +4341,11 @@ n(tikz_fname,"w"); else { if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { - if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) + if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) break; } else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-2) + if (((double)errs[0][0]/(round_trials[0]))<1e-3) break; } From ef3991d46113b64fa9937699923f15d0b03d0902 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 4 Jan 2016 16:58:32 +0100 Subject: [PATCH 040/571] Minor change in dlsch_demod. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 57bb26f0a4..ff6df07b4b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -451,7 +451,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else // to avoid tails in SNR/BLER curves - avg[0] = log2_approx(avg[0]) + interf_unaw_shift; + avg[0] = log2_approx(avg[0]) - interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); //printf("TM4 I-UA shift = %d\n",interf_unaw_shift); From fa64a1285012e87e76164f3eb7965488657fc97a Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 5 Jan 2016 00:25:23 +0100 Subject: [PATCH 041/571] Applying channel scaling for TM4, playing with log2approx in demodulation --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index ff6df07b4b..963d03a35e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -420,11 +420,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // scaling interfering channel (following for TM56) - /*dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, - nb_rb);*/ + nb_rb); if (first_symbol_flag==1) { @@ -451,7 +451,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else // to avoid tails in SNR/BLER curves - avg[0] = log2_approx(avg[0]) - interf_unaw_shift; + avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); //printf("TM4 I-UA shift = %d\n",interf_unaw_shift); From 73c76d14569618fb197de206d485f12c0e527a7a Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 5 Jan 2016 11:11:35 +0100 Subject: [PATCH 042/571] Small changes in dataout file names. --- openair1/PHY/TOOLS/cdot_prod.c | 7 +++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/TOOLS/cdot_prod.c b/openair1/PHY/TOOLS/cdot_prod.c index 2e52e63f7e..195869c913 100644 --- a/openair1/PHY/TOOLS/cdot_prod.c +++ b/openair1/PHY/TOOLS/cdot_prod.c @@ -114,12 +114,11 @@ int32_t dot_product(int16_t *x, // print_shorts("mmtmp7",&mmtmp7); // convert back to integer result = _mm_cvtsi64_si32(mmtmp7); - - return(result); - + _mm_empty(); _m_empty(); - + + return(result); #elif defined(__arm__) int16x4_t *x_128=(int16x4_t*)x; int16x4_t *y_128=(int16x4_t*)y; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a5a9901cc9..547cd5aeae 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d_3mod.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d_3mod_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d_3mod.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d_3mod_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); From 7a8e3a421c921f9404f8225adcd5dcec0b190e10 Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 5 Jan 2016 15:27:15 +0100 Subject: [PATCH 043/571] Commit to compare -u0 and -u2 performance in interference free environment for TM4 and verify if any additional gain/penatly is needed. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 963d03a35e..f87835e2bd 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -439,10 +439,18 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (rx_type>rx_standard) { - // interf_unaw_shift_tm4_mcs is to avoid tails in SNR/BLER curves - avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->Qm>>1)-1]; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs];//+offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs];//+offset_mumimo_llr_drange[dlsch1_harq->mcs][(get_Qm(dlsch0_harq->mcs)>>1)-1]; + // !!!!! Right now in testing mode for -gS channel ONLY. We investigate if any + // additional gain/penalty needs to be introduced in comparison with I-UA receiver + // by comparing performances if run with -u2 and -u0. + // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 3. + // MCS-dependent LUT will be introduced. + avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); + + //avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->Qm>>1)-1]; + //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs];//+offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; + //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs];//+offset_mumimo_llr_drange[dlsch1_harq->mcs][(get_Qm(dlsch0_harq->mcs)>>1)-1]; //printf("TM4 I-A shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); //printf("TM4 I-A shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs] ); @@ -450,7 +458,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else - // to avoid tails in SNR/BLER curves + // to avoid tails in SNR/BLER curves. -13 is needed to make shift a positive number. + // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 3. + // MCS-dependent LUT will be introduced. avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); From 40313356173b8981544bed1aadd8f3be4b0b4bff Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 5 Jan 2016 20:24:12 +0100 Subject: [PATCH 044/571] Changing names of the files in dlsim.c --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index f87835e2bd..70f605916a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -442,7 +442,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // !!!!! Right now in testing mode for -gS channel ONLY. We investigate if any // additional gain/penalty needs to be introduced in comparison with I-UA receiver // by comparing performances if run with -u2 and -u0. - // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 3. + // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. // MCS-dependent LUT will be introduced. avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); @@ -459,7 +459,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else // to avoid tails in SNR/BLER curves. -13 is needed to make shift a positive number. - // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 3. + // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. // MCS-dependent LUT will be introduced. avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 547cd5aeae..505847bb53 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d_3mod.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_ab_perf_ce_sh%d_div2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_3mod.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_div2.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d_3mod.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_perf_ce_sh%d_div2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_3mod.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_div2.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d_3mod_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_perf_ce_sh%d_div2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d_3mod_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dataout_tx%d_rec%d_mcs%d_mcsi%d_chan%d_ns%d_R%d_ab_sh%d_div2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); // sprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); From 3262bfa66efe8de7c688f1d1df1086a8a269ba55 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 6 Jan 2016 10:38:47 +0100 Subject: [PATCH 045/571] Fixing dlsch_channel_level_TM34. Passing 2 avrage channel lvel and not max how it was done before. Continuing with calibration. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 70f605916a..29d8c30a6b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -445,14 +445,14 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. // MCS-dependent LUT will be introduced. avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; + avg[1] = (log2_approx(avg[1])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); - + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[1],0); //avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->Qm>>1)-1]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs];//+offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs];//+offset_mumimo_llr_drange[dlsch1_harq->mcs][(get_Qm(dlsch0_harq->mcs)>>1)-1]; //printf("TM4 I-A shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); - //printf("TM4 I-A shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs] ); + //printf("TM4 I-A shift layer2 = %dlsch_channel_level_TM34d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs] ); @@ -462,8 +462,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. // MCS-dependent LUT will be introduced. avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; + avg[1] = (log2_approx(avg[1])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[1],0); //printf("TM4 I-UA shift = %d\n",interf_unaw_shift); //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; @@ -3086,9 +3087,11 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, for (aarx=0; aarxnb_antennas_rx; aarx++) { dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - + + avg128D = _mm_setzero_si128(); + for (rb=0; rb Date: Wed, 6 Jan 2016 13:07:10 +0100 Subject: [PATCH 046/571] Now channel-level dependent part of log2_approx works properly. Validating mcs-dependent shift. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 95 ++++++++++++------- openair1/PHY/LTE_TRANSPORT/proto.h | 3 +- 2 files changed, 64 insertions(+), 34 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 29d8c30a6b..e0aac9ed11 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -58,6 +58,8 @@ //#define DEBUG_DLSCH_DEMOD 1 int avg[4]; +int avg_0[4]; +int avg_1[4]; // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; @@ -301,7 +303,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_ue, symbol, nb_rb); - */ + if (first_symbol_flag==1) { dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, @@ -352,7 +354,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); #endif - } + // } aatx = frame_parms->nb_antennas_tx_eNB; aarx = frame_parms->nb_antennas_rx; @@ -420,11 +422,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // scaling interfering channel (following for TM56) - dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + /*dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, - nb_rb); + nb_rb);*/ if (first_symbol_flag==1) { @@ -432,7 +434,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, lte_ue_pdsch_vars[eNB_id]->pmi_ext, - avg, + avg_0, + avg_1, symbol, nb_rb, dlsch0_harq->mimo_mode); @@ -444,10 +447,13 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // by comparing performances if run with -u2 and -u0. // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. // MCS-dependent LUT will be introduced. - avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; - avg[1] = (log2_approx(avg[1])/2) - 13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[1],0); + avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); + + //printf("log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + //printf("log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); //avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->Qm>>1)-1]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs];//+offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs];//+offset_mumimo_llr_drange[dlsch1_harq->mcs][(get_Qm(dlsch0_harq->mcs)>>1)-1]; @@ -457,14 +463,18 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } - else + else { // to avoid tails in SNR/BLER curves. -13 is needed to make shift a positive number. // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. // MCS-dependent LUT will be introduced. - avg[0] = (log2_approx(avg[0])/2) - 13 + interf_unaw_shift; - avg[1] = (log2_approx(avg[1])/2) - 13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg[1],0); + avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); + //printf("log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + //printf("log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + } + //printf("TM4 I-UA shift = %d\n",interf_unaw_shift); //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; @@ -3056,8 +3066,9 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, //compute average channel_level of effective (precoded) channel void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, - unsigned char *pmi_ext, - int *avg, + unsigned char *pmi_ext, + int *avg_0, + int *avg_1, uint8_t symbol, unsigned short nb_rb, MIMO_mode_t mimo_mode){ @@ -3067,14 +3078,15 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, short rb; unsigned char aarx,nre=12,symbol_mod; - __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D; + __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp, avg_0_128D, avg_1_128D; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; //clear average level - avg128D = _mm_setzero_si128(); - avg[0] = 0; - avg[1] = 0; + avg_0[0] = 0; + avg_0[1] = 0; + avg_1[0] = 0; + avg_1[1] = 0; // 5 is always a symbol with no pilots for both normal and extended prefix if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) @@ -3088,11 +3100,12 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - avg128D = _mm_setzero_si128(); - + avg_0_128D = _mm_setzero_si128(); + avg_1_128D = _mm_setzero_si128(); for (rb=0; rbNcp-1)))&&(frame_parms->mode1_flag==0)) { dl_ch0_128+=2; @@ -3140,21 +3157,33 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + + avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); dl_ch0_128+=3; dl_ch1_128+=3; } } - avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + - (((int*)&avg128D)[1])/(nb_rb*nre) + - (((int*)&avg128D)[2])/(nb_rb*nre) + - (((int*)&avg128D)[3])/(nb_rb*nre); + avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) + + (((int*)&avg_0_128D)[1])/(nb_rb*nre) + + (((int*)&avg_0_128D)[2])/(nb_rb*nre) + + (((int*)&avg_0_128D)[3])/(nb_rb*nre); + // printf("From Chan_level aver stream 0 %d =%d\n", aarx, avg_0[aarx]); + + avg_1[aarx] = (((int*)&avg_1_128D)[0])/(nb_rb*nre) + + (((int*)&avg_1_128D)[1])/(nb_rb*nre) + + (((int*)&avg_1_128D)[2])/(nb_rb*nre) + + (((int*)&avg_1_128D)[3])/(nb_rb*nre); + // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); } + // choose maximum of the 2 effective channels - // avg[0] = cmax(avg[0],avg[1]); + avg_0[0] = cmax(avg_0[0], avg_0[1]); + avg_1[0] = cmax(avg_1[0], avg_1[1]); _mm_empty(); _m_empty(); diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 25d77b25f7..392e20f0be 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1000,7 +1000,8 @@ void dlsch_channel_level(int32_t **dl_ch_estimates_ext, void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, unsigned char *pmi_ext, - int *avg, + int *avg_0, + int *avg_1, uint8_t symbol, unsigned short nb_rb, MIMO_mode_t mimo_mode); From 3521765b6281c068d86157feebec9968c0d8996e Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 7 Jan 2016 11:47:14 +0100 Subject: [PATCH 047/571] Changes: 1. Fixing a bug in dlsch_channel_level_TM56. avg128D = _mm_setzero_si128() must be done inside the rx_antennas loop and not before 2. Cleaning up code in dlsch_demodulation.c 3. Offsets for TM5 and TM6 still must be validated. 4. Right now IA and I-UA receivers for TM4 have the same offset - validate if any additional penalty/gain is needed. 5. Shortened file names in dlsim.c since matlab can read only 63-characters file names. 6. Tested: TM4 U2 -gS perfect CE works fine for EESM and MIESM abstraction (MCS 4 MSE= 0.007 dB on both streams). --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 176 ++++++++---------- openair1/SIMULATION/LTE_PHY/dlsim.c | 13 +- openair1/SIMULATION/TOOLS/abstraction.c | 4 +- 3 files changed, 88 insertions(+), 105 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index e0aac9ed11..e3a0267721 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -197,6 +197,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, return(-1); } } + +#ifdef DEBUG_PHY + LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); +#endif //printf("rx_pdsch: harq_pid=%d, round=%d\n",harq_pid,round); @@ -296,70 +300,35 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, return(-1); } - /* - // DL power control: Scaling of Channel estimates for PDSCH - dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); - - if (first_symbol_flag==1) { - dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - avg, - symbol, - nb_rb); -#ifdef DEBUG_PHY - LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]); -#endif - - // the channel gain should be the effective gain of precoding + channel - // however lets be more conservative and set maxh = nb_tx*nb_rx*max(h_i) - // in case of precoding we add an additional factor of two for the precoding gain - avgs = 0; - - for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) - for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); - // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; - // printf(" TM1 shift = %d\n",interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]); - // + log2_approx(frame_parms->nb_antennas_tx_eNB-1) //-1 because log2_approx counts the number of bits - // + log2_approx(frame_parms->nb_antennas_rx-1); - - if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) && - (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) && - (dlsch0_harq->dl_power_off==1)) // we are in TM 6 - lte_ue_pdsch_vars[eNB_id]->log2_maxh++; - - //printf("log2_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); - - // this version here applies the factor .5 also to the extra terms. however, it does not work so well as the one above - /* K = Nb_rx in TM1 - Nb_tx*Nb_rx in TM2,4,5 - Nb_tx^2*Nb_rx in TM6 */ - /* - K = frame_parms->nb_antennas_rx*frame_parms->nb_antennas_tx_eNB; //that also covers TM1 since Nb_tx=1 - if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) && - (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) && - (dlsch0_harq->dl_power_off==1)) // we are in TM 6 - K *= frame_parms->nb_antennas_tx_eNB; - - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(K*avgs)/2); - */ - -#ifdef DEBUG_PHY - LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); - LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); -#endif - // } aatx = frame_parms->nb_antennas_tx_eNB; aarx = frame_parms->nb_antennas_rx; if (dlsch0_harq->mimo_modedl_ch_estimates_ext, + frame_parms, + dlsch_ue, + symbol, + nb_rb); + + if (first_symbol_flag==1) { + dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_rb); + + avgs = 0; + + for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) + for (aarx=0;aarxnb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + // printf(" TM1 shift = %d\n",interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]); + + } dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -419,14 +388,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // LOG_I(PHY,"Running PDSCH RX for TM3\n"); if (frame_parms->nb_antennas_tx_eNB == 2) { - - - // scaling interfering channel (following for TM56) - /*dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, - nb_rb);*/ + nb_rb); if (first_symbol_flag==1) { @@ -441,46 +408,30 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch0_harq->mimo_mode); - if (rx_type>rx_standard) { - // !!!!! Right now in testing mode for -gS channel ONLY. We investigate if any - // additional gain/penalty needs to be introduced in comparison with I-UA receiver - // by comparing performances if run with -u2 and -u0. - // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. - // MCS-dependent LUT will be introduced. + if (rx_type>rx_standard) { + // Shifts are needed to avoid tails in SNR/BLER curves. + // LUT will be introduced with mcs-dependent shift avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - //printf("log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - //printf("log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - //avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(dlsch1_harq->Qm>>1)-1]; - //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs];//+offset_mumimo_llr_drange[dlsch0_harq->mcs][(get_Qm(dlsch1_harq->mcs)>>1)-1]; - //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs];//+offset_mumimo_llr_drange[dlsch1_harq->mcs][(get_Qm(dlsch0_harq->mcs)>>1)-1]; - //printf("TM4 I-A shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); - //printf("TM4 I-A shift layer2 = %dlsch_channel_level_TM34d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs] ); - - + //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - } + } else { - // to avoid tails in SNR/BLER curves. -13 is needed to make shift a positive number. - // this is valid only if same mcs are used. We calibrate for mcs 4. Best shift value is 13. - // MCS-dependent LUT will be introduced. + // Shifts are needed to avoid tails in SNR/BLER curves. + // LUT will be introduced with mcs-dependent shift avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - //printf("log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - //printf("log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - } + //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + } - //printf("TM4 I-UA shift = %d\n",interf_unaw_shift); - //lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]; - //lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = (log2_approx(avg[0])/2) +interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]; - //printf("TM4 I-UA shift layer1 = %d\n",interf_unaw_shift_tm4_mcs[dlsch0_harq->mcs]); - //printf("TM4 I-UA shift layer2 = %d\n",interf_unaw_shift_tm4_mcs[dlsch1_harq->mcs]); - } + } dlsch_channel_compensation_TM34(frame_parms, lte_ue_pdsch_vars[eNB_id], @@ -633,7 +584,40 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh); - } else { + } + else { + + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + dlsch_ue, + symbol, + nb_rb); + + if (first_symbol_flag==1) { + + dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + avg, + symbol, + nb_rb); + + avgs = 0; + + for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) + for (aarx=0;aarxnb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + + if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) && + (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) && + (dlsch0_harq->dl_power_off==1)) // we are in TM 6 + + lte_ue_pdsch_vars[eNB_id]->log2_maxh++; + // printf(" TM6 log2_maxh = %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); + + } dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, @@ -3313,8 +3297,6 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - //clear average level - avg128D = _mm_setzero_si128(); avg[0] = 0; avg[1] = 0; // 5 is always a symbol with no pilots for both normal and extended prefix @@ -3329,7 +3311,9 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, for (aarx=0; aarxnb_antennas_rx; aarx++) { dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - + + avg128D = _mm_setzero_si128(); + for (rb=0; rb #include #include From b80a6660bf06d3471bc2c297319f87dbd81b4615 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 7 Jan 2016 13:50:45 +0100 Subject: [PATCH 048/571] Some more clean up in dlsch_demodulation.c --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index e3a0267721..02e729c07f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -585,7 +585,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh); } - else { + else if (dlsch0_harq->dl_power_off==1) { dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, From 42eb48faa7f698b7a76d95cf0f52ed6431925f13 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 8 Jan 2016 15:32:53 +0100 Subject: [PATCH 049/571] Fixing previous commit: messed up with parenthesis in dlsch_demodulation.c --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 107 +++++++++--------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 02e729c07f..8406f65610 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -197,10 +197,6 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, return(-1); } } - -#ifdef DEBUG_PHY - LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); -#endif //printf("rx_pdsch: harq_pid=%d, round=%d\n",harq_pid,round); @@ -301,34 +297,43 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } +#ifdef DEBUG_PHY + LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); + LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); +#endif + aatx = frame_parms->nb_antennas_tx_eNB; aarx = frame_parms->nb_antennas_rx; if (dlsch0_harq->mimo_modedl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); + + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + dlsch_ue, + symbol, + nb_rb); - if (first_symbol_flag==1) { - dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + if (first_symbol_flag==1) { + dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, avg, symbol, nb_rb); - +#ifdef DEBUG_PHY + LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]); +#endif + avgs = 0; for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) for (aarx=0;aarxnb_antennas_rx;aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; - // printf(" TM1 shift = %d\n",interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]); - - } + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + + } + dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -388,7 +393,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // LOG_I(PHY,"Running PDSCH RX for TM3\n"); if (frame_parms->nb_antennas_tx_eNB == 2) { - + + + // scaling interfering channel (following for TM56) dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, @@ -408,7 +415,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch0_harq->mimo_mode); - if (rx_type>rx_standard) { + if (rx_type>rx_standard) { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; @@ -430,8 +437,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); } - - } + } dlsch_channel_compensation_TM34(frame_parms, lte_ue_pdsch_vars[eNB_id], @@ -485,7 +491,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else if (dlsch0_harq->mimo_moden_connected_eNB)) { // TM5 two-user + if ((rx_type==rx_IC_single_stream) && (eNB_id_i==phy_vars_ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) { // TM5 two-user // Scale the channel estimates for interfering stream @@ -512,7 +518,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); //printf("log1_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); } - + dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, @@ -552,7 +558,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // printf("pmi %d, pmi_i %d\n",lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb],lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]); } - + + dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, @@ -584,40 +591,36 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh); - } - else if (dlsch0_harq->dl_power_off==1) { + } else if (dlsch0_harq->dl_power_off==1) { - dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); - - if (first_symbol_flag==1) { - - dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + frame_parms, + dlsch_ue, + symbol, + nb_rb); + + /* compute new log2_maxh for effective channel */ + if (first_symbol_flag==1) { + + // effective channel of desired user is always stronger than interfering eff. channel + dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb); - - avgs = 0; - for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) - for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); + avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; - - if ((dlsch0_harq->mimo_mode>=UNIFORM_PRECODING11) && - (dlsch0_harq->mimo_mode< DUALSTREAM_UNIFORM_PRECODING1) && - (dlsch0_harq->dl_power_off==1)) // we are in TM 6 + lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh++; + + //printf("log1_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); + } + + - lte_ue_pdsch_vars[eNB_id]->log2_maxh++; - // printf(" TM6 log2_maxh = %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); - - } dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, @@ -3297,6 +3300,8 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + //clear average level + avg128D = _mm_setzero_si128(); avg[0] = 0; avg[1] = 0; // 5 is always a symbol with no pilots for both normal and extended prefix @@ -3311,9 +3316,7 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, for (aarx=0; aarxnb_antennas_rx; aarx++) { dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - - avg128D = _mm_setzero_si128(); - + for (rb=0; rb Date: Fri, 8 Jan 2016 15:53:41 +0100 Subject: [PATCH 050/571] Small bugfix for TM5 and TM6 --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 8406f65610..bbb02b3d0f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -494,6 +494,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if ((rx_type==rx_IC_single_stream) && (eNB_id_i==phy_vars_ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) { // TM5 two-user // Scale the channel estimates for interfering stream + + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + dlsch_ue, + symbol, + nb_rb); dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, frame_parms, @@ -593,7 +599,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } else if (dlsch0_harq->dl_power_off==1) { - dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, @@ -609,9 +615,14 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avg, symbol, nb_rb); + avgs = 0; + + for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) + for (aarx=0;aarxnb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); - avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh++; From d0fac35f680e950b5811c8bf55f3cb15242ff862 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 8 Jan 2016 16:13:09 +0100 Subject: [PATCH 051/571] Preparing to merge with hotfix-71-freq_channel, running with old version of abstrcation.c --- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index b08cf06915..326ab31641 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_nofix_pce_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_nofix_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 73382b828482868e3565bb372453f3bbf264894c Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 8 Jan 2016 16:54:06 +0100 Subject: [PATCH 052/571] Validating abstraction.c with a hotfix. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 +- openair1/SIMULATION/TOOLS/abstraction.c | 186 +----------------------- 2 files changed, 3 insertions(+), 187 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 326ab31641..a0ae4fdbfc 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_nofix_pce_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_nofix_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c index f26f450a7d..b896a2ad78 100644 --- a/openair1/SIMULATION/TOOLS/abstraction.c +++ b/openair1/SIMULATION/TOOLS/abstraction.c @@ -26,7 +26,7 @@ Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ -/*#include +#include #include #include #include @@ -324,189 +324,5 @@ double pbch_bler(double sinr) //printf ("sinr %f bler %f\n",sinr,bler); return(bler); -}*/ - -#include -#include -#include -#include -#include - - -#include "PHY/TOOLS/defs.h" -#include "defs.h" - -void freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { - - double delta_f,freq; // 90 kHz spacing - double delay; - int16_t f; - uint8_t aarx,aatx,l; - - delta_f = nb_rb*180000/(n_samples-1); - //write_output("channel.m","a",desc->a[0],desc->nb_taps,1,8); - for (f=-n_samples/2;fnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { - desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f].x=0.0; - desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f].y=0.0; - for (l=0;l<(int)desc->nb_taps;l++) { - if (desc->nb_taps==1) - delay = desc->delays[l]; - else - delay = desc->delays[l]+NB_SAMPLES_CHANNEL_OFFSET/desc->sampling_rate; - desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*cos(2*M_PI*freq*delay)+ - desc->a[l][aarx+(aatx*desc->nb_rx)].y*sin(2*M_PI*freq*delay)); - desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*sin(2*M_PI*freq*delay)+ - desc->a[l][aarx+(aatx*desc->nb_rx)].y*cos(2*M_PI*freq*delay)); - } - // printf("chF(%d) => (%f,%f)\n",n_samples/2+f, - // desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].x, - // desc->chF[aarx+(aatx*desc->nb_rx)][f+n_samples/2].y); - } - } - } } -double compute_pbch_sinr(channel_desc_t *desc, - channel_desc_t *desc_i1, - channel_desc_t *desc_i2, - double snr_dB,double snr_i1_dB, - double snr_i2_dB, - uint16_t nb_rb) { - - double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); - uint16_t f; - uint8_t aarx,aatx; - double S; - struct complex S_i1; - struct complex S_i2; - - avg_sinr=0.0; - // printf("nb_rb %d\n",nb_rb); - for (f=(nb_rb-6);f<(nb_rb+6);f++) { - S = 0.0; - S_i1.x =0.0; - S_i1.y =0.0; - S_i2.x =0.0; - S_i2.y =0.0; - for (aarx=0;aarxnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { - S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x + - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y); - // printf("%d %d chF[%d] => (%f,%f)\n",aarx,aatx,f,desc->chF[aarx+(aatx*desc->nb_rx)][f].x,desc->chF[aarx+(aatx*desc->nb_rx)][f].y); - - if (desc_i1) { - S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x + - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y); - S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y - - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x); - } - if (desc_i2) { - S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x + - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y); - S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y - - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x); - } - } - } - // printf("snr %f f %d : S %f, S_i1 %f, S_i2 %f\n",snr,f-nb_rb,S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)); - avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y))); - } - // printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2); - return(10*log10(avg_sinr/12.0)); -} - - -double compute_sinr(channel_desc_t *desc, - channel_desc_t *desc_i1, - channel_desc_t *desc_i2, - double snr_dB,double snr_i1_dB, - double snr_i2_dB, - uint16_t nb_rb) { - - double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); - uint16_t f; - uint8_t aarx,aatx; - double S; - struct complex S_i1; - struct complex S_i2; - - avg_sinr=0.0; - // printf("nb_rb %d\n",nb_rb); - for (f=0;f<2*nb_rb;f++) { - S = 0.0; - S_i1.x =0.0; - S_i1.y =0.0; - S_i2.x =0.0; - S_i2.y =0.0; - for (aarx=0;aarxnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { - S += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc->chF[aarx+(aatx*desc->nb_rx)][f].x + - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc->chF[aarx+(aatx*desc->nb_rx)][f].y); - if (desc_i1) { - S_i1.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x + - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y); - S_i1.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].y - - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i1->chF[aarx+(aatx*desc->nb_rx)][f].x); - } - if (desc_i2) { - S_i2.x += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x + - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y); - S_i2.y += (desc->chF[aarx+(aatx*desc->nb_rx)][f].x*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].y - - desc->chF[aarx+(aatx*desc->nb_rx)][f].y*desc_i2->chF[aarx+(aatx*desc->nb_rx)][f].x); - } - } - } - // printf("f %d : S %f, S_i1 %f, S_i2 %f\n",f-nb_rb,snr*S,snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y),snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y)); - avg_sinr += (snr*S/(desc->nb_tx+snr_i1*sqrt(S_i1.x*S_i1.x + S_i1.y*S_i1.y)+snr_i2*sqrt(S_i2.x*S_i2.x + S_i2.y*S_i2.y))); - } - // printf("avg_sinr %f (%f,%f,%f)\n",avg_sinr/12.0,snr,snr_i1,snr_i2); - return(10*log10(avg_sinr/(nb_rb*2))); -} - - uint8_t pbch_polynomial_degree; -double a[7]; - -void load_pbch_desc(FILE *pbch_file_fd) { - - int i; - char dummy[25]; - - fscanf(pbch_file_fd,"%d",&pbch_polynomial_degree); - if (pbch_polynomial_degree>6) { - printf("Illegal degree for pbch interpolation polynomial %d\n",pbch_polynomial_degree); - exit(-1); - } - - printf("PBCH polynomial : "); - - for (i=0;i<=pbch_polynomial_degree;i++) { - fscanf(pbch_file_fd,"%s",dummy); - a[i] = strtod(dummy,NULL); - printf("%f ",a[i]); - } - printf("\n"); -} - -double pbch_bler(double sinr) { - - int i; - double log10_bler=a[pbch_polynomial_degree]; - double sinrpow=sinr; - // printf("log10bler %f\n",log10_bler); - if (sinr<-7.9) - return(1.0); - else if (sinr>=0.0) - return(1e-4); - - for (i=1;i<=pbch_polynomial_degree;i++) { - // printf("sinrpow %f\n",sinrpow); - log10_bler += (a[pbch_polynomial_degree-i]*sinrpow); - sinrpow *= sinr; - // printf("log10bler %f\n",log10_bler); - } - return(pow(10.0,log10_bler)); -} From 388452f1bcc79fd7f4d82d3a562696d9bd6a4e09 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 11 Jan 2016 11:10:04 +0100 Subject: [PATCH 053/571] For in demodulation TM4 trying average as a sum of energy in both antennas. Changing names of output files in dlsim respectiively. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 7 +++++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index bbb02b3d0f..6ea8f45b43 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -471,6 +471,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + + //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); //to be optimized (just take complex conjugate) @@ -481,6 +483,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); } @@ -3180,8 +3183,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, // choose maximum of the 2 effective channels - avg_0[0] = cmax(avg_0[0], avg_0[1]); - avg_1[0] = cmax(avg_1[0], avg_1[1]); + avg_0[0] = avg_0[0] + avg_0[1]; + avg_1[0] = avg_1[0] + avg_1[1]; _mm_empty(); _m_empty(); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a0ae4fdbfc..52d3a91b19 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avs.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avs.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From e4dec0771c3b6273c6b5dc03ade11abf5fadb780 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 11 Jan 2016 15:04:03 +0100 Subject: [PATCH 054/571] Another change for aver level: now log2aaprox(ch11/2) + log2approx(ch21/2) -13 +shift --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 9 ++++----- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 6ea8f45b43..1607b77806 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -430,8 +430,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; + avg_0[0] = (log2_approx(avg_0[0])/2) + (log2_approx(avg_0[1])/2) - 13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) + (log2_approx(avg_1[1])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); @@ -3182,9 +3182,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, } - // choose maximum of the 2 effective channels - avg_0[0] = avg_0[0] + avg_0[1]; - avg_1[0] = avg_1[0] + avg_1[1]; +// avg_0[0] = avg_0[0] + avg_0[1]; + // avg_1[0] = avg_1[0] + avg_1[1]; _mm_empty(); _m_empty(); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 52d3a91b19..667b9a2008 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avs.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avs.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avs.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 42eeb9d65e84afeb15ddf27860a6092f58ff9bf1 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 11 Jan 2016 15:53:13 +0100 Subject: [PATCH 055/571] New attempt to scale IA receiver --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 12 ++++++------ openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 1607b77806..c0915a72c9 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -430,10 +430,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) + (log2_approx(avg_0[1])/2) - 13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) + (log2_approx(avg_1[1])/2) - 13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); + avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],avg_1[0]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],avg_1[0]); //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); } @@ -3182,8 +3182,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, } -// avg_0[0] = avg_0[0] + avg_0[1]; - // avg_1[0] = avg_1[0] + avg_1[1]; + avg_0[0] = avg_0[0] + avg_0[1]; + avg_1[0] = avg_1[0] + avg_1[1]; _mm_empty(); _m_empty(); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 667b9a2008..60d113ec26 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn2.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn2.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From e5a94ee6ddfd1be8df0350b2d7f390b3eca0642c Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 11 Jan 2016 16:04:10 +0100 Subject: [PATCH 056/571] Exchanging rho for thr first stream and for the second in qpsk_qpsk_llr --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 6 +++--- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index c0915a72c9..4dd87f36d9 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -736,7 +736,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_qpsk_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), @@ -745,10 +745,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_qpsk_qpsk_llr(frame_parms, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); } } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 60d113ec26..f38e9eb3c8 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn2.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn2.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn2.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 5e1e8a58a7e2d24b400bf97e18bd993dd669302f Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 11 Jan 2016 16:12:21 +0100 Subject: [PATCH 057/571] Fixing previous commit --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 4dd87f36d9..d4983e262f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -433,7 +433,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],avg_1[0]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],avg_1[0]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_0[0],avg_1[0]); //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); } From 432a889cc06ec0e232b267e55b4e461694fcbe96 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 11 Jan 2016 16:27:58 +0100 Subject: [PATCH 058/571] Stupid check if do not divide by 2 the aver level --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index d4983e262f..15e40d6d20 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -430,8 +430,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; + avg_0[0] = (log2_approx(avg_0[0])) - 13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],avg_1[0]); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_0[0],avg_1[0]); //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f38e9eb3c8..f01f4f96a1 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_nod2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_nod2_avsn2_rho.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_nod2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_nod2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_nod2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_nod2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From cbd30e62fab1b06de2ea3035f085ff4f2133fc03 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 13 Jan 2016 12:17:29 +0100 Subject: [PATCH 059/571] Experimanetal change in dlsch_channel_commensation_TM34. Will not work for more than 2 antennas. Testing. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 873 +++++++++++++++++- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 +- 2 files changed, 870 insertions(+), 15 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index d4983e262f..6ba3d6abeb 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -237,10 +237,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], - lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, rballoc, symbol, subframe, @@ -1850,6 +1850,857 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, _m_empty(); } +#if 1 +void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDSCH *lte_ue_pdsch_vars, + PHY_MEASUREMENTS *phy_measurements, + int eNB_id, + unsigned char symbol, + unsigned char mod_order0, + unsigned char mod_order1, + int harq_pid, + int round, + MIMO_mode_t mimo_mode, + unsigned short nb_rb, + unsigned char output_shift0, + unsigned char output_shift1) { + +#if defined(__x86_64__) || defined(__i386__) + + unsigned short rb,Nre; + __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag0_128,*dl_ch_mag1_128,*dl_ch_mag0_128b,*dl_ch_mag1_128b,*rxdataF128,*rxdataF_comp0_128,*rxdataF_comp1_128, + *dl_ch00_128, *dl_ch01_128, *dl_ch10_128, *dl_ch11_128, *rxdataF0_128, *rxdataF1_128, *rxdataF_comp00_128, *rxdataF_comp01_128, + *rxdataF_comp10_128, *rxdataF_comp11_128; + unsigned char aarx=0,symbol_mod,pilots=0; + int precoded_signal_strength0=0,precoded_signal_strength1=0, precoded_signal_strength00=0, precoded_signal_strength01=0, + precoded_signal_strength10=0, precoded_signal_strength11=0; + int rx_power_correction; + + int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; + int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; + int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; + int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; + int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; + int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; + int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; + int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; + unsigned char *pmi_ext = lte_ue_pdsch_vars->pmi_ext; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) + pilots=1; + + rx_power_correction = 1; + + // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); + + if (mod_order0 == 4) { + QAM_amp0_128 = _mm_set1_epi16(QAM16_n1); + QAM_amp0_128b = _mm_setzero_si128(); + } else if (mod_order0 == 6) { + QAM_amp0_128 = _mm_set1_epi16(QAM64_n1); + QAM_amp0_128b = _mm_set1_epi16(QAM64_n2); + } + + if (mod_order1 == 4) { + QAM_amp1_128 = _mm_set1_epi16(QAM16_n1); + QAM_amp1_128b = _mm_setzero_si128(); + } else if (mod_order1 == 6) { + QAM_amp1_128 = _mm_set1_epi16(QAM64_n1); + QAM_amp1_128b = _mm_set1_epi16(QAM64_n2); + } + + //for (aarx=0;aarxnb_antennas_rx;aarx++) { + + // printf("symbol %d, rx antenna %d\n", symbol, aarx); + + dl_ch00_128 = (__m128i *)&dl_ch_estimates_ext[0][symbol*frame_parms->N_RB_DL*12]; // this is h11 + dl_ch01_128 = (__m128i *)&dl_ch_estimates_ext[1][symbol*frame_parms->N_RB_DL*12]; // this is h12 + dl_ch10_128 = (__m128i *)&dl_ch_estimates_ext[2][symbol*frame_parms->N_RB_DL*12]; // this is h21 + dl_ch11_128 = (__m128i *)&dl_ch_estimates_ext[3][symbol*frame_parms->N_RB_DL*12]; // this is h22 + + // dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 + // dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1 + // dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 + // dl_ch_mag1_128b = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 + rxdataF0_128 = (__m128i *)&rxdataF_ext[0][symbol*frame_parms->N_RB_DL*12]; // y0=h11*x1+h12*x2 + rxdataF1_128 = (__m128i *)&rxdataF_ext[1][symbol*frame_parms->N_RB_DL*12]; // y1=h21*x1 + h22*x2 + rxdataF_comp00_128 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; // comp x1 antenna 0 + rxdataF_comp01_128 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; // comp x1 antenna 1 + rxdataF_comp10_128 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; // comp x2 antenna 0 + rxdataF_comp11_128 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; // comp x2 antenna 1 + + for (rb=0; rb2) { + // get channel amplitude if not QPSK + + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + + mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + dl_ch_mag0_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag0_128b[0] = dl_ch_mag0_128[0]; + dl_ch_mag0_128[0] = _mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128); + dl_ch_mag0_128[0] = _mm_slli_epi16(dl_ch_mag0_128[0],1); + + // print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]); + + + dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag0_128b[1] = dl_ch_mag0_128[1]; + dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128); + dl_ch_mag0_128[1] = _mm_slli_epi16(dl_ch_mag0_128[1],1); + + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + + dl_ch_mag0_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag0_128b[2] = dl_ch_mag0_128[2]; + + dl_ch_mag0_128[2] = _mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128); + dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1); + } + + dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b); + dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1); + + // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]); + + dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b); + dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1); + + if (pilots==0) { + dl_ch_mag0_128b[2] = _mm_mulhi_epi16(dl_ch_mag0_128b[2],QAM_amp0_128b); + dl_ch_mag0_128b[2] = _mm_slli_epi16(dl_ch_mag0_128b[2],1); + } + } + + if (mod_order1>2) { + // get channel amplitude if not QPSK + + mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + + mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); + + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + + dl_ch_mag1_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag1_128b[0] = dl_ch_mag1_128[0]; + dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128); + dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1); + + // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]); + + dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); + dl_ch_mag1_128b[1] = dl_ch_mag1_128[1]; + dl_ch_mag1_128[1] = _mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128); + dl_ch_mag1_128[1] = _mm_slli_epi16(dl_ch_mag1_128[1],1); + + if (pilots==0) { + mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); + + dl_ch_mag1_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); + dl_ch_mag1_128b[2] = dl_ch_mag1_128[2]; + + dl_ch_mag1_128[2] = _mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128); + dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1); + } + + dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b); + dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1); + + // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]); + + dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b); + dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1); + + if (pilots==0) { + dl_ch_mag1_128b[2] = _mm_mulhi_epi16(dl_ch_mag1_128b[2],QAM_amp1_128b); + dl_ch_mag1_128b[2] = _mm_slli_epi16(dl_ch_mag1_128b[2],1); + } + } */ + + // Layer zero antenna 0 : we make conj(ch11)*y1 + mmtmpD0 = _mm_madd_epi16(dl_ch00_128[0],rxdataF0_128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch00_128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[0]); + // print_ints("im",&mmtmpD1); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + // printf("Shift: %d\n",output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp00_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch0_128); + // print_shorts("pack:",rxdataF_comp0_128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch00_128[1],rxdataF0_128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch00_128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp00_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch0_128+1); + // print_shorts("pack:",rxdataF_comp0_128+1); + + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch00_128[2],rxdataF0_128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch00_128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp00_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch0_128+2); + // print_shorts("pack:",rxdataF_comp0_128+2); + + } + + // Layer zero antenna 1 : we make conj(ch21)*y2 + mmtmpD0 = _mm_madd_epi16(dl_ch10_128[0],rxdataF1_128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch10_128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[0]); + // print_ints("im",&mmtmpD1); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + // printf("Shift: %d\n",output_shift); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp01_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch0_128); + // print_shorts("pack:",rxdataF_comp0_128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch10_128[1],rxdataF1_128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch10_128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp01_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch0_128+1); + // print_shorts("pack:",rxdataF_comp0_128+1); + + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch10_128[2],rxdataF1_128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch10_128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp01_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch0_128+2); + // print_shorts("pack:",rxdataF_comp0_128+2); + + } + + + + + // Layer one antenna 0 : we make conj(ch12)*y0 + mmtmpD0 = _mm_madd_epi16(dl_ch01_128[0],rxdataF0_128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch01_128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp10_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch1_128); + // print_shorts("pack:",rxdataF_comp1_128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch01_128[1],rxdataF0_128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch01_128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp10_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch1_128+1); + // print_shorts("pack:",rxdataF_comp1_128+1); + + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch01_128[2],rxdataF0_128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch01_128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp10_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch1_128+2); + // print_shorts("pack:",rxdataF_comp1_128+2); + + } + + // Layer one antenna 1 : we make conj(ch22)*y2 + mmtmpD0 = _mm_madd_epi16(dl_ch11_128[0],rxdataF1_128[0]); + // print_ints("re",&mmtmpD0); + + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch11_128[0],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[0]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + // print_ints("re(shift)",&mmtmpD0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); + // print_ints("im(shift)",&mmtmpD1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); + rxdataF_comp11_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch1_128); + // print_shorts("pack:",rxdataF_comp1_128); + + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch11_128[1],rxdataF1_128[1]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch11_128[1],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[1]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp11_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch1_128+1); + // print_shorts("pack:",rxdataF_comp1_128+1); + + if (pilots==0) { + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch11_128[2],rxdataF1_128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch11_128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + + rxdataF_comp11_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch1_128+2); + // print_shorts("pack:",rxdataF_comp1_128+2); + + dl_ch00_128+=3; + dl_ch01_128+=3; + dl_ch10_128+=3; + dl_ch11_128+=3; + //dl_ch_mag0_128+=3; + //dl_ch_mag1_128+=3; + //dl_ch_mag0_128b+=3; + //dl_ch_mag1_128b+=3; + rxdataF0_128+=3; + rxdataF1_128+=3; + rxdataF_comp00_128+=3; + rxdataF_comp01_128+=3; + rxdataF_comp10_128+=3; + rxdataF_comp11_128+=3; + } + else { + dl_ch00_128+=2; + dl_ch01_128+=2; + dl_ch10_128+=2; + dl_ch11_128+=2; + //dl_ch_mag0_128+=3; + //dl_ch_mag1_128+=3; + //dl_ch_mag0_128b+=3; + //dl_ch_mag1_128b+=3; + rxdataF0_128+=2; + rxdataF1_128+=2; + rxdataF_comp00_128+=2; + rxdataF_comp01_128+=2; + rxdataF_comp10_128+=2; + rxdataF_comp11_128+=2; + } + + } // rb loop + Nre = (pilots==0) ? 12 : 8; + + precoded_signal_strength00 = ((signal_energy_nodc(&dl_ch_estimates_ext[0][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[0])); + precoded_signal_strength01 = ((signal_energy_nodc(&dl_ch_estimates_ext[1][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[1])); + precoded_signal_strength0 = precoded_signal_strength00 + precoded_signal_strength01; + + precoded_signal_strength10 = ((signal_energy_nodc(&dl_ch_estimates_ext[2][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[2])); + precoded_signal_strength11 = ((signal_energy_nodc(&dl_ch_estimates_ext[3][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[3])); + precoded_signal_strength1 = precoded_signal_strength10 + precoded_signal_strength11; + + + phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,phy_measurements->n0_power_tot); + phy_measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,phy_measurements->n0_power_tot); + + // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, + // phy_measurements->precoded_cqi_dB[eNB_id][0]); + + _mm_empty(); + _m_empty(); + + #elif defined(__arm__) + + unsigned short rb,Nre; + unsigned char aarx,symbol_mod,pilots=0; + int precoded_signal_strength0=0,precoded_signal_strength1=0, rx_power_correction; + int16x4_t *dl_ch0_128,*rxdataF128; + int16x4_t *dl_ch1_128; + int16x8_t *dl_ch0_128b,*dl_ch1_128b; + + int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; + int16x8_t *dl_ch_mag0_128,*dl_ch_mag0_128b,*dl_ch_mag1_128,*dl_ch_mag1_128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp0_128,*rxdataF_comp1_128; + int16x8_t QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; + int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); + + int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; + int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; + int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; + int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; + int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; + int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; + int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; + int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; + + int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { + if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size + { nb_rb=1+(5*nb_rb/6); } + + else + { pilots=1; } + } + + rx_power_correction=1; + + if (mod_order0 == 4) { + QAM_amp0_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) + QAM_amp0_128b = vmovq_n_s16(0); + + } else if (mod_order0 == 6) { + QAM_amp0_128 = vmovq_n_s16(QAM64_n1); // + QAM_amp0_128b = vmovq_n_s16(QAM64_n2); + } + + if (mod_order1 == 4) { + QAM_amp1_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) + QAM_amp1_128b = vmovq_n_s16(0); + + } else if (mod_order1 == 6) { + QAM_amp1_128 = vmovq_n_s16(QAM64_n1); // + QAM_amp1_128b = vmovq_n_s16(QAM64_n2); + } + + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + + + + dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128b = (int16x8_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag0_128 = (int16x8_t*)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag0_128b = (int16x8_t*)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag1_128 = (int16x8_t*)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag1_128b = (int16x8_t*)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp0_128 = (int16x8_t*)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp1_128 = (int16x8_t*)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; + + for (rb=0; rb2) { + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + + } + + dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b); + dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b); + dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128); + dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128); + + + if (pilots==0) { + dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b); + dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128); + } + } + + if (mod_order1>2) { + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(dl_ch1_128[0], dl_ch1_128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + + } + + dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b); + dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b); + dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128); + dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128); + + + if (pilots==0) { + dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b); + dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128); + } + } + + mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]); + //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] + mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]); + //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); + //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); + //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp0_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); + mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp0_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + // second stream + mmtmpD0 = vmull_s16(dl_ch1_128[0], rxdataF128[0]); + mmtmpD1 = vmull_s16(dl_ch1_128[1], rxdataF128[1]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); + + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); + //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp1_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + mmtmpD0 = vmull_s16(dl_ch1_128[2], rxdataF128[2]); + mmtmpD1 = vmull_s16(dl_ch1_128[3], rxdataF128[3]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp1_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vmull_s16(dl_ch1_128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + } + } + + + + Nre = (pilots==0) ? 12 : 8; + + // rx_antennas + } + + + Nre = (pilots==0) ? 12 : 8; + + precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); + + precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], + (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); + + phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,phy_measurements->n0_power_tot); + phy_measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,phy_measurements->n0_power_tot); + +#endif +} +#endif + + + + +#if 0 void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_PDSCH *lte_ue_pdsch_vars, PHY_MEASUREMENTS *phy_measurements, @@ -1912,8 +2763,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // printf("symbol %d, rx antenna %d\n", symbol, aarx); - dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 - dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 + dl_ch00_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 + dl_ch10_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h21 dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 @@ -2539,7 +3390,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, #endif } - +#endif void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, unsigned char symbol, @@ -4121,7 +4972,9 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch0 = &dl_ch_estimates[aarx][5]; dl_ch1 = &dl_ch_estimates[2+aarx][5]; } - + // printf ("antenna %d\n", aarx); + // print_shorts("From extraction ch0\n", dl_ch0 ); + // print_shorts("From extraction ch1\n", dl_ch1 ); pmi_loc = pmi_ext; // pointers to extracted RX signals and channel estimates @@ -4129,6 +4982,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)]; + for (prb=0; prbN_RB_DL; prb++) { skip_half=0; @@ -4208,7 +5062,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } - /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; @@ -4509,13 +5362,15 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } dl_ch0_ext+=8; - dl_ch1_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; } //pilots==1 } // if Middle PRB } // if odd PRB } // if rballoc==1 } // for prb + } // for aarx return(nb_rb/frame_parms->nb_antennas_rx); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f38e9eb3c8..36873adce6 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_expcomp.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_expcomp.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From aaccaf9796f0ff61b4393843b6a3c6e81ecd353d Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 13 Jan 2016 14:43:16 +0100 Subject: [PATCH 060/571] Revert ":q#" This reverts commit 83324945ad2a93323e7296d55af44c3532ad4442, reversing changes made to cbd30e62fab1b06de2ea3035f085ff4f2133fc03. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 812da7e4e8..36873adce6 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -151,7 +151,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi // phy_init_top(lte_frame_parms); //allocation - PHY_vars_UE->is_secondary_ue = 0;2 + PHY_vars_UE->is_secondary_ue = 0; PHY_vars_UE->lte_frame_parms = *lte_frame_parms; PHY_vars_eNB->lte_frame_parms = *lte_frame_parms; @@ -798,7 +798,7 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); - + bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",bler_fname); @@ -837,7 +837,6 @@ int main(int argc, char **argv) else sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_expcomp.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); - csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); if (csv_fd==NULL) { From e2d13c9762a712293cb938a4588eb568b19f0acf Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 13 Jan 2016 14:43:47 +0100 Subject: [PATCH 061/571] Revert "Experimanetal change in dlsch_channel_commensation_TM34. Will not work for more than 2 antennas." This reverts commit cbd30e62fab1b06de2ea3035f085ff4f2133fc03. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 873 +----------------- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 +- 2 files changed, 15 insertions(+), 870 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 6ba3d6abeb..d4983e262f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -237,10 +237,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], - lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, + lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, rballoc, symbol, subframe, @@ -1850,857 +1850,6 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, _m_empty(); } -#if 1 -void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *lte_ue_pdsch_vars, - PHY_MEASUREMENTS *phy_measurements, - int eNB_id, - unsigned char symbol, - unsigned char mod_order0, - unsigned char mod_order1, - int harq_pid, - int round, - MIMO_mode_t mimo_mode, - unsigned short nb_rb, - unsigned char output_shift0, - unsigned char output_shift1) { - -#if defined(__x86_64__) || defined(__i386__) - - unsigned short rb,Nre; - __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag0_128,*dl_ch_mag1_128,*dl_ch_mag0_128b,*dl_ch_mag1_128b,*rxdataF128,*rxdataF_comp0_128,*rxdataF_comp1_128, - *dl_ch00_128, *dl_ch01_128, *dl_ch10_128, *dl_ch11_128, *rxdataF0_128, *rxdataF1_128, *rxdataF_comp00_128, *rxdataF_comp01_128, - *rxdataF_comp10_128, *rxdataF_comp11_128; - unsigned char aarx=0,symbol_mod,pilots=0; - int precoded_signal_strength0=0,precoded_signal_strength1=0, precoded_signal_strength00=0, precoded_signal_strength01=0, - precoded_signal_strength10=0, precoded_signal_strength11=0; - int rx_power_correction; - - int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; - int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; - int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; - int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; - int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; - int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; - int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; - int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; - unsigned char *pmi_ext = lte_ue_pdsch_vars->pmi_ext; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) - pilots=1; - - rx_power_correction = 1; - - // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); - - if (mod_order0 == 4) { - QAM_amp0_128 = _mm_set1_epi16(QAM16_n1); - QAM_amp0_128b = _mm_setzero_si128(); - } else if (mod_order0 == 6) { - QAM_amp0_128 = _mm_set1_epi16(QAM64_n1); - QAM_amp0_128b = _mm_set1_epi16(QAM64_n2); - } - - if (mod_order1 == 4) { - QAM_amp1_128 = _mm_set1_epi16(QAM16_n1); - QAM_amp1_128b = _mm_setzero_si128(); - } else if (mod_order1 == 6) { - QAM_amp1_128 = _mm_set1_epi16(QAM64_n1); - QAM_amp1_128b = _mm_set1_epi16(QAM64_n2); - } - - //for (aarx=0;aarxnb_antennas_rx;aarx++) { - - // printf("symbol %d, rx antenna %d\n", symbol, aarx); - - dl_ch00_128 = (__m128i *)&dl_ch_estimates_ext[0][symbol*frame_parms->N_RB_DL*12]; // this is h11 - dl_ch01_128 = (__m128i *)&dl_ch_estimates_ext[1][symbol*frame_parms->N_RB_DL*12]; // this is h12 - dl_ch10_128 = (__m128i *)&dl_ch_estimates_ext[2][symbol*frame_parms->N_RB_DL*12]; // this is h21 - dl_ch11_128 = (__m128i *)&dl_ch_estimates_ext[3][symbol*frame_parms->N_RB_DL*12]; // this is h22 - - // dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 - // dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1 - // dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 - // dl_ch_mag1_128b = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 - rxdataF0_128 = (__m128i *)&rxdataF_ext[0][symbol*frame_parms->N_RB_DL*12]; // y0=h11*x1+h12*x2 - rxdataF1_128 = (__m128i *)&rxdataF_ext[1][symbol*frame_parms->N_RB_DL*12]; // y1=h21*x1 + h22*x2 - rxdataF_comp00_128 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; // comp x1 antenna 0 - rxdataF_comp01_128 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; // comp x1 antenna 1 - rxdataF_comp10_128 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; // comp x2 antenna 0 - rxdataF_comp11_128 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; // comp x2 antenna 1 - - for (rb=0; rb2) { - // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - - mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - - dl_ch_mag0_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag0_128b[0] = dl_ch_mag0_128[0]; - dl_ch_mag0_128[0] = _mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128); - dl_ch_mag0_128[0] = _mm_slli_epi16(dl_ch_mag0_128[0],1); - - // print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]); - - - dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag0_128b[1] = dl_ch_mag0_128[1]; - dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128); - dl_ch_mag0_128[1] = _mm_slli_epi16(dl_ch_mag0_128[1],1); - - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - - dl_ch_mag0_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag0_128b[2] = dl_ch_mag0_128[2]; - - dl_ch_mag0_128[2] = _mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128); - dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1); - } - - dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b); - dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1); - - // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]); - - dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b); - dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1); - - if (pilots==0) { - dl_ch_mag0_128b[2] = _mm_mulhi_epi16(dl_ch_mag0_128b[2],QAM_amp0_128b); - dl_ch_mag0_128b[2] = _mm_slli_epi16(dl_ch_mag0_128b[2],1); - } - } - - if (mod_order1>2) { - // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - - mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - - dl_ch_mag1_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag1_128b[0] = dl_ch_mag1_128[0]; - dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128); - dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1); - - // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]); - - dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag1_128b[1] = dl_ch_mag1_128[1]; - dl_ch_mag1_128[1] = _mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128); - dl_ch_mag1_128[1] = _mm_slli_epi16(dl_ch_mag1_128[1],1); - - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - - dl_ch_mag1_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag1_128b[2] = dl_ch_mag1_128[2]; - - dl_ch_mag1_128[2] = _mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128); - dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1); - } - - dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b); - dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1); - - // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]); - - dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b); - dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1); - - if (pilots==0) { - dl_ch_mag1_128b[2] = _mm_mulhi_epi16(dl_ch_mag1_128b[2],QAM_amp1_128b); - dl_ch_mag1_128b[2] = _mm_slli_epi16(dl_ch_mag1_128b[2],1); - } - } */ - - // Layer zero antenna 0 : we make conj(ch11)*y1 - mmtmpD0 = _mm_madd_epi16(dl_ch00_128[0],rxdataF0_128[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch00_128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[0]); - // print_ints("im",&mmtmpD1); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - // printf("Shift: %d\n",output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp00_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch0_128); - // print_shorts("pack:",rxdataF_comp0_128); - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch00_128[1],rxdataF0_128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch00_128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp00_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch0_128+1); - // print_shorts("pack:",rxdataF_comp0_128+1); - - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch00_128[2],rxdataF0_128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch00_128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp00_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch0_128+2); - // print_shorts("pack:",rxdataF_comp0_128+2); - - } - - // Layer zero antenna 1 : we make conj(ch21)*y2 - mmtmpD0 = _mm_madd_epi16(dl_ch10_128[0],rxdataF1_128[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch10_128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[0]); - // print_ints("im",&mmtmpD1); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - // printf("Shift: %d\n",output_shift); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp01_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch0_128); - // print_shorts("pack:",rxdataF_comp0_128); - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch10_128[1],rxdataF1_128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch10_128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp01_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch0_128+1); - // print_shorts("pack:",rxdataF_comp0_128+1); - - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch10_128[2],rxdataF1_128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch10_128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp01_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch0_128+2); - // print_shorts("pack:",rxdataF_comp0_128+2); - - } - - - - - // Layer one antenna 0 : we make conj(ch12)*y0 - mmtmpD0 = _mm_madd_epi16(dl_ch01_128[0],rxdataF0_128[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch01_128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp10_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch1_128); - // print_shorts("pack:",rxdataF_comp1_128); - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch01_128[1],rxdataF0_128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch01_128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp10_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch1_128+1); - // print_shorts("pack:",rxdataF_comp1_128+1); - - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch01_128[2],rxdataF0_128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch01_128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp10_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch1_128+2); - // print_shorts("pack:",rxdataF_comp1_128+2); - - } - - // Layer one antenna 1 : we make conj(ch22)*y2 - mmtmpD0 = _mm_madd_epi16(dl_ch11_128[0],rxdataF1_128[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch11_128[0],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[0]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - // print_ints("im(shift)",&mmtmpD1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); - rxdataF_comp11_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch1_128); - // print_shorts("pack:",rxdataF_comp1_128); - - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch11_128[1],rxdataF1_128[1]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch11_128[1],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF1_128[1]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp11_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch1_128+1); - // print_shorts("pack:",rxdataF_comp1_128+1); - - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch11_128[2],rxdataF1_128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch11_128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF0_128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rxdataF_comp11_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch1_128+2); - // print_shorts("pack:",rxdataF_comp1_128+2); - - dl_ch00_128+=3; - dl_ch01_128+=3; - dl_ch10_128+=3; - dl_ch11_128+=3; - //dl_ch_mag0_128+=3; - //dl_ch_mag1_128+=3; - //dl_ch_mag0_128b+=3; - //dl_ch_mag1_128b+=3; - rxdataF0_128+=3; - rxdataF1_128+=3; - rxdataF_comp00_128+=3; - rxdataF_comp01_128+=3; - rxdataF_comp10_128+=3; - rxdataF_comp11_128+=3; - } - else { - dl_ch00_128+=2; - dl_ch01_128+=2; - dl_ch10_128+=2; - dl_ch11_128+=2; - //dl_ch_mag0_128+=3; - //dl_ch_mag1_128+=3; - //dl_ch_mag0_128b+=3; - //dl_ch_mag1_128b+=3; - rxdataF0_128+=2; - rxdataF1_128+=2; - rxdataF_comp00_128+=2; - rxdataF_comp01_128+=2; - rxdataF_comp10_128+=2; - rxdataF_comp11_128+=2; - } - - } // rb loop - Nre = (pilots==0) ? 12 : 8; - - precoded_signal_strength00 = ((signal_energy_nodc(&dl_ch_estimates_ext[0][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[0])); - precoded_signal_strength01 = ((signal_energy_nodc(&dl_ch_estimates_ext[1][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[1])); - precoded_signal_strength0 = precoded_signal_strength00 + precoded_signal_strength01; - - precoded_signal_strength10 = ((signal_energy_nodc(&dl_ch_estimates_ext[2][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[2])); - precoded_signal_strength11 = ((signal_energy_nodc(&dl_ch_estimates_ext[3][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[3])); - precoded_signal_strength1 = precoded_signal_strength10 + precoded_signal_strength11; - - - phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,phy_measurements->n0_power_tot); - phy_measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,phy_measurements->n0_power_tot); - - // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, - // phy_measurements->precoded_cqi_dB[eNB_id][0]); - - _mm_empty(); - _m_empty(); - - #elif defined(__arm__) - - unsigned short rb,Nre; - unsigned char aarx,symbol_mod,pilots=0; - int precoded_signal_strength0=0,precoded_signal_strength1=0, rx_power_correction; - int16x4_t *dl_ch0_128,*rxdataF128; - int16x4_t *dl_ch1_128; - int16x8_t *dl_ch0_128b,*dl_ch1_128b; - - int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; - int16x8_t *dl_ch_mag0_128,*dl_ch_mag0_128b,*dl_ch_mag1_128,*dl_ch_mag1_128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp0_128,*rxdataF_comp1_128; - int16x8_t QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; - int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); - - int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; - int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; - int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; - int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; - int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; - int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; - int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; - int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; - - int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size - { nb_rb=1+(5*nb_rb/6); } - - else - { pilots=1; } - } - - rx_power_correction=1; - - if (mod_order0 == 4) { - QAM_amp0_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) - QAM_amp0_128b = vmovq_n_s16(0); - - } else if (mod_order0 == 6) { - QAM_amp0_128 = vmovq_n_s16(QAM64_n1); // - QAM_amp0_128b = vmovq_n_s16(QAM64_n2); - } - - if (mod_order1 == 4) { - QAM_amp1_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) - QAM_amp1_128b = vmovq_n_s16(0); - - } else if (mod_order1 == 6) { - QAM_amp1_128 = vmovq_n_s16(QAM64_n1); // - QAM_amp1_128b = vmovq_n_s16(QAM64_n2); - } - - // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); - - for (aarx=0; aarxnb_antennas_rx; aarx++) { - - - - dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128b = (int16x8_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag0_128 = (int16x8_t*)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag0_128b = (int16x8_t*)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag1_128 = (int16x8_t*)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag1_128b = (int16x8_t*)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp0_128 = (int16x8_t*)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp1_128 = (int16x8_t*)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; - - for (rb=0; rb2) { - // get channel amplitude if not QPSK - mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); - // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits - mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits - mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - - } - - dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b); - dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b); - dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128); - dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128); - - - if (pilots==0) { - dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b); - dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128); - } - } - - if (mod_order1>2) { - // get channel amplitude if not QPSK - mmtmpD0 = vmull_s16(dl_ch1_128[0], dl_ch1_128[0]); - // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits - mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits - mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - - } - - dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b); - dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b); - dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128); - dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128); - - - if (pilots==0) { - dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b); - dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128); - } - } - - mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]); - //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] - mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]); - //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); - //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); - //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp0_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); - mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp0_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - // second stream - mmtmpD0 = vmull_s16(dl_ch1_128[0], rxdataF128[0]); - mmtmpD1 = vmull_s16(dl_ch1_128[1], rxdataF128[1]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); - - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); - //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp1_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - mmtmpD0 = vmull_s16(dl_ch1_128[2], rxdataF128[2]); - mmtmpD1 = vmull_s16(dl_ch1_128[3], rxdataF128[3]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp1_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); - mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - mmtmpD0 = vmull_s16(dl_ch1_128[4], rxdataF128[4]); - mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - } - } - - - - Nre = (pilots==0) ? 12 : 8; - - // rx_antennas - } - - - Nre = (pilots==0) ? 12 : 8; - - precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); - - precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); - - phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,phy_measurements->n0_power_tot); - phy_measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,phy_measurements->n0_power_tot); - -#endif -} -#endif - - - - -#if 0 void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_PDSCH *lte_ue_pdsch_vars, PHY_MEASUREMENTS *phy_measurements, @@ -2763,8 +1912,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // printf("symbol %d, rx antenna %d\n", symbol, aarx); - dl_ch00_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 - dl_ch10_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h21 + dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 + dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 @@ -3390,7 +2539,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, #endif } -#endif + void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, unsigned char symbol, @@ -4972,9 +4121,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch0 = &dl_ch_estimates[aarx][5]; dl_ch1 = &dl_ch_estimates[2+aarx][5]; } - // printf ("antenna %d\n", aarx); - // print_shorts("From extraction ch0\n", dl_ch0 ); - // print_shorts("From extraction ch1\n", dl_ch1 ); + pmi_loc = pmi_ext; // pointers to extracted RX signals and channel estimates @@ -4982,7 +4129,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)]; - for (prb=0; prbN_RB_DL; prb++) { skip_half=0; @@ -5062,6 +4208,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } + /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; @@ -5362,15 +4509,13 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } dl_ch0_ext+=8; - dl_ch1_ext+=8; - + dl_ch1_ext+=8; rxF_ext+=8; } //pilots==1 } // if Middle PRB } // if odd PRB } // if rballoc==1 } // for prb - } // for aarx return(nb_rb/frame_parms->nb_antennas_rx); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 36873adce6..f38e9eb3c8 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_expcomp.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_avsn2_rho.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_expcomp.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_expcomp.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_avsn2_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From fa315a3115dbd58ac69de27a98f1c1c9ba24a3b8 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 13 Jan 2016 18:54:03 +0100 Subject: [PATCH 062/571] Fixing bug in passing arguments to dlsch_dual_stream_correlation, introducing dlsch_dual_stream_correlation_opposite --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 123 +++++++++++++++++- openair1/PHY/LTE_TRANSPORT/proto.h | 8 ++ openair1/SIMULATION/LTE_PHY/dlsim.c | 12 +- 3 files changed, 131 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index d4983e262f..d4eb4be68d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -468,7 +468,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + 0, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh0); @@ -476,14 +476,14 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //to be optimized (just take complex conjugate) - dlsch_dual_stream_correlation(frame_parms, + dlsch_dual_stream_correlation_opposite(frame_parms, symbol, nb_rb, - &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + 0, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); + // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); } @@ -2567,7 +2567,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); for (aarx=0; aarxnb_antennas_rx; aarx++) { - + //printf ("antenna %d", aarx); dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; if (dl_ch_estimates_ext_i == NULL) // TM3/4 @@ -2598,7 +2598,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // print_ints("c0",&mmtmpD2); // print_ints("c1",&mmtmpD3); dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - + //print_shorts("rho 0:",dl_ch_rho128); // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -2629,7 +2629,118 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + + dl_ch128+=3; + dl_ch128i+=3; + dl_ch_rho128+=3; + } else { + dl_ch128+=2; + dl_ch128i+=2; + dl_ch_rho128+=2; + } + } + + } + + _mm_empty(); + _m_empty(); + +#elif defined(__arm__) + +#endif +} + +void dlsch_dual_stream_correlation_opposite(LTE_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + unsigned short nb_rb, + int **dl_ch_estimates_ext, + int **dl_ch_estimates_ext_i, + int **dl_ch_rho_ext, + unsigned char output_shift) +{ + +#if defined(__x86_64__)||defined(__i386__) + + unsigned short rb; + __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + unsigned char aarx,symbol_mod,pilots=0; + + // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol); + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { + pilots=1; + } + + // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + //printf ("antenna %d", aarx); + + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + + if (dl_ch_estimates_ext_i == NULL) // TM3/4 + dl_ch128i = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + else + dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12]; + + dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + + + for (rb=0; rb Date: Wed, 13 Jan 2016 23:54:25 +0100 Subject: [PATCH 063/571] NULL pointer --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index d4eb4be68d..9320054592 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -468,7 +468,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - 0, + NULL, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh0); @@ -480,7 +480,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - 0, + NULL, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a356de4420..f4e52b0c3f 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_rho.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_rho.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_rho.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_rho_n.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_rho.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_rho_n.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From b00f64ed56ae7b2e6e59b72a22ff8b8abbefe440 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 14 Jan 2016 10:55:49 +0100 Subject: [PATCH 064/571] 1)Removing dlsch_dual_stream_correlation 2) Fixing bug in mrc_TM4 - removing loop over tx antennas. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 142 ++---------------- openair1/PHY/LTE_TRANSPORT/proto.h | 8 - openair1/SIMULATION/LTE_PHY/dlsim.c | 12 +- 3 files changed, 20 insertions(+), 142 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 9320054592..82c4b29556 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -468,7 +468,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - NULL, + &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh0); @@ -476,12 +476,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //to be optimized (just take complex conjugate) - dlsch_dual_stream_correlation_opposite(frame_parms, + dlsch_dual_stream_correlation(frame_parms, symbol, nb_rb, + &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - NULL, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); @@ -2598,7 +2598,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // print_ints("c0",&mmtmpD2); // print_ints("c1",&mmtmpD3); dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - //print_shorts("rho 0:",dl_ch_rho128); + // print_shorts("rho 0:",dl_ch_rho128); // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -2651,117 +2651,6 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, #endif } -void dlsch_dual_stream_correlation_opposite(LTE_DL_FRAME_PARMS *frame_parms, - unsigned char symbol, - unsigned short nb_rb, - int **dl_ch_estimates_ext, - int **dl_ch_estimates_ext_i, - int **dl_ch_rho_ext, - unsigned char output_shift) -{ - -#if defined(__x86_64__)||defined(__i386__) - - unsigned short rb; - __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; - unsigned char aarx,symbol_mod,pilots=0; - - // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol); - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - pilots=1; - } - - // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); - - for (aarx=0; aarxnb_antennas_rx; aarx++) { - //printf ("antenna %d", aarx); - - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - - if (dl_ch_estimates_ext_i == NULL) // TM3/4 - dl_ch128i = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - else - dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12]; - - dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - - - for (rb=0; rbrxdataF_comp0; int **rxdataF_comp1 =lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; - int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; + int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for first stream int **dl_ch_rho2_ext =lte_ue_pdsch_vars->dl_ch_rho2_ext; int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; @@ -2927,14 +2816,12 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (frame_parms->nb_antennas_rx>1) { - for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) { - - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[1][symbol*frame_parms->N_RB_DL*12]; // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) for (i=0;iN_RB_DL*12]; @@ -2980,7 +2866,7 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, //print_shorts("mrc mag128_i0b:",&dl_ch_mag128_i0b[i]); } } - } + _mm_empty(); _m_empty(); diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 66fc01098c..392e20f0be 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -952,14 +952,6 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_rho_ext, unsigned char output_shift); -void dlsch_dual_stream_correlation_opposite(LTE_DL_FRAME_PARMS *frame_parms, - unsigned char symbol, - unsigned short nb_rb, - int **dl_ch_estimates_ext, - int **dl_ch_estimates_ext_i, - int **dl_ch_rho_ext, - unsigned char output_shift); - void dlsch_channel_compensation_TM56(int **rxdataF_ext, int **dl_ch_estimates_ext, int **dl_ch_mag, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f4e52b0c3f..b1c659533f 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_mrc.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_mrc.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_mrc.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_rho_n.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_mrc.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_rho_n.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_pce_sh%d_d2_%d_mrc.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_rho_n.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_fix_sh%d_d2_%d_mrc.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 7b5165c70a80a525ba37f13b941a1f5ad43c5215 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 14 Jan 2016 21:05:56 +0100 Subject: [PATCH 065/571] Small change in log2_approx in demodulation --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 82c4b29556..bdc52ddd09 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -420,8 +420,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // LUT will be introduced with mcs-dependent shift avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],avg_1[0]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],avg_1[0]); //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); @@ -468,7 +468,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh0); @@ -479,7 +479,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_dual_stream_correlation(frame_parms, symbol, nb_rb, - &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); From 98b91e1d4c2f6ab42518d61dfe3a89b122385891 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 14 Jan 2016 22:14:24 +0100 Subject: [PATCH 066/571] Improving previous commit --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index bdc52ddd09..cb1ea58035 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -421,7 +421,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],avg_1[0]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],avg_1[0]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_0[0],avg_1[0]); //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); From f415d7118d02639c3cdcfa4479b9af4f81a4662c Mon Sep 17 00:00:00 2001 From: lukashov Date: Sat, 16 Jan 2016 12:49:58 +0100 Subject: [PATCH 067/571] Applying output shift on per-antenna basis in demodulation --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 74 +++++++++++-------- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 +-- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index cb1ea58035..add72453f3 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -420,8 +420,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // LUT will be introduced with mcs-dependent shift avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],avg_1[0]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_0[0],avg_1[0]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); @@ -432,8 +432,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // LUT will be introduced with mcs-dependent shift avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],avg_1[0]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_0[0],avg_1[0]); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); } @@ -464,7 +464,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, }*/ // compute correlation between signal and interference channels (rho12 and rho21) - dlsch_dual_stream_correlation(frame_parms, + dlsch_dual_stream_correlation(frame_parms,// this is doing h0'h1, needed for llr[1] symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -476,7 +476,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //to be optimized (just take complex conjugate) - dlsch_dual_stream_correlation(frame_parms, + dlsch_dual_stream_correlation(frame_parms, // this is doing h1'h0, needed for llr[0] symbol, nb_rb, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), @@ -1424,8 +1424,8 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { // amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); __m128i tmp0,tmp1; - //print_shorts("prec2A_TM4 ch0 (before):",ch0); - //print_shorts("prec2A_TM4 ch1 (before):",ch1); + // print_shorts("prec2A_TM4 ch0 (before):",ch0); + // print_shorts("prec2A_TM4 ch1 (before):",ch1); if (pmi == 0) { //[1 1;1 -1] tmp0 = ch0[0]; @@ -1439,7 +1439,7 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); tmp1 = _mm_shufflehi_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); ch0[0] = _mm_subs_epi16(tmp0,tmp1); - ch1[0] = _mm_adds_epi16(tmp0,tmp1); + ch1[0] = _mm_add_epi16(tmp0,tmp1); } //print_shorts("prec2A_TM4 ch0 (middle):",ch0); @@ -1450,11 +1450,11 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { //ch1[0] = _mm_mulhi_epi16(ch1[0],amp); //ch1[0] = _mm_slli_epi16(ch1[0],1); - //print_shorts("prec2A_TM4 ch0 (end):",ch0); - //print_shorts("prec2A_TM4 ch1 (end):",ch1); + ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 - + //print_shorts("prec2A_TM4 ch0 (end):",ch0); + //print_shorts("prec2A_TM4 ch1 (end):",ch1); _mm_empty(); _m_empty(); // print_shorts("prec2A_TM4 ch0 (end):",ch0); @@ -1871,6 +1871,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned char aarx=0,symbol_mod,pilots=0; int precoded_signal_strength0=0,precoded_signal_strength1=0; int rx_power_correction; + int output_shift; int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; @@ -1909,7 +1910,15 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } for (aarx=0;aarxnb_antennas_rx;aarx++) { - + + if (aarx==0) { + output_shift=output_shift0; + } + else { + output_shift=output_shift1; + } + + // printf("antenna %d\n", aarx); // printf("symbol %d, rx antenna %d\n", symbol, aarx); dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 @@ -1920,11 +1929,12 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1 dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 dl_ch_mag1_128b = (__m128i *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; //received signal on antenna of interest h11*x1+h12*x2 + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; //received signal on antenna of interest h11*x1+h12*x2 rxdataF_comp0_128 = (__m128i *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x1 on antenna of interest rxdataF_comp1_128 = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x2 on antenna of interest for (rb=0; rb Date: Sun, 17 Jan 2016 00:39:39 +0100 Subject: [PATCH 068/571] Playing with average channel level: avg_0[0] = max(avg_0[0],avg_1[0]); avg_1[0] = max(avg_0[1],avg_1[1]); taking this into account in correlation. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 141 +++++++++++++++++- openair1/PHY/LTE_TRANSPORT/proto.h | 9 ++ openair1/SIMULATION/LTE_PHY/dlsim.c | 12 +- 3 files changed, 150 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index add72453f3..45fb8599eb 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -464,24 +464,26 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, }*/ // compute correlation between signal and interference channels (rho12 and rho21) - dlsch_dual_stream_correlation(frame_parms,// this is doing h0'h1, needed for llr[1] + dlsch_dual_stream_correlationTM34(frame_parms,// this is doing h0'h1, needed for llr[1] symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0, + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); //to be optimized (just take complex conjugate) - dlsch_dual_stream_correlation(frame_parms, // this is doing h1'h0, needed for llr[0] + dlsch_dual_stream_correlationTM34(frame_parms, // this is doing h1'h0, needed for llr[0] symbol, nb_rb, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->log2_maxh0, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); @@ -2577,6 +2579,9 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); for (aarx=0; aarxnb_antennas_rx; aarx++) { + + + //printf ("antenna %d", aarx); dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; @@ -2661,6 +2666,128 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, #endif } + +void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + unsigned short nb_rb, + int **dl_ch_estimates_ext, + int **dl_ch_estimates_ext_i, + int **dl_ch_rho_ext, + unsigned char output_shift0, + unsigned char output_shift1) +{ + +#if defined(__x86_64__)||defined(__i386__) + + unsigned short rb; + __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + unsigned char aarx,symbol_mod,pilots=0; + int output_shift; + + // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol); + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { + pilots=1; + } + + // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); + + for (aarx=0; aarxnb_antennas_rx; aarx++) { + + if (aarx==0) { + output_shift=output_shift0; + } + else { + output_shift=output_shift1; + } + + //printf ("antenna %d", aarx); + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + + if (dl_ch_estimates_ext_i == NULL) // TM3/4 + dl_ch128i = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + else + dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12]; + + dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + + + for (rb=0; rb Date: Sun, 17 Jan 2016 02:29:14 +0100 Subject: [PATCH 069/571] avg_0[0] = max(avg_0[0],avg_0[1]); avg_1[0] = max(avg_1[0],avg_1[1]); --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 42 +++++++++---------- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 +++--- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 45fb8599eb..619c31f841 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -464,27 +464,25 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, }*/ // compute correlation between signal and interference channels (rho12 and rho21) - dlsch_dual_stream_correlationTM34(frame_parms,// this is doing h0'h1, needed for llr[1] + dlsch_dual_stream_correlation(frame_parms,// this is doing h0'h1, needed for llr[1] symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->log2_maxh0, - lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); //to be optimized (just take complex conjugate) - dlsch_dual_stream_correlationTM34(frame_parms, // this is doing h1'h0, needed for llr[0] + dlsch_dual_stream_correlation(frame_parms, // this is doing h1'h0, needed for llr[0] symbol, nb_rb, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->log2_maxh0, - lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); @@ -1913,12 +1911,12 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, for (aarx=0;aarxnb_antennas_rx;aarx++) { - if (aarx==0) { + /* if (aarx==0) { output_shift=output_shift0; } else { output_shift=output_shift1; - } + } */ // printf("antenna %d\n", aarx); // printf("symbol %d, rx antenna %d\n", symbol, aarx); @@ -2093,10 +2091,10 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // print_ints("im",&mmtmpD1); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); // printf("Shift: %d\n",output_shift); // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2116,8 +2114,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2135,8 +2133,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2160,9 +2158,9 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); // print_ints("re(shift)",&mmtmpD0); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2181,8 +2179,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -2200,8 +2198,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); @@ -3314,8 +3312,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, (((int*)&avg_1_128D)[3])/(nb_rb*nre); // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); } -avg_0[0] = max(avg_0[0],avg_1[0]); -avg_1[0] = max(avg_0[1],avg_1[1]); +avg_0[0] = max(avg_0[0],avg_0[1]); +avg_1[0] = max(avg_1[0],avg_1[1]); //avg_0[0]=max (avg_0[0], avg_0[1]); // avg_0[0] = avg_0[0] + avg_0[1]; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 273d897ca1..93f3e598f1 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_maxeant.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_maxamant.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_maxeant.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_maxamant.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_maxeant.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_maxamant.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_maxeant.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_maxamant.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_maxeant.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_maxamant.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_maxeant.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_maxamant.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From b6ac32b0dbf1c23837d0ecb919987e24926d3ca0 Mon Sep 17 00:00:00 2001 From: lukashov Date: Sun, 17 Jan 2016 16:50:53 +0100 Subject: [PATCH 070/571] Chosing the max channel among the four and passing same shift everywhere. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3 ++- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 619c31f841..07481c282c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -3314,7 +3314,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, } avg_0[0] = max(avg_0[0],avg_0[1]); avg_1[0] = max(avg_1[0],avg_1[1]); - +avg_0[0]= max(avg_0[0], avg_1[0]); +avg_1[0]=avg_0[0]; //avg_0[0]=max (avg_0[0], avg_0[1]); // avg_0[0] = avg_0[0] + avg_0[1]; // avg_1[0] = avg_1[0] + avg_1[1]; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 93f3e598f1..dcef7e0848 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_maxamant.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_maxch.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_maxamant.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_maxch.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_maxamant.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_maxch.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_maxamant.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_maxch.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_maxamant.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_maxch.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_maxamant.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_maxch.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From dcf4473284f7eb563c997d574817022bb5ffdf8e Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 18 Jan 2016 18:04:54 +0100 Subject: [PATCH 071/571] Coming back to avg_0[0] = avg_0[0] + avg_0[1]; avg_1[0] = avg_1[0] + avg_1[1]; avg_0[0] = max (avg_0[0], avg_1[0]); avg_1[0] = avg_0[0]; --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 19 ++++++++++--------- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 07481c282c..7846aa284c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -3216,6 +3216,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; //clear average level + // avg_0_128D = _mm_setzero_si128(); + // avg_1_128D = _mm_setzero_si128(); avg_0[0] = 0; avg_0[1] = 0; avg_1[0] = 0; @@ -3312,14 +3314,15 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, (((int*)&avg_1_128D)[3])/(nb_rb*nre); // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); } -avg_0[0] = max(avg_0[0],avg_0[1]); -avg_1[0] = max(avg_1[0],avg_1[1]); -avg_0[0]= max(avg_0[0], avg_1[0]); -avg_1[0]=avg_0[0]; - //avg_0[0]=max (avg_0[0], avg_0[1]); -// avg_0[0] = avg_0[0] + avg_0[1]; -// avg_1[0] = avg_1[0] + avg_1[1]; +//avg_0[0] = max(avg_0[0],avg_0[1]); +//avg_1[0] = max(avg_1[0],avg_1[1]); +//avg_0[0]= max(avg_0[0], avg_1[0]); + avg_0[0] = avg_0[0] + avg_0[1]; + avg_1[0] = avg_1[0] + avg_1[1]; + avg_0[0] = max (avg_0[0], avg_1[0]); + avg_1[0] = avg_0[0]; + _mm_empty(); _m_empty(); @@ -4102,8 +4105,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, skip_half=2; } - - if (rb_alloc_ind==1) { #ifdef DEBUG_DLSCH_DEMOD printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index dcef7e0848..3edd17c6e3 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_maxch.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_maxnormeq.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_maxch.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_maxnormeq.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_maxch.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_maxnormeq.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_maxch.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_maxnormeq.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_maxch.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_maxnormeq.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_maxch.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_maxnormeq.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From e60c6e3f84ea798aa5053dfb51606c8a5ede242c Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 18 Jan 2016 21:09:59 +0100 Subject: [PATCH 072/571] This commit is to generate TM4 awgn with perfect channel estimation with the right precoder. To be reverted after. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 13 +++++++------ openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 7846aa284c..893a00adcb 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -1963,11 +1963,11 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); + prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); if (pilots==0) { - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); } } @@ -3238,6 +3238,7 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, avg_0_128D = _mm_setzero_si128(); avg_1_128D = _mm_setzero_si128(); for (rb=0; rbharq_processes[harq_pid], pilots, ((pilots) ? amp_rho_b : amp_rho_a), - get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), - qam_table_s0, + //get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), + 0, + qam_table_s0, qam_table_s1, &re_allocated, skip_dc, From 56c660dbe9a3086178a373d4ad2acef8d4e36c19 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 18 Jan 2016 22:55:47 +0100 Subject: [PATCH 073/571] Undoing previos commit. Previous commit is kept to generate TM4 PCE AWGN plots with the right precoder. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 13 ++++++------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 5 ++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 893a00adcb..7846aa284c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -1963,11 +1963,11 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { - prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); if (pilots==0) { - prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); } } @@ -3238,7 +3238,6 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, avg_0_128D = _mm_setzero_si128(); avg_1_128D = _mm_setzero_si128(); for (rb=0; rbharq_processes[harq_pid], pilots, ((pilots) ? amp_rho_b : amp_rho_a), - //get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), - 0, - qam_table_s0, + get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), + qam_table_s0, qam_table_s1, &re_allocated, skip_dc, From c7d2bbe5137e2abe316eb1be6fc5f199da549375 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 20 Jan 2016 16:08:54 +0100 Subject: [PATCH 074/571] avg_0[0] = avg_0[0] + avg_0[1]; avg_1[0] = avg_1[0] + avg_1[1]; Diff per-layer shift --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 16 ++++++++-------- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 7846aa284c..5469ad815a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -1982,10 +1982,10 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // get channel amplitude if not QPSK mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); @@ -2004,7 +2004,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); @@ -2033,10 +2033,10 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // get channel amplitude if not QPSK mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); @@ -2054,7 +2054,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); @@ -3320,8 +3320,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, avg_0[0] = avg_0[0] + avg_0[1]; avg_1[0] = avg_1[0] + avg_1[1]; - avg_0[0] = max (avg_0[0], avg_1[0]); - avg_1[0] = avg_0[0]; + // avg_0[0] = max (avg_0[0], avg_1[0]); + // avg_1[0] = avg_0[0]; _mm_empty(); _m_empty(); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3edd17c6e3..b8c018c267 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_maxnormeq.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_sumnormdif.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_maxnormeq.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_sumnormdif.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_maxnormeq.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_sumnormdif.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_maxnormeq.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_sumnormdif.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_maxnormeq.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_sumnormdif.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_maxnormeq.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_sumnormdif.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From c453384e977ff8babd8e26ff1fc9d0be8689ece6 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 20 Jan 2016 16:29:07 +0100 Subject: [PATCH 075/571] Small improvement in correlation --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 5469ad815a..85f550c896 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -470,7 +470,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); @@ -482,7 +482,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); From 9410e893103e50acc1d81d75bb556cb447ea6972 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 22 Jan 2016 11:52:51 +0100 Subject: [PATCH 076/571] Small change in measurements: while calculating pmi take into account ch_12[1] as well. --- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 25 +++++++++++++++++-- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 6 +++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 +-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index b43fc8b9ef..e0d285df03 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -577,6 +577,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, } for (aarx=0; aarxnb_antennas_rx; aarx++) { + //printf("aarx=%d", aarx); // skip the first 4 RE due to interpolation filter length of 5 (not possible to skip 5 due to 128i alignment, must be multiple of 128bit) #if defined(__x86_64__) || defined(__i386__) @@ -634,9 +635,29 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, // print_ints("mm_madd_epi16",&mmtmpPMI1); // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit) pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0); - // print_ints(" pmi128_re",&pmi128_re); + // print_ints(" pmi128_re 0",&pmi128_re); pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); - // print_ints(" pmi128_im",&pmi128_im); + // print_ints(" pmi128_im 0 ",&pmi128_im); + + mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0); + mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1); + + mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]); + // print_ints("re",&mmtmpPMI0); + mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1)); + // print_ints("_mm_shufflelo_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1)); + // print_ints("_mm_shufflehi_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate); + // print_ints("_mm_sign_epi16",&mmtmpPMI1); + mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[1]); + // print_ints("mm_madd_epi16",&mmtmpPMI1); + // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit) + pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0); + // print_ints(" pmi128_re 1",&pmi128_re); + pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); + //print_ints(" pmi128_im 1 ",&pmi128_im); + #elif defined(__arm__) mmtmpPMI0 = vmull_s16(((int16x4_t*)dl_ch0_128)[0], ((int16x4_t*)dl_ch1_128)[0]); diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 03f0d97cf5..d04ba7a521 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5877,14 +5877,16 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) else if (rank==1) { for (aarx=0; aarxnb_antennas_rx; aarx++) { pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; + //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]); pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; + //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); } - if (((pmi_re > pmi_im) && (pmi_re > -pmi_im)) || ((pmi_re < pmi_im) && (pmi_re < -pmi_im))) + if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re < pmi_im) && (pmi_re < -pmi_im))) pmiq = PMI_2A_R1_11; else pmiq = PMI_2A_R1_1j; - // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); + // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); // printf("subband %d, pmi%d \n",i,pmiq); //According to Section 7.2.4 of 36.213 diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index b8c018c267..b440057fd7 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_pce_sh%d_d2_%d_sumnormdif.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_d2_%d_sumnormdif_ms.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_ab_sh%d_d2_%d_sumnormdif.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_d2_%d_sumnormdif_ms.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From bca0b4067930bbf5d591fe1dfbca83c8e626f98d Mon Sep 17 00:00:00 2001 From: lukashov Date: Sun, 24 Jan 2016 16:44:33 +0100 Subject: [PATCH 077/571] Small changes in precoder to max MI 1stream --- openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index e0d285df03..0e01a28c5f 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -639,7 +639,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); // print_ints(" pmi128_im 0 ",&pmi128_im); - mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0); + /* mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0); mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1); mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]); @@ -656,7 +656,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue, pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0); // print_ints(" pmi128_re 1",&pmi128_re); pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1); - //print_ints(" pmi128_im 1 ",&pmi128_im); + //print_ints(" pmi128_im 1 ",&pmi128_im);*/ #elif defined(__arm__) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index d04ba7a521..ac0604e60f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5881,7 +5881,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); } - if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re < pmi_im) && (pmi_re < -pmi_im))) + if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re >= pmi_im) && (pmi_re <= -pmi_im))) pmiq = PMI_2A_R1_11; else pmiq = PMI_2A_R1_1j; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index b440057fd7..36c61aac3b 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_sumnormdif.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_sumnormdifprec.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_sumnormdif.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_sumnormdifprec.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_sumnormdif.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_sumnormdifprec.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_sumnormdif.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_sumnormdifprec.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_d2_%d_sumnormdif_ms.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_d2_%d_sumnormdifprec.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_d2_%d_sumnormdif_ms.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_d2_%d_sumnormdifprec.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From f922b493a66cf7407e0a776e4ea0c199113541b1 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 22 Feb 2016 22:43:47 +0100 Subject: [PATCH 078/571] Bug in modulation.c with new qam tables. Error floor for 16QAM and 64QAM. Going back to old ones till fix the bug. --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 28 +++++++++++-------- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++---- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index dd6d26668b..2084420f73 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -832,9 +832,10 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj=*jj+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));//>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));//>>15); - + //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));//>>15); + //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));//>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; @@ -870,9 +871,10 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam64_table_offset_im+=1; *jj=*jj+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));//>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));//>>15); - + //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));//>>15); + //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));//>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; @@ -925,9 +927,10 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj2=*jj2+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re]));//>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im]));//>>15); - + //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re]));//>>15); + //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im]));//>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; @@ -963,9 +966,10 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam64_table_offset_im+=1; *jj2=*jj2+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re]));//>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im]));//>>15); - + //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re]));//>>15); + //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im]));//>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 36c61aac3b..829306ba02 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_sumnormdifprec.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_d2_sumnormdifprec.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_d2_sumnormdifprec.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_d2_sumnormdifprec.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_d2_%d_sumnormdifprec.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_d2_%d_sumnormdifprec.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 193ab717faddeefbef25d231d1fad81a3b026c2b Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 22 Feb 2016 22:49:34 +0100 Subject: [PATCH 079/571] Fix channel level --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 85f550c896..008b2ebf8d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -3320,8 +3320,8 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, avg_0[0] = avg_0[0] + avg_0[1]; avg_1[0] = avg_1[0] + avg_1[1]; - // avg_0[0] = max (avg_0[0], avg_1[0]); - // avg_1[0] = avg_0[0]; + avg_0[0] = max (avg_0[0], avg_1[0]); + avg_1[0] = avg_0[0]; _mm_empty(); _m_empty(); From dbf587a51564476500ac75401ec00aacef4b7d8d Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 22 Feb 2016 23:39:36 +0100 Subject: [PATCH 080/571] Adding different shifts for CWs coming from dif constellations --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 8 ++++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 008b2ebf8d..4531ea919b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -418,8 +418,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (rx_type>rx_standard) { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; + avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift0; + avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift1; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); @@ -430,8 +430,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; + avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift0; + avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift1; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 829306ba02..76fd6d7891 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift0, interf_unaw_shift1); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift0, interf_unaw_shift1); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift0, interf_unaw_shift1); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift0, interf_unaw_shift1); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0, interf_unaw_shift1, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0, interf_unaw_shift1, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 0022ccf790da5966cf8a9c77df890c470e88b1b8 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 29 Feb 2016 12:32:51 +0100 Subject: [PATCH 081/571] Revert "Adding different shifts for CWs coming from dif constellations" Streams must have the same shift, otherwise error floor. O This reverts commit dbf587a51564476500ac75401ec00aacef4b7d8d. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 8 ++++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 4531ea919b..008b2ebf8d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -418,8 +418,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (rx_type>rx_standard) { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift0; - avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift1; + avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); @@ -430,8 +430,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift0; - avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift1; + avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 76fd6d7891..829306ba02 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -790,14 +790,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift0, interf_unaw_shift1); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift0, interf_unaw_shift1); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift0, interf_unaw_shift1); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift0, interf_unaw_shift1); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_sumnormdifpm.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -833,9 +833,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0, interf_unaw_shift1, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift0, interf_unaw_shift1, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_sumnormdifpm.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 04b07f8bd3b087803701e312d04662f338c02b47 Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 1 Mar 2016 11:08:45 +0100 Subject: [PATCH 082/571] Fixing bug with dl_offset in TM3. Always must be 1. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index ac0604e60f..f4fce719ad 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1621,9 +1621,6 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0->rnti = rnti; dlsch1->rnti = rnti; - // dlsch0_harq->dl_power_off = 1; - // dlsch1_harq->dl_power_off = 1; - break; case format2A: @@ -5376,8 +5373,6 @@ int generate_ue_dlsch_params_from_dci(int frame, case 0: // one layer per transport block dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->dl_power_off = 0; //apply power offset - dlsch1_harq->dl_power_off = 0; //apply power offset dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; @@ -5386,8 +5381,6 @@ int generate_ue_dlsch_params_from_dci(int frame, case 1: // one-layers on TB 0, two on TB 1 dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->dl_power_off = 0; //apply power offset - dlsch1_harq->dl_power_off = 0; //apply power offset dlsch1_harq->Nl = 2; dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; break; @@ -5396,8 +5389,6 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->Nl = 2; - dlsch0_harq->dl_power_off = 0; //apply power offset - dlsch1_harq->dl_power_off = 0; //apply power offset if (frame_parms->N_RB_DL <= 56) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; @@ -5442,8 +5433,6 @@ int generate_ue_dlsch_params_from_dci(int frame, case 1: // two-layers on TB 0 dlsch1_harq->mimo_mode = LARGE_CDD; dlsch1_harq->Nl = 2; - dlsch0_harq->dl_power_off = 1; //apply power offset - dlsch1_harq->dl_power_off = 0; //apply power offset dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; break; From d988214e0140c9b5f540e03527196eae3dd24e32 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 1 Mar 2016 11:40:34 +0100 Subject: [PATCH 083/571] debug info for power control --- openair1/PHY/LTE_TRANSPORT/power_control.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 0692165164..471e85b794 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -29,7 +29,7 @@ #include "PHY/defs.h" #include "PHY/impl_defs_lte.h" -//#define DEBUG_PC 1 +#define DEBUG_PC 1 /* double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0}, @@ -64,7 +64,7 @@ double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); #ifdef DEBUG_PC - printf("sqrt_rho_a(eNB):%d\n",dlsch_eNB->sqrt_rho_a); + printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a); #endif return(rho_a_dB); @@ -92,7 +92,7 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); #ifdef DEBUG_PC - printf("sqrt_rho_b(eNB):%d\n",dlsch_eNB->sqrt_rho_b); + printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pdsch_config_common->p_b,ratioPB[1][pdsch_config_common->p_b],dlsch_eNB->sqrt_rho_b); #endif return(rho_b_dB); } @@ -121,7 +121,7 @@ double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); #ifdef DEBUG_PC - printf("sqrt_rho_a(ue):%d\n",dlsch_ue->sqrt_rho_a); + printf("UE: p_a=%d, value=%f, dl_power_off=%d, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dl_power_off,dlsch_ue->sqrt_rho_a); #endif return(rho_a_dB); @@ -149,7 +149,7 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, dlsch_ue->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); #ifdef DEBUG_PC - printf("sqrt_rho_b(ue):%d\n",dlsch_ue->sqrt_rho_b); + printf("UE: p_b=%d, n_ant=%d -> ratio=%f -> sqrt_rho_b=%d\n",pdsch_config_common->p_b, n_antenna_port,ratioPB[1][pdsch_config_common->p_b],dlsch_ue->sqrt_rho_b); #endif return(rho_b_dB); } From b46c6b700bae5067413f688b3f57543a8dc91c91 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 1 Mar 2016 12:08:59 +0100 Subject: [PATCH 084/571] previous bugfix for dl_power_off in TM3 was incomplete --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index f4fce719ad..b51e85006c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5361,8 +5361,6 @@ int generate_ue_dlsch_params_from_dci(int frame, if ((dlsch0->active==1) && (dlsch1->active==1)) { dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->dl_power_off = 0; //apply power offset - dlsch1_harq->dl_power_off = 0; //apply power offset } else { dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; From c1f495300805ce2ec377aa692233abe532fd10e3 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 2 Mar 2016 11:02:05 +0100 Subject: [PATCH 085/571] Fixing new modulation tables for TM4 and TM6. Now all modulation orders and combinations work and the maginutes are at appropriate level. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 41 ++++---- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 97 +++++++++---------- openair1/PHY/LTE_TRANSPORT/power_control.c | 4 +- openair1/PHY/impl_defs_top.h | 2 +- 4 files changed, 67 insertions(+), 77 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 008b2ebf8d..d736a2e4cf 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -600,37 +600,34 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh); - } else if (dlsch0_harq->dl_power_off==1) { + } + else if (dlsch0_harq->dl_power_off==1) { dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); - - /* compute new log2_maxh for effective channel */ + frame_parms, + dlsch_ue, + symbol, + nb_rb); + if (first_symbol_flag==1) { + dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_rb); +#ifdef DEBUG_PHY + LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]); +#endif - // effective channel of desired user is always stronger than interfering eff. channel - dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, - avg, - symbol, - nb_rb); - avgs = 0; + avgs = 0; for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) for (aarx=0;aarxnb_antennas_rx;aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; - - lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh++; - - //printf("log1_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 2084420f73..9e1c187774 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -718,16 +718,17 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj=*jj+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; @@ -756,16 +757,16 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam64_table_offset_im+=1; *jj=*jj+1; - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; @@ -801,13 +802,13 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, *jj = *jj + 1; // normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } break; @@ -832,17 +833,15 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj=*jj+1; - //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re]));//>>15); - //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im]));//>>15); - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } break; @@ -871,17 +870,15 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam64_table_offset_im+=1; *jj=*jj+1; - //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re]));//>>15); - //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im]));//>>15); - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } break; @@ -896,13 +893,13 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, *jj2 = *jj2 + 1; // normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } break; @@ -927,17 +924,15 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj2=*jj2+1; - //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re]));//>>15); - //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im]));//>>15); - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } break; @@ -966,17 +961,15 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam64_table_offset_im+=1; *jj2=*jj2+1; - //((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re]));//>>15); - //((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im]));//>>15); - ((int16_t*)&tmp_sample1)[0] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t*)&tmp_sample1)[1] = (int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; - ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } break; diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 471e85b794..492f15c218 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -29,7 +29,7 @@ #include "PHY/defs.h" #include "PHY/impl_defs_lte.h" -#define DEBUG_PC 1 +//#define DEBUG_PC /* double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0}, @@ -63,7 +63,7 @@ double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); -#ifdef DEBUG_PC +#if DEBUG_PC printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a); #endif diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index c84b7d3ece..51a9c50a4d 100755 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -207,7 +207,7 @@ #define ONE_OVER_SQRT2_Q15 23170 - +#define ONE_OVER_2_Q15 16384 // QAM amplitude definitions From 20cc8bc9f667ec4c75ea2f4e5c118d7b54c5dee4 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 3 Mar 2016 16:35:50 +0100 Subject: [PATCH 086/571] Fixing FDD for TM4 --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 13 ++++++++----- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 4 +--- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index efead973ae..9e56da1e74 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1586,7 +1586,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; dlsch0_harq->pmi_alloc = DL_pmi_single; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = DL_pmi_single; //this is actually never used, since the PMI for the second codeword is always the opposote of the first one + dlsch1_harq->pmi_alloc = DL_pmi_single; break; default: break; @@ -3337,7 +3337,8 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) break; case 25: - LOG_D(PHY,"DCI format2 2 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", + //LOG_D + printf("DCI format2 2 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, swap %d, TPMI %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, @@ -4772,8 +4773,10 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); } - - tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + if (frame_type == TDD) + tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + else + tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; if (tbswap == 0) { dlsch0 = dlsch[0]; @@ -5899,7 +5902,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) else pmiq = PMI_2A_R1_1j; - // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); + // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); // printf("subband %d, pmi%d \n",i,pmiq); //According to Section 7.2.4 of 36.213 diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 9e1c187774..6718c8d8e4 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -776,9 +776,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) { // this is for transmission mode 4 (1 layer) *re_allocated = *re_allocated + 1; - //amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); - amp = tmp_amp/2; - gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); + if (precoder_index==0) { precoder_index0 = 0; //[1 1] diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 7e59003dfd..23692b9f26 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1785,7 +1785,7 @@ n(tikz_fname,"w"); } printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); - if (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) { + if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); @@ -2771,7 +2771,7 @@ n(tikz_fname,"w"); } - if (transmission_mode==4 && (((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)){ + if (transmission_mode==4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); } From cdbc4baa583c05fc0bedaba87ce489ab229820f7 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 3 Mar 2016 23:00:12 +0100 Subject: [PATCH 087/571] Fixing rho for qpsk_qpsk in demodulation.c Still need to caliibrate shifts -J. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index d736a2e4cf..be1648f3eb 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -733,7 +733,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_qpsk_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), @@ -742,7 +742,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_qpsk_qpsk_llr(frame_parms, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), From c7828888abe50d9cac0d312f0a916d5056bd55f2 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 9 Mar 2016 20:36:06 +0100 Subject: [PATCH 088/571] small fix --- openair1/PHY/TOOLS/lte_phy_scope.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index a82934fc7f..fc6af36776 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -626,7 +626,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, pdsch_magb0 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0[0]; pdsch_magb1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[0]; - fl_freeze_form(form); + fl_freeze_form(form->lte_phy_scope_ue); // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { @@ -918,7 +918,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); */ - fl_unfreeze_form(form); + fl_unfreeze_form(form->lte_phy_scope_ue); fl_check_forms(); From 4573c0b962aedf2b2d574a05823a263aafff33c9 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 16 Mar 2016 16:05:09 +0100 Subject: [PATCH 089/571] Changes for SIC-receiver: 1. in dlsim.c: now we check for the receiver type and, if SIC, proceed through encoding, modulation, LLR compuattion and decoding of the decoded TB0. 2. Implementing routines for vector-vector multiplication and vector-vector subtraction 3. Adding some printouts for debuging purposes. 4. New functions: modulation_SIC, dlsch_qpsk_llr_SIC 5. In phy_scope.c: changing llr plotting: now for the length of coded_bits_per_cw. --- cmake_targets/CMakeLists.txt | 3 +- openair1/PHY/LTE_TRANSPORT/defs.h | 1 + .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 41 +- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 359 ++++++++++++++++++ openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 162 +++++++- openair1/PHY/LTE_TRANSPORT/power_control.c | 3 +- openair1/PHY/LTE_TRANSPORT/proto.h | 43 ++- openair1/PHY/TOOLS/cadd_sv.c | 2 +- openair1/PHY/TOOLS/cadd_vv.c | 33 +- openair1/PHY/TOOLS/cmult_sv.c | 10 +- openair1/PHY/TOOLS/cmult_vv.c | 78 +++- openair1/PHY/TOOLS/defs.h | 11 + openair1/PHY/TOOLS/lte_phy_scope.c | 16 +- openair1/SCHED/phy_procedures_lte_eNb.c | 1 - openair1/SIMULATION/LTE_PHY/dlsim.c | 350 +++++++++++++---- 15 files changed, 1018 insertions(+), 95 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 92505b9ef6..77d8703d95 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -123,7 +123,7 @@ endmacro(add_list_string_option) #################################################### # compilation flags ############################################# -#set (CMAKE_BUILD_TYPE "Debug") +set (CMAKE_BUILD_TYPE "Debug") if (CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() @@ -934,6 +934,7 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/INIT/lte_parms.c ${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c ${OPENAIR1_DIR}/PHY/TOOLS/file_output.c + ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c ${OPENAIR1_DIR}/PHY/TOOLS/log2_approx.c ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index a05b16d12a..bb38628669 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -742,6 +742,7 @@ typedef enum { rx_standard=0, rx_IC_single_stream, rx_IC_dual_stream, + rx_SIC_dual_stream } RX_type_t; typedef enum { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index be1648f3eb..4ac64e11e6 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -220,7 +220,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, printf("\n");*/ //#endif - if (rx_type==rx_IC_single_stream) { + if (rx_type >= rx_IC_single_stream) { if (eNB_id_in_connected_eNB) // we are in TM5 nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id_i], @@ -348,10 +348,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, nb_rb, lte_ue_pdsch_vars[eNB_id]->log2_maxh, phy_measurements); // log2_maxh+I0_shift - /* + if (symbol == 5) { write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - } */ + } if ((rx_type==rx_IC_single_stream) && (eNB_id_in_connected_eNB)) { @@ -452,8 +452,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, nb_rb, lte_ue_pdsch_vars[eNB_id]->log2_maxh0, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - /* - if (symbol == 5) { + + if (symbol == 5) { write_output("rxF_comp_d00.m","rxF_c_d00",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rxF_comp_d01.m","rxF_c_d01",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 @@ -461,7 +461,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, write_output("rxF_comp_d11.m","rxF_c_d11",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - }*/ + } + // compute correlation between signal and interference channels (rho12 and rho21) dlsch_dual_stream_correlation(frame_parms,// this is doing h0'h1, needed for llr[1] @@ -485,6 +486,16 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); + + if (symbol == 5) { + + write_output("rho0_0.m","rho0_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + write_output("rho2_0.m","rho2_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rho0_1.m.m","rho0_1",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rho2_1.m","rho2_1",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM + + + } } else { @@ -664,6 +675,15 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, 1); + + + if (symbol == 5) { + + write_output("rho0_mrc.m","rho0_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + write_output("rho2_mrc.m","rho2_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + } + + } } else { @@ -728,7 +748,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128); } - else if ((rx_type==rx_IC_single_stream) || (rx_type==rx_IC_dual_stream)) { + else if (rx_type >= rx_IC_single_stream) { if (dlsch1_harq->Qm == 2) { dlsch_qpsk_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, @@ -4705,8 +4725,13 @@ void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per */ sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round); sprintf(vname,"dl_rho_r%d_%d",eNB_id,round); - write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0][0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); + sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round); + sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round); + write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); + + sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round); write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index a4211ad3d6..78590b3017 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -39,6 +39,7 @@ */ #include "PHY/defs.h" +#include "PHY/TOOLS/defs.h" #include "PHY/extern.h" #include "defs.h" #include "extern.h" @@ -684,6 +685,99 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, return(0); } +int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + mod_sym_t **sic_buffer, + int **rho_i, + short *dlsch_llr, + uint8_t num_pdcch_symbols, + uint16_t nb_rb, + uint16_t pbch_pss_sss_adjust, + LTE_UE_DLSCH_t *dlsch0) +{ + + int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; + int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; + int16_t clean_x1[2*frame_parms->N_RB_DL*12]; + uint16_t amp_tmp; + uint16_t *llr16=(uint16_t*)dlsch_llr; + int i, len, nsymb; + uint8_t symbol, symbol_mod; + //uint8_t pilots; + int len_acc=0; + uint16_t *sic_data; + + nsymb = (frame_parms->Ncp==0) ? 14:12; + + for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]; + int16_t *rho_1=(int16_t*)&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]; + sic_data = (uint16_t*)&sic_buffer[0][((int16_t)len_acc)]; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) //pilots=1 + amp_tmp=dlsch0->sqrt_rho_b; + else //pilots=0 + amp_tmp=dlsch0->sqrt_rho_a; + + // printf("amp_tmp=%d\n", amp_tmp); + + if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { + if (frame_parms->mode1_flag==0) + len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3); + else + len = (nb_rb*10) - (5*pbch_pss_sss_adjust/6); + } else { + len = (nb_rb*12) - pbch_pss_sss_adjust; + } + + len_acc+=len; //accumulated length; this is done because in sic_buffer we have only data symbols + + multadd_complex_vector_real_scalar((int16_t *)sic_data, + amp_tmp, + (int16_t *)rho_amp_x0, + 1, + len); + + printf ("Got x0*rho_a\n"); + + mult_cpx_vector((int16_t *)rho_amp_x0, + (int16_t *)rho_1, + (int16_t*)rho_rho_amp_x0, + len, + 13); + + write_output("rho_rho.m","rho2", rho_rho_amp_x0,len,1,1); + printf ("Computed rho*rho_a*x0\n"); + + sub_cpx_vector16((int16_t *)rxF, + (int16_t *)rho_rho_amp_x0, + //(int16_t *)clean_x1, + (int16_t *)rxF, + len*2); + + write_output("clean_x1.m","x1", clean_x1,len,1,1); + printf ("Interference removed \n"); + + printf("dlsch_qpsk_llr_SIC: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); + + + //this is for QPSK only!!! + for (i=0; i=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; +#endif + if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + } else { + len = nb_rb*12 - pbch_pss_sss_adjust; + } + + // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE) + if (first_symbol_flag == 1) + *llr32p = dlsch_llr + (len<<2); + else + *llr32p += (len<<2); + + len_mod4 = len&3; + len>>=2; // length in quad words (4 REs) + len+=(len_mod4==0 ? 0 : 1); + + for (i=0; iN_RB_DL*12)]; + __m128i *ch_mag; + __m128i llr128[2]; + uint32_t *llr32; +#elif defined(__arm__) + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + int16x8_t *ch_mag; + int16x8_t xmm0; + int16_t *llr16; +#endif + + + int i,len; + unsigned char symbol_mod,len_mod4=0; + + #if defined(__x86_64__) || defined(__i386__) if (first_symbol_flag==1) { llr32 = (uint32_t*)dlsch_llr; @@ -958,6 +1170,153 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, } +void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + uint8_t symbol, + uint8_t first_symbol_flag, + uint16_t nb_rb, + uint16_t pbch_pss_sss_adjust, + int16_t **llr_save) +{ +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + __m128i *ch_mag,*ch_magb; +#elif defined(__arm__) + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; + int16x8_t *ch_mag,*ch_magb,xmm1,xmm2; +#endif + int i,len,len2; + unsigned char symbol_mod,len_mod4; + short *llr; + int16_t *llr2; + + if (first_symbol_flag==1) + llr = dlsch_llr; + else + llr = *llr_save; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + +#if defined(__x86_64__) || defined(__i386__) + ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; + ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; +#elif defined(__arm__) + ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; + ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; +#endif + if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + } else { + len = nb_rb*12 - pbch_pss_sss_adjust; + } + + llr2 = llr; + llr += (len*6); + + len_mod4 =len&3; + len2=len>>2; // length in quad words (4 REs) + len2+=(len_mod4?0:1); + + for (i=0; iNcp==0) { // normal prefix @@ -1559,7 +1561,8 @@ int dlsch_modulation(mod_sym_t **txdataF, if (rb_alloc_ind > 0) { // printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj); - allocate_REs_in_RB(frame_parms, + + allocate_REs_in_RB(frame_parms, txdataF, &jj, &jj2, @@ -1603,6 +1606,159 @@ int dlsch_modulation(mod_sym_t **txdataF, return (re_allocated); } + +int dlsch_modulation_SIC(mod_sym_t **sic_buffer, + int16_t amp, + uint32_t subframe_offset, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch0, + LTE_eNB_DLSCH_t *dlsch1, + int G) +{ + + uint8_t nsymb; + uint8_t harq_pid = dlsch0->current_harq_pid; + LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid]; + LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid]; + uint32_t i,jj,re_allocated; + uint16_t l,rb,re_offset; + uint32_t *rb_alloc = dlsch0_harq->rb_alloc; + uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs); + uint8_t *x0 = dlsch0_harq->e; + uint8_t qam64_table_offset_re = 0; + uint8_t qam64_table_offset_im = 0; + uint8_t qam16_table_offset_re = 0; + uint8_t qam16_table_offset_im = 0; + int16_t gain_lin_QPSK; + #ifdef DEBUG_DLSCH_MODULATION + uint8_t Nl0 = dlsch0_harq->Nl; + uint8_t Nl1; +#endif + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN); + + amp=1; //we do full scale here for SIC + gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)); + + jj = 0; + i = 0; + while (jj <= G-1) { + + re_allocated = re_allocated + 1; + + switch (mod_order0) { + case 2: //QPSK + /* TODO: handle more than 1 antenna */ + // printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + + ((int16_t*)&sic_buffer[0][i])[0] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i + + jj = jj + 1; + + ((int16_t*)&sic_buffer[0][i])[1] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} + + jj = jj + 1; + + // printf("%d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); + + i++; + + break; + + case 4: //16QAM + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; + + if (x0[jj] == 1) + qam16_table_offset_re+=2; + + jj=jj+1; + + if (x0[jj] == 1) + qam16_table_offset_im+=2; + + jj=jj+1; + + + if (x0[jj] == 1) + qam16_table_offset_re+=1; + + jj=jj+1; + + if (x0[jj] == 1) + qam16_table_offset_im+=1; + + jj=jj+1; + + + ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re]; + ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_im]; + + i++; + + break; + + case 6: //64QAM + + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + + if (x0[jj] == 1) + qam64_table_offset_re+=4; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_im+=4; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_re+=2; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_im+=2; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_re+=1; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_im+=1; + + jj=jj+1; + + + ((int16_t *)&sic_buffer[0][i])[0]+=qam64_table[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&sic_buffer[0][i])[0]+=qam64_table[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + i++; + + break; + } + + } + + +#ifdef DEBUG_DLSCH_MODULATION + msg("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset)); +#endif + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT); + + return (re_allocated); +} + + + int mch_modulation(mod_sym_t **txdataF, int16_t amp, uint32_t subframe_offset, @@ -1647,7 +1803,7 @@ int mch_modulation(mod_sym_t **txdataF, if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL - if (rb==(frame_parms->N_RB_DL>>1)) + if (rb==(frame_parms->N_RB_DL>>1)) skip_dc = 1; else skip_dc = 0; diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 492f15c218..d0d2742443 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -29,8 +29,7 @@ #include "PHY/defs.h" #include "PHY/impl_defs_lte.h" -//#define DEBUG_PC - +#define DEBUG_PC 0 /* double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0}, { 5.0/4.0,1.0,3.0/4.0,1.0/2.0}}; diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 91f3503904..17436bf869 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -185,7 +185,6 @@ int32_t allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, uint8_t skip_dc, uint8_t skip_half); - /** \fn int32_t dlsch_modulation(mod_sym_t **txdataF, int16_t amp, uint32_t sub_frame_offset, @@ -210,6 +209,15 @@ int32_t dlsch_modulation(mod_sym_t **txdataF, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch0, LTE_eNB_DLSCH_t *dlsch1); + +int32_t dlsch_modulation_SIC(mod_sym_t **sic_buffer, + int16_t amp, + uint32_t sub_frame_offset, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch0, + LTE_eNB_DLSCH_t *dlsch1, + int G); /* \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH. @param txdataF Table of pointers for frequency-domain TX signals @@ -710,6 +718,16 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, @param llr128p pointer to pointer to symbol in dlsch_llr */ +int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, + int **rxdataF_comp, + mod_sym_t **sic_buffer, + int **rho_i, + short *dlsch_llr, + uint8_t num_pdcch_symbols, + uint16_t nb_rb, + uint16_t pbch_pss_sss_adjust, + LTE_UE_DLSCH_t *dlsch0); + void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, int16_t *dlsch_llr, @@ -719,7 +737,6 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t nb_rb, uint16_t pbch_pss_sss_adjust, int16_t **llr128p); - /** \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms @param frame_parms Frame descriptor structure @@ -732,6 +749,17 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, @param nb_rb number of RBs for this allocation @param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs) */ +void dlsch_16qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + int32_t **dl_ch_mag, + uint8_t symbol, + uint8_t first_symbol_flag, + uint16_t nb_rb, + uint16_t pbch_pss_sss_adjust, + int16_t **llr128p); + + void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, int16_t *dlsch_llr, @@ -743,6 +771,17 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t pbch_pss_sss_adjust, short **llr_save); +void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + uint8_t symbol, + uint8_t first_symbol_flag, + uint16_t nb_rb, + uint16_t pbch_pss_sss_adjust, + short **llr_save); + /** \fn dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, int32_t **rxdataF_comp_i, diff --git a/openair1/PHY/TOOLS/cadd_sv.c b/openair1/PHY/TOOLS/cadd_sv.c index 2fa052f6c9..2902f2017a 100644 --- a/openair1/PHY/TOOLS/cadd_sv.c +++ b/openair1/PHY/TOOLS/cadd_sv.c @@ -65,7 +65,7 @@ int add_cpx_vector(short *x, int add_vector32_scalar(short *x, int alpha, short *y, - unsigned int N) + unsigned int { unsigned int i; // loop counter diff --git a/openair1/PHY/TOOLS/cadd_vv.c b/openair1/PHY/TOOLS/cadd_vv.c index 3bc349463e..8ab8f3a8e1 100644 --- a/openair1/PHY/TOOLS/cadd_vv.c +++ b/openair1/PHY/TOOLS/cadd_vv.c @@ -9,7 +9,7 @@ OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of + but WITTOOLHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -176,6 +176,37 @@ int add_cpx_vector32(short *x, return(0); } +int32_t sub_cpx_vector16(int16_t *x, + int16_t *y, + int16_t *z, + uint32_t N) +{ + unsigned int i; // loop counter + + __m128i *x_128; + __m128i *y_128; + __m128i *z_128; + + x_128 = (__m128i *)&x[0]; + y_128 = (__m128i *)&y[0]; + z_128 = (__m128i *)&z[0]; + + for(i=0; i<(N>>3); i++) { + z_128[0] = _mm_subs_epi16(x_128[0],y_128[0]); + + x_128++; + y_128++; + z_128++; + + } + + _mm_empty(); + _m_empty(); + return(0); +} + + + int add_real_vector64(short *x, short* y, short *z, diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index 31ad77be82..a30bbcd321 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -66,18 +66,23 @@ void multadd_complex_vector_real_scalar(int16_t *x, if (zero_flag == 1) for (n=0; n>2; n++) { + //print_shorts("x_128[n]=", &x_128[n]); + //print_shorts("alpha_128", &alpha_128); y_128[n] = mulhi_int16(x_128[n],alpha_128); + //print_shorts("y_128[n]=", &y_128[n]); //Q2.13 } else for (n=0; n>2; n++) { y_128[n] = adds_int16(y_128[n],mulhi_int16(x_128[n],alpha_128)); } - + _mm_empty(); _m_empty(); } + + void multadd_real_vector_complex_scalar(int16_t *x, int16_t *alpha, int16_t *y, @@ -387,7 +392,8 @@ int rotate_cpx_vector(int16_t *x, m3 = _mm_sra_epi32(m3,shift); // shift right by shift in order to compensate for the input amplitude y_128[0] = _mm_packs_epi32(m2,m3); // pack in 16bit integers with saturation [re im re im re im re im] -#elif defined(__arm__) + print_ints("y_128[0]=", &y_128[0]); + #elif defined(__arm__) ab_re0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bconj)[0]); ab_re1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bconj)[1]); diff --git a/openair1/PHY/TOOLS/cmult_vv.c b/openair1/PHY/TOOLS/cmult_vv.c index f970d33224..895bb4f166 100755 --- a/openair1/PHY/TOOLS/cmult_vv.c +++ b/openair1/PHY/TOOLS/cmult_vv.c @@ -34,8 +34,12 @@ #if defined(__x86_64__) || defined(__i386__) int16_t conjug[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ; +int16_t conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; + #define simd_q15_t __m128i #define simdshort_q15_t __m64 +#define set1_int16(a) _mm_set1_epi16(a) +#define setr_int16(a0, a1, a2, a3, a4, a5, a6, a7) _mm_setr_epi16(a0, a1, a2, a3, a4, a5, a6, a7 ) #elif defined(__arm__) int16_t conjug[4]__attribute__((aligned(16))) = {-1,1,-1,1} ; #define simd_q15_t int16x8_t @@ -71,6 +75,7 @@ int mult_cpx_conj_vector(int16_t *x1, #if defined(__x86_64__) || defined(__i386__) simd_q15_t tmp_re,tmp_im; simd_q15_t tmpy0,tmpy1; + #elif defined(__arm__) int32x4_t tmp_re,tmp_im; int32x4_t tmp_re1,tmp_im1; @@ -82,7 +87,7 @@ int mult_cpx_conj_vector(int16_t *x1, x2_128 = (simd_q15_t *)&x2[0]; y_128 = (simd_q15_t *)&y[0]; - + // we compute 4 cpx multiply for each loop for(i=0; i<(N>>2); i++) { #if defined(__x86_64__) || defined(__i386__) @@ -131,3 +136,74 @@ int mult_cpx_conj_vector(int16_t *x1, return(0); } + +int mult_cpx_vector(int16_t *x1, + int16_t *x2, + int16_t *y, + uint32_t N, + int output_shift) +{ + // Multiply elementwise x1 with x2. + // x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + // We assume x1 with a dinamic of 15 bit maximum + // + // x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + // We assume x2 with a dinamic of 14 bit maximum + /// + // y - output in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)| + // + // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; + // + // output_shift - shift to be applied to generate output + + uint32_t i; // loop counter + + simd_q15_t *x1_128; + simd_q15_t *x2_128; + simd_q15_t *y_128; + simd_q15_t tmp_re,tmp_im; + simd_q15_t tmpy0,tmpy1; + + + x1_128 = (simd_q15_t *)&x1[0]; + x2_128 = (simd_q15_t *)&x2[0]; + y_128 = (simd_q15_t *)&y[0]; + //print_shorts("x1_128:",&x1_128[0]); + //print_shorts("x2_128:",&x2_128[0]); + + //right shift by 13 while p_a * x0 and 15 while + // we compute 4 cpx multiply for each loop + for(i=0; i<(N>>2); i++) { + tmp_re = _mm_sign_epi16(*x1_128,*(__m128i*)&conjug2[0]); + //print_shorts("tmp_re1:",&tmp_re[i]); + tmp_re = _mm_madd_epi16(tmp_re,*x2_128); + //print_ints("tmp_re2:",&tmp_re[i]); + + tmp_im = _mm_shufflelo_epi16(*x1_128,_MM_SHUFFLE(2,3,0,1)); + //print_shorts("tmp_im1:",&tmp_im[i]); + tmp_im = _mm_shufflehi_epi16(tmp_im,_MM_SHUFFLE(2,3,0,1)); + //print_shorts("tmp_im2:",&tmp_im[i]); + tmp_im = _mm_madd_epi16(tmp_im, *x2_128); + //print_ints("tmp_im3:",&tmp_im[i]); + tmp_re = _mm_srai_epi32(tmp_re,output_shift); + //print_ints("tmp_re shifted:",&tmp_re[i]); + tmp_im = _mm_srai_epi32(tmp_im,output_shift); + //print_ints("tmp_im shifted:",&tmp_im[i]); + tmpy0 = _mm_unpacklo_epi32(tmp_re,tmp_im); + //print_ints("unpack lo :",&tmpy0[i]); + tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im); + //print_ints("mrc rho0:",&tmpy1[i]); + *y_128 = _mm_packs_epi32(tmpy0,tmpy1); + //print_shorts("*y_128:",&y_128[i]); + + x1_128++; + x2_128++; + y_128++; + } + + + _mm_empty(); + _m_empty(); + + return(0); +} diff --git a/openair1/PHY/TOOLS/defs.h b/openair1/PHY/TOOLS/defs.h index 963c1384b7..959469e382 100644 --- a/openair1/PHY/TOOLS/defs.h +++ b/openair1/PHY/TOOLS/defs.h @@ -131,6 +131,12 @@ int mult_cpx_conj_vector(int16_t *x1, uint32_t N, int output_shift); +int mult_cpx_vector(int16_t *x1, + int16_t *x2, + int16_t *y, + uint32_t N, + int output_shift); + // lte_dfts.c void init_fft(uint16_t size, uint8_t logsize, @@ -214,6 +220,11 @@ int32_t add_cpx_vector(int16_t *x, int16_t *y, uint32_t N); +int32_t sub_cpx_vector16(int16_t *x, + int16_t *y, + int16_t *z, + uint32_t N); + int32_t add_cpx_vector32(int16_t *x, int16_t *y, int16_t *z, diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index fc6af36776..d5f3f3f5e7 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -768,13 +768,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // PDSCH LLRs CW0 if (pdsch_llr != NULL) { - for (i=0; ipdsch_llr,0,coded_bits_per_codeword0/mod0); - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword0/mod0,"","",""); + fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword0); + fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword0,"","",""); } // PDSCH I/Q of MF Output @@ -836,13 +836,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // PDSCH LLRs CW1 if (pdsch_llr1 != NULL) { - for (i=0; ipdsch_llr1,0,coded_bits_per_codeword1/mod1); - fl_set_xyplot_data(form->pdsch_llr1,bit,llr,coded_bits_per_codeword1/mod1,"","",""); + fl_set_xyplot_xbounds(form->pdsch_llr1,0,coded_bits_per_codeword1); + fl_set_xyplot_data(form->pdsch_llr1,bit,llr,coded_bits_per_codeword1,"","",""); } // PDSCH I/Q of MF Output diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 375c0dcd1f..99122c4ea1 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -3873,4 +3873,3 @@ void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **phy_vars_eNB,u VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0); stop_meas(&phy_vars_eNB[0]->phy_proc); } - diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 1e6a5a3e5b..3efbdb6994 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -253,14 +253,17 @@ int main(int argc, char **argv) int TB0_active = 1; uint32_t perfect_ce = 0; - // LTE_DL_UE_HARQ_t *dlsch0_ue_harq; - // LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; + LTE_DL_UE_HARQ_t *dlsch0_ue_harq; + LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; uint8_t Kmimo; mod_sym_t **sic_buffer; + int8_t cw_to_decode_interf; + int8_t cw_to_decode_interf_free; + int8_t cw_non_sic; + int8_t cw_sic; FILE *proc_fd = NULL; char buf[64]; - uint8_t ue_category=4; uint32_t Nsoft; @@ -537,7 +540,7 @@ int main(int argc, char **argv) break; case 'u': rx_type = (RX_type_t) atoi(optarg); - if (rx_typerx_IC_dual_stream) { + if (rx_typerx_SIC_dual_stream) { printf("Unsupported rx type %d\n",rx_type); exit(-1); } @@ -639,7 +642,7 @@ int main(int argc, char **argv) printf("only standard rx available for TM1 and TM2\n"); exit(-1); } - if (((transmission_mode==5) || (transmission_mode==6)) && (rx_type == rx_IC_dual_stream)) { + if (((transmission_mode==5) || (transmission_mode==6)) && (rx_type > rx_IC_single_stream)) { printf("only standard rx or single stream IC available for TM5 and TM6\n"); exit(-1); } @@ -2816,7 +2819,8 @@ n(tikz_fname,"w"); &PHY_vars_eNB->lte_frame_parms, num_pdcch_symbols, PHY_vars_eNB->dlsch_eNB[k][0], - PHY_vars_eNB->dlsch_eNB[k][1]); + PHY_vars_eNB->dlsch_eNB[k][1] + ); stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); /* if (trials==0 && round==0) @@ -3438,34 +3442,42 @@ n(tikz_fname,"w"); } } } - - for (int cw=0; cwdlsch_ue[0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + + if (rx_type==rx_SIC_dual_stream){ + cw_to_decode_interf=1; + cw_to_decode_interf_free=1; + } + else { + cw_to_decode_interf=Kmimo; + } + + for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->Nl, + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, num_pdcch_symbols, 0,subframe); - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->G = coded_bits_per_codeword; - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->mcs); + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword; + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); if (n_frames==1) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw,coded_bits_per_codeword, - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid]->TBS); + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword, + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw); - sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw],coded_bits_per_codeword,1,0); - sprintf(fname,"dlsch_cw%d_e.m", cw); - sprintf(vname,"dlsch_cw%d_e", cw); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_non_sic); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword,1,0); + sprintf(fname,"dlsch_cw%d_e.m", cw_non_sic); + sprintf(vname,"dlsch_cw%d_e", cw_non_sic); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); uncoded_ber=0; for (i=0;idlsch_eNB[0][cw]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw][i]<0)) { + if (PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } @@ -3474,10 +3486,10 @@ n(tikz_fname,"w"); uncoded_ber/=coded_bits_per_codeword; avg_ber += uncoded_ber; - sprintf(fname,"cw%d_uncoded_ber_bit.m", cw); - sprintf(vname,"uncoded_ber_bit_cw%d", cw); + sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_non_sic); + sprintf(vname,"uncoded_ber_bit_cw%d", cw_non_sic); write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); - printf("cw %d, uncoded ber %f\n",cw,uncoded_ber); + printf("cw %d, uncoded ber %f\n",cw_non_sic,uncoded_ber); free(uncoded_ber_bit); @@ -3488,59 +3500,61 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, 0, - PHY_vars_UE->dlsch_ue[0][cw], + PHY_vars_UE->dlsch_ue[0][cw_non_sic], coded_bits_per_codeword, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw], - cw, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], + cw_non_sic, subframe<<1); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); ret = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw], - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid], + PHY_vars_UE->dlsch_ue[0][cw_non_sic], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid], subframe, - PHY_vars_UE->dlsch_ue[0][cw]->current_harq_pid, + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid, 1,llr8_flag); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - - - if (ret <= PHY_vars_UE->dlsch_ue[0][cw]->max_turbo_iterations ) { - - if (cw==0) { + + + if (ret <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { + printf("ret=%d\n", ret); + if (cw_non_sic==0) { avg_iter += ret; iter_trials++; } if (n_frames==1) { - printf("cw %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw,round,uncoded_ber); + printf("cw %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kminus; + for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; else - Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kplus; + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch_ue[0][cw]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); } #endif } - PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw]->current_harq_pid]->TBS; + PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->current_harq_pid]->TBS; + // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER + //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) if (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* //for (round = 0 ; round < PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round ; round++) { // we assume here that the second stream has a lower MCS and is thus more likely to be decoded // re-encoding of second stream - dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][1]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = LARGE_CDD; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; @@ -3554,11 +3568,11 @@ n(tikz_fname,"w"); dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][1]->active; - PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][1]->rnti; - PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid; + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][1]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->b, + dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, &PHY_vars_UE->lte_frame_parms, num_pdcch_symbols, PHY_vars_UE->dlsch_eNB[eNB_id], @@ -3630,36 +3644,242 @@ n(tikz_fname,"w"); //} } - } - else { - errs[cw][round]++; - if (cw==0) { - avg_iter += ret-1; + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + rx_type==rx_SIC_dual_stream) { + + for (round = 0 ; round < 1 ; round++) { + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + + dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; + dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; + dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; + dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; + dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; + dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; + dlsch0_eNB_harq->round = dlsch0_ue_harq->round; + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; + dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; + dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; + dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0, + subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats); + + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0, + subframe); + + dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword, + 0, + subframe<<1); + + re_allocated = dlsch_modulation_SIC(sic_buffer, + AMP, + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL, + coded_bits_per_codeword); + + write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); + write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + + + dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + dlsch0_eNB_harq->nb_rb, + adjust_G2(&PHY_vars_UE->lte_frame_parms,&dlsch0_eNB_harq->rb_alloc[0],2,subframe,num_pdcch_symbols), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + }// round + + write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); + + for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe); + + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword; + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); + + if (n_frames==1) { + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword, + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); + + // calculate uncoded BER + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_sic); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword,1,0); + sprintf(fname,"dlsch_cw%d_e.m", cw_sic); + sprintf(vname,"dlsch_cw%d_e", cw_sic); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + uncoded_ber=0; + for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } else + uncoded_ber_bit[i] = 0; + + uncoded_ber/=coded_bits_per_codeword; + avg_ber += uncoded_ber; + sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); + sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); + printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); + free(uncoded_ber_bit); + uncoded_ber_bit = NULL; + } + + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_ue[0][cw_sic], + coded_bits_per_codeword, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + cw_sic, + subframe<<1); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + + start_meas(&PHY_vars_UE->dlsch_decoding_stats); + ret = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][cw_sic], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, + 1,llr8_flag); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + + + if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { + if (cw_sic==1) { + avg_iter += ret; iter_trials++; } - if (cw==1) { + if (n_frames==1) { + printf("cw %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + } +#endif + } + + // PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw_sic]->current_harq_pid]->TBS; + + } //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + + else { + errs[cw_sic][round]++; + + if (cw_sic==0) { avg_iter += ret-1; iter_trials++; } if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { - printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw,round,uncoded_ber); + printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kminus; + for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; else - Kr = PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->Kplus; + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch_ue[0][cw]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + } +#endif + } //n_frames==1 + } //if (ret > PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + } //for (int cw_1=cw_to_decode_interf_free; cw_1dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) + else { + errs[cw_non_sic][round]++; + + if (cw_non_sic==0) { + avg_iter += ret-1; + iter_trials++; + } + + if (cw_non_sic==1) { + avg_iter += ret-1; + iter_trials++; + } + + if (n_frames==1) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); } #endif } From 127fa9ae377f59f564d0085fd9525ec3d482fcef Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 16 Mar 2016 18:10:07 +0100 Subject: [PATCH 090/571] Fixing bug in modulation_SIC: initially setting re_allocated to 0. --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 4fd659186d..30c8b69197 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1621,7 +1621,7 @@ int dlsch_modulation_SIC(mod_sym_t **sic_buffer, uint8_t harq_pid = dlsch0->current_harq_pid; LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid]; LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid]; - uint32_t i,jj,re_allocated; + uint32_t i,jj,re_allocated=0; uint16_t l,rb,re_offset; uint32_t *rb_alloc = dlsch0_harq->rb_alloc; uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs); From 291a7f1752f39b75c9caf48f4e38e25f4248af43 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 18 Mar 2016 12:00:49 +0100 Subject: [PATCH 091/571] 1. Changing precoder to minimize interference: testing simple channels. 2. Fixing confusion between dl_ch_rho2_ext and dl_ch_rho_ext[harq_pid][round]. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 56 +++++++++---------- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 19 ++++--- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 5 +- openair1/PHY/LTE_TRANSPORT/power_control.c | 2 +- openair1/PHY/TOOLS/cmult_vv.c | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 9 +-- 7 files changed, 51 insertions(+), 44 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 9e56da1e74..bed93103f8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5897,7 +5897,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); } - if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re >= pmi_im) && (pmi_re <= -pmi_im))) + if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re <= -pmi_im))) pmiq = PMI_2A_R1_11; else pmiq = PMI_2A_R1_1j; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 4ac64e11e6..cfb394ce8b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -453,7 +453,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh0, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - if (symbol == 5) { + /* if (symbol == 5) { write_output("rxF_comp_d00.m","rxF_c_d00",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rxF_comp_d01.m","rxF_c_d01",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 @@ -461,33 +461,33 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, write_output("rxF_comp_d11.m","rxF_c_d11",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } + } */ // compute correlation between signal and interference channels (rho12 and rho21) - dlsch_dual_stream_correlation(frame_parms,// this is doing h0'h1, needed for llr[1] + dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22 symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); //to be optimized (just take complex conjugate) - dlsch_dual_stream_correlation(frame_parms, // this is doing h1'h0, needed for llr[0] + dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21 symbol, nb_rb, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); - if (symbol == 5) { + /* if (symbol == 5) { write_output("rho0_0.m","rho0_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rho2_0.m","rho2_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 @@ -495,7 +495,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, write_output("rho2_1.m","rho2_1",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } + } */ } else { @@ -677,11 +677,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, 1); - if (symbol == 5) { + /* if (symbol == 5) { write_output("rho0_mrc.m","rho0_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rho2_mrc.m","rho2_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - } + } */ } @@ -753,7 +753,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_qpsk_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), @@ -762,7 +762,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_qpsk_qpsk_llr(frame_parms, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), @@ -774,7 +774,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), @@ -784,7 +784,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i dl_ch_mag_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), @@ -796,7 +796,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), @@ -806,7 +806,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i dl_ch_mag_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), @@ -831,7 +831,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), @@ -841,7 +841,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), @@ -854,7 +854,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), @@ -865,7 +865,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i dl_ch_mag_ptr, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), @@ -878,7 +878,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), @@ -889,7 +889,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, dl_ch_mag_ptr, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), @@ -915,7 +915,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), @@ -925,7 +925,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), @@ -938,7 +938,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), @@ -949,7 +949,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i dl_ch_mag_ptr, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), @@ -962,7 +962,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, rxdataF_comp_ptr,//i lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), @@ -973,7 +973,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i dl_ch_mag_ptr, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->llr[1], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 78590b3017..ca8b38c3fd 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -740,7 +740,8 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, 1, len); - printf ("Got x0*rho_a\n"); + + // printf ("Got x0*rho_a\n"); mult_cpx_vector((int16_t *)rho_amp_x0, (int16_t *)rho_1, @@ -749,30 +750,32 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, 13); write_output("rho_rho.m","rho2", rho_rho_amp_x0,len,1,1); - printf ("Computed rho*rho_a*x0\n"); + // printf ("Computed rho*rho_a*x0\n"); + sub_cpx_vector16((int16_t *)rxF, (int16_t *)rho_rho_amp_x0, - //(int16_t *)clean_x1, + // (int16_t *)clean_x1, (int16_t *)rxF, len*2); + write_output("clean_x1.m","x1", clean_x1,len,1,1); - printf ("Interference removed \n"); + // printf ("Interference removed \n"); - printf("dlsch_qpsk_llr_SIC: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); + // printf("dlsch_qpsk_llr_SIC: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); //this is for QPSK only!!! for (i=0; idlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { - printf("ret=%d\n", ret); + if (cw_non_sic==0) { avg_iter += ret; iter_trials++; @@ -3649,7 +3649,7 @@ n(tikz_fname,"w"); (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && rx_type==rx_SIC_dual_stream) { - for (round = 0 ; round < 1 ; round++) { + // for (round = 0 ; round < 1 ; round++) { dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; @@ -3676,6 +3676,7 @@ n(tikz_fname,"w"); &PHY_vars_UE->dlsch_rate_matching_stats, &PHY_vars_UE->dlsch_turbo_encoding_stats, &PHY_vars_UE->dlsch_interleaving_stats); + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, @@ -3698,7 +3699,7 @@ n(tikz_fname,"w"); subframe, &PHY_vars_UE->lte_frame_parms, num_pdcch_symbols, - &PHY_vars_UE->dlsch_eNB[0][0], + &PHY_vars_UE->dlsch_eNB[0][0], NULL, coded_bits_per_codeword); @@ -3716,7 +3717,7 @@ n(tikz_fname,"w"); dlsch0_eNB_harq->nb_rb, adjust_G2(&PHY_vars_UE->lte_frame_parms,&dlsch0_eNB_harq->rb_alloc[0],2,subframe,num_pdcch_symbols), PHY_vars_UE->dlsch_ue[eNB_id][0]); - }// round + // }// round write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); From 6eea200c3506310286a69c53f50051e6c360d56d Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 21 Mar 2016 15:21:09 +0100 Subject: [PATCH 092/571] in dlsim ret, aver_iter, iter_trials are now arrays to be used for 2 cw independently; + small bug fix in dlsim related to sic cw. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 +- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 6 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 82 ++++++++++--------- 4 files changed, 48 insertions(+), 46 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index cfb394ce8b..aa9ea86daf 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -2682,7 +2682,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, } -void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms, +/*void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned char symbol, unsigned short nb_rb, int **dl_ch_estimates_ext, @@ -2801,7 +2801,7 @@ void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms, #endif } - +*/ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index ca8b38c3fd..0fef37e30a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -747,9 +747,9 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, (int16_t *)rho_1, (int16_t*)rho_rho_amp_x0, len, - 13); + 15); - write_output("rho_rho.m","rho2", rho_rho_amp_x0,len,1,1); + // write_output("rho_rho.m","rho2", rho_rho_amp_x0,len,1,1); // printf ("Computed rho*rho_a*x0\n"); @@ -760,7 +760,7 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, len*2); - write_output("clean_x1.m","x1", clean_x1,len,1,1); + // write_output("clean_x1.m","x1", clean_x1,len,1,1); // printf ("Interference removed \n"); // printf("dlsch_qpsk_llr_SIC: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index ec5a830162..ba0b6cd5ae 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1643,7 +1643,7 @@ int dlsch_modulation_SIC(mod_sym_t **sic_buffer, amp=1; //we do full scale here for SIC gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15)); - + jj = 0; i = 0; while (jj <= G-1) { diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index c9dc55fd57..4c7859c900 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -170,7 +170,7 @@ int main(int argc, char **argv) unsigned char *input_buffer0[2],*input_buffer1[2]; unsigned short input_buffer_length0,input_buffer_length1; - unsigned int ret; + unsigned int ret[2]; unsigned int coded_bits_per_codeword=0,nsymb,dci_cnt,tbs=0; unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[2][4],round_trials[4]={0,0,0,0},dci_errors=0,dlsch_active=0,num_layers; @@ -240,7 +240,7 @@ int main(int argc, char **argv) double cpu_freq_GHz; // time_stats_t ts;//,sts,usts; - int avg_iter,iter_trials; + int avg_iter[2],iter_trials[2]; int rballocset=0; int print_perf=0; int test_perf=0; @@ -2027,7 +2027,7 @@ n(tikz_fname,"w"); i=0; while ((!feof(input_trch_fd)) && (i>3]+=(1<<(7-(i&7))); @@ -2066,8 +2066,10 @@ n(tikz_fname,"w"); // avg_ber = 0; round=0; - avg_iter = 0; - iter_trials=0; + avg_iter[0] = 0; + avg_iter[1] = 0; + iter_trials[0]=0; + iter_trials[1]=0; reset_meas(&PHY_vars_eNB->phy_proc_tx); // total eNB tx reset_meas(&PHY_vars_eNB->dlsch_scrambling_stats); reset_meas(&PHY_vars_UE->dlsch_unscrambling_stats); @@ -2122,8 +2124,9 @@ n(tikz_fname,"w"); //if (trials%100==0) eNB2UE[0]->first_run = 1; - ret = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; - while ((round < num_rounds) && (ret > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) { + ret[0] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; + ret[1] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; + while ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) { // printf("Trial %d, round %d\n",trials,round); round_trials[round]++; @@ -3508,7 +3511,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret = dlsch_decoding(PHY_vars_UE, + ret[0] = dlsch_decoding(PHY_vars_UE, PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], &PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_ue[0][cw_non_sic], @@ -3519,15 +3522,15 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - if (ret <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { + if (ret[0] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { if (cw_non_sic==0) { - avg_iter += ret; - iter_trials++; + avg_iter[0] += ret[0]; + iter_trials[0]++; } if (n_frames==1) { - printf("cw %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); + printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); #ifdef PRINT_BYTES for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) @@ -3703,9 +3706,9 @@ n(tikz_fname,"w"); NULL, coded_bits_per_codeword); - write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); - write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); + // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, @@ -3719,7 +3722,7 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_ue[eNB_id][0]); // }// round - write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); + // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; @@ -3777,7 +3780,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret = dlsch_decoding(PHY_vars_UE, + ret[1] = dlsch_decoding(PHY_vars_UE, PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], &PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_ue[0][cw_sic], @@ -3788,14 +3791,14 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { - if (cw_sic==1) { - avg_iter += ret; - iter_trials++; - } + if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + + avg_iter[1] += ret[1]; + iter_trials[1]++; + if (n_frames==1) { - printf("cw %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); + printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); #ifdef PRINT_BYTES for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) @@ -3811,23 +3814,22 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); } #endif - } + } + + } + - // PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw_sic]->current_harq_pid]->TBS; - - } //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) - else { errs[cw_sic][round]++; - if (cw_sic==0) { - avg_iter += ret-1; - iter_trials++; + if (cw_sic==1) { + avg_iter[1] += ret[1]-1; + iter_trials[1]++; } if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { - printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); + printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); #ifdef PRINT_BYTES for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) @@ -3856,13 +3858,13 @@ n(tikz_fname,"w"); errs[cw_non_sic][round]++; if (cw_non_sic==0) { - avg_iter += ret-1; - iter_trials++; + avg_iter[0] += ret[0]-1; + iter_trials[0]++; } if (cw_non_sic==1) { - avg_iter += ret-1; - iter_trials++; + avg_iter[1] += ret[1]-1; + iter_trials[1]++; } if (n_frames==1) { @@ -4225,7 +4227,7 @@ n(tikz_fname,"w"); std_phy_proc_rx_dec = sqrt((double)PHY_vars_UE->dlsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, 2)/PHY_vars_UE->dlsch_decoding_stats.trials - pow((double)PHY_vars_UE->dlsch_decoding_stats.diff/PHY_vars_UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000,2)); printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f) :%f us (%d trials, max %f)\n", - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter[0]/iter_trials[0], (double)PHY_vars_UE->dlsch_decoding_stats.diff/PHY_vars_UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_UE->dlsch_decoding_stats.trials, (double)PHY_vars_UE->dlsch_decoding_stats.max/cpu_freq_GHz/1000.0); printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); @@ -4236,7 +4238,7 @@ n(tikz_fname,"w"); (double)PHY_vars_UE->dlsch_turbo_decoding_stats.diff/PHY_vars_UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)PHY_vars_UE->dlsch_tc_init_stats.diff/PHY_vars_UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, - (double)PHY_vars_UE->dlsch_tc_init_stats.diff/PHY_vars_UE->dlsch_tc_init_stats.trials/((double)avg_iter/iter_trials), + (double)PHY_vars_UE->dlsch_tc_init_stats.diff/PHY_vars_UE->dlsch_tc_init_stats.trials/((double)avg_iter[0]/iter_trials[0]), PHY_vars_UE->dlsch_tc_init_stats.trials); printf(" |__ alpha %f us (cycles/iter %f, %d trials)\n", (double)PHY_vars_UE->dlsch_tc_alpha_stats.diff/PHY_vars_UE->dlsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0, @@ -4364,7 +4366,7 @@ n(tikz_fname,"w"); rate*effective_rate, 100*effective_rate, rate, - (double)avg_iter/iter_trials, + (double)avg_iter[0]/iter_trials[0], errs[0][0], round_trials[0], errs[0][1], @@ -4409,7 +4411,7 @@ n(tikz_fname,"w"); rate*effective_rate, 100*effective_rate, rate, - (double)avg_iter/iter_trials, + (double)avg_iter[0]/iter_trials[0], errs[0][0], round_trials[0], errs[0][1], From 25796d27a1a2c8be3cd0153da8054ecc68479491 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 24 Mar 2016 09:52:34 +0100 Subject: [PATCH 093/571] Fixing the way bler is computed for SIC receiver --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 4 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index bed93103f8..eb404138b4 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5897,7 +5897,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); } - if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re <= -pmi_im))) + if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re >= pmi_im) && (pmi_re <= -pmi_im))) pmiq = PMI_2A_R1_11; else pmiq = PMI_2A_R1_1j; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index ba0b6cd5ae..393a39b259 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1295,7 +1295,7 @@ uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb int dlsch_modulation(mod_sym_t **txdataF, - int16_t amp, + int16_t amp, //512 uint32_t subframe_offset, LTE_DL_FRAME_PARMS *frame_parms, uint8_t num_pdcch_symbols, @@ -1336,7 +1336,7 @@ int dlsch_modulation(mod_sym_t **txdataF, nsymb = (frame_parms->Ncp==0) ? 14:12; - amp_rho_a = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_a)>>13); + amp_rho_a = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_a)>>13); //amp=512 in full scale; dlsch0->sqrt_rho_a=8192in Q2.13, 1 in full scale amp_rho_b = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_b)>>13); if (mod_order0 == 4) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 4c7859c900..1d47e25081 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -3511,7 +3511,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret[0] = dlsch_decoding(PHY_vars_UE, + ret[cw_non_sic] = dlsch_decoding(PHY_vars_UE, PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], &PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_ue[0][cw_non_sic], @@ -3522,7 +3522,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - if (ret[0] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { + if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { if (cw_non_sic==0) { avg_iter[0] += ret[0]; @@ -3862,11 +3862,16 @@ n(tikz_fname,"w"); iter_trials[0]++; } + if (rx_type==rx_SIC_dual_stream) { + errs[1][round]++; + } + if (cw_non_sic==1) { avg_iter[1] += ret[1]-1; iter_trials[1]++; } + if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); From f5c798e48ce312c1e46f460d5afa8a9b59dffa3b Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 31 Mar 2016 11:34:32 +0200 Subject: [PATCH 094/571] transmission mode is now taken into account in RRC signalling small bugfix in dlsch_demodulation shunted out TM3-7 specific DCI generation in scheduler to enable basic operation. more work needed. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 5 ++- openair1/PHY/TOOLS/cmult_sv.c | 4 +-- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 31 +++++-------------- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/LITE/rrc_eNB.c | 2 +- .../CONF/enb.band7.exmimo2.conf | 2 +- targets/SIMU/USER/oaisim_functions.c | 5 +-- 7 files changed, 20 insertions(+), 31 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index aa9ea86daf..a6b3bec1e4 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -990,6 +990,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, break; } + if (dlsch1_harq) { switch (get_Qm(dlsch1_harq->mcs)) { case 2 : if (rx_type==rx_standard) { @@ -1033,6 +1034,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, return(-1); break; } + } + return(0); } @@ -4795,4 +4798,4 @@ void print_ints(char *s,__m128i *x) tempb[0],tempb[1],tempb[2],tempb[3]); }*/ -#endif \ No newline at end of file +#endif diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index a30bbcd321..73d1c56309 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -392,8 +392,8 @@ int rotate_cpx_vector(int16_t *x, m3 = _mm_sra_epi32(m3,shift); // shift right by shift in order to compensate for the input amplitude y_128[0] = _mm_packs_epi32(m2,m3); // pack in 16bit integers with saturation [re im re im re im re im] - print_ints("y_128[0]=", &y_128[0]); - #elif defined(__arm__) + //print_ints("y_128[0]=", &y_128[0]); +#elif defined(__arm__) ab_re0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bconj)[0]); ab_re1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bconj)[1]); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 2a52d8779a..3312f0f371 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -737,7 +737,8 @@ schedule_ue_spec( } break; - + /* + // this code is disabled for now - needs to be done properly case 4: // if (nb_rb>10) { ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 0; @@ -775,6 +776,7 @@ schedule_ue_spec( ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;//dl_pow_off[UE_id]; break; + */ } add_ue_dlsch_info(module_idP, @@ -1402,8 +1404,9 @@ schedule_ue_spec( break; + /* + // disabled for now as this needs to be done properly case 4: - // if (nb_rb>10) { ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1; @@ -1411,15 +1414,6 @@ schedule_ue_spec( ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc; - //} - /* else { - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->mcs1 = eNB_UE_stats->DL_cqi[0]; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 1; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->tpmi = 5; - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - }*/ break; case 5: @@ -1450,6 +1444,7 @@ schedule_ue_spec( ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->TPC = tpc; break; + */ } // Toggle NDI for next time @@ -1729,9 +1724,9 @@ fill_DLSCH_dci( break; + /* case 4: - //if (nb_rb>10) { // DCI format 2_2A ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rah = 0; @@ -1743,17 +1738,6 @@ fill_DLSCH_dci( sizeof_DCI2_5MHz_2A_TDD_t, format2, 0); - /*} - else { - ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub); - add_ue_spec_dci(DCI_pdu, - DLSCH_dci, - rnti, - sizeof(DCI2_5MHz_2A_L10PRB_TDD_t), - 2,//aggregation, - sizeof_DCI2_5MHz_2A_L10PRB_TDD_t, - format2_2A_L10PRB); - }*/ break; case 5: @@ -1783,6 +1767,7 @@ fill_DLSCH_dci( format1E_2A_M10PRB, 0); break; + */ } } diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index ff0adf713b..83fd5d357d 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -107,7 +107,7 @@ int errno; # endif #endif -//#define XER_PRINT +#define XER_PRINT extern Enb_properties_array_t enb_properties; typedef struct xer_sprint_string_s { diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 1d0b5f2902..94b0d46eef 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -3277,7 +3277,7 @@ rrc_eNB_generate_RRCConnectionSetup( do_RRCConnectionSetup(ctxt_pP, ue_context_pP, (uint8_t*) eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].Srb0.Tx_buffer.Payload, - (mac_xface->lte_frame_parms->nb_antennas_tx==2)?2:1, + mac_xface->get_transmission_mode(ctxt_pP->module_id,CC_id,ue_context_pP->ue_id_rnti), rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), mac_xface->lte_frame_parms, SRB_configList, diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf index bc9d15195c..6493c01167 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.exmimo2.conf @@ -47,7 +47,7 @@ eNBs = pucch_nCS_AN = 0; pucch_n1_AN = 32; pdsch_referenceSignalPower = -24; - pdsch_p_b = 0; + pdsch_p_b = 1; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; pusch_hoppingMode = "interSubFrame"; diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 014a9e39d0..721b743389 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -684,8 +684,9 @@ void get_simulation_options(int argc, char *argv[]) case 'x': oai_emulation.info.transmission_mode[0] = atoi (optarg); - if ((oai_emulation.info.transmission_mode[0] != 1) && (oai_emulation.info.transmission_mode[0] != 2) && (oai_emulation.info.transmission_mode[0] != 3) - && (oai_emulation.info.transmission_mode[0] != 5) && (oai_emulation.info.transmission_mode[0] != 6)) { + if ((oai_emulation.info.transmission_mode[0] != 1) && (oai_emulation.info.transmission_mode[0] != 2) && + (oai_emulation.info.transmission_mode[0] != 3) && (oai_emulation.info.transmission_mode[0] != 4) && + (oai_emulation.info.transmission_mode[0] != 5) && (oai_emulation.info.transmission_mode[0] != 6)) { printf("Unsupported transmission mode %d\n",oai_emulation.info.transmission_mode[0]); exit(-1); } From 459913de55e86495cb4c64ce0110f0a845255834 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 18 Apr 2016 20:08:54 +0200 Subject: [PATCH 095/571] changes are mostly related to: 1. Introducing dlsch_16qam_llr_SIC. 2. New writing files format in file_output.c 3. Some comments addded. --- openair1/PHY/INIT/lte_init.c | 5 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 +- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 22 +-- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 53 +++-- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 186 ++++++++++-------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 7 +- openair1/PHY/LTE_TRANSPORT/proto.h | 23 ++- openair1/PHY/MODULATION/slot_fep.c | 8 +- openair1/PHY/TOOLS/cmult_sv.c | 6 +- openair1/PHY/TOOLS/cmult_vv.c | 24 +-- openair1/PHY/TOOLS/file_output.c | 15 +- openair1/PHY/TOOLS/lte_phy_scope.c | 26 +-- openair1/SIMULATION/LTE_PHY/dlsim.c | 59 ++++-- openair1/SIMULATION/TOOLS/random_channel.c | 2 +- openair1/SIMULATION/TOOLS/rangen_double.c | 31 ++- openair1/SIMULATION/TOOLS/taus.c | 39 +++- 16 files changed, 329 insertions(+), 179 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index bf48bcd8a8..e22e91e1fe 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -1127,15 +1127,16 @@ int phy_init_lte_ue(PHY_VARS_UE *phy_vars_ue, ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); } + const size_t num = 7*2*frame_parms->N_RB_DL*12+4; for (k=0;k<8;k++) { //harq_pid for (l=0;l<8;l++) { //round ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - + // ue_pdsch_vars[eNB_id]->clean_x1[k][l] = (int16_t*)malloc16_clear( sizeof(int32_t) * num); + for (int i=0; inb_antennas_rx; i++) for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) const int idx = (j<<1)+i; - const size_t num = 7*2*frame_parms->N_RB_DL*12+4; ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); } diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index eb404138b4..59c235b34d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5897,7 +5897,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); } - if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re >= pmi_im) && (pmi_re <= -pmi_im))) + if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im))) pmiq = PMI_2A_R1_11; else pmiq = PMI_2A_R1_1j; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 95af038ab0..3627482dc9 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -299,7 +299,7 @@ int dlsch_encoding(unsigned char *a, printf("\n"); */ // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a, + crc = crc24a(a, //input bits for computation, A is a size of a A)>>8; a[A>>3] = ((uint8_t*)&crc)[2]; a[1+(A>>3)] = ((uint8_t*)&crc)[1]; @@ -310,15 +310,15 @@ int dlsch_encoding(unsigned char *a, // dlsch->harq_processes[harq_pid]->b = a; memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); - if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, - dlsch->harq_processes[harq_pid]->c, - dlsch->harq_processes[harq_pid]->B, - &dlsch->harq_processes[harq_pid]->C, - &dlsch->harq_processes[harq_pid]->Cplus, - &dlsch->harq_processes[harq_pid]->Cminus, - &dlsch->harq_processes[harq_pid]->Kplus, - &dlsch->harq_processes[harq_pid]->Kminus, - &dlsch->harq_processes[harq_pid]->F)<0) + if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, // bits after CRC attachement + dlsch->harq_processes[harq_pid]->c, // output from segmentation + dlsch->harq_processes[harq_pid]->B, //size of B=L+A + &dlsch->harq_processes[harq_pid]->C, //number of codeblocks + &dlsch->harq_processes[harq_pid]->Cplus, //Number of segments of size K+ + &dlsch->harq_processes[harq_pid]->Cminus,//Number of segments of size K_ + &dlsch->harq_processes[harq_pid]->Kplus, //First segmentation size + &dlsch->harq_processes[harq_pid]->Kminus, //Second segmentation size + &dlsch->harq_processes[harq_pid]->F)<0) //Number of filler bits return(-1); for (r=0; rharq_processes[harq_pid]->C; r++) { @@ -399,7 +399,7 @@ int dlsch_encoding(unsigned char *a, r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], G, //G dlsch->harq_processes[harq_pid]->w[r], - dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->e+r_offset, // sequence of bits for transmission dlsch->harq_processes[harq_pid]->C, // C dlsch->Nsoft, // Nsoft, dlsch->Mdlharq, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index a6b3bec1e4..6abdaa8f7d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -58,8 +58,8 @@ //#define DEBUG_DLSCH_DEMOD 1 int avg[4]; -int avg_0[4]; -int avg_1[4]; +int avg_0[2]; +int avg_1[2]; // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; @@ -329,9 +329,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, for (aarx=0;aarxnb_antennas_rx;aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; - + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2); //+ interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + // printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh); } @@ -349,9 +348,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh, phy_measurements); // log2_maxh+I0_shift - if (symbol == 5) { + /*if (symbol == 5) { write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - } + } */ if ((rx_type==rx_IC_single_stream) && (eNB_id_in_connected_eNB)) { @@ -413,6 +412,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, dlsch0_harq->mimo_mode); + + + + // write_output("dlsch0_r0_aver_chan_1.m","dl_aver_ch1_r0_0",&avg_1[0],1,1,2); if (rx_type>rx_standard) { @@ -438,7 +441,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); } } - + dlsch_channel_compensation_TM34(frame_parms, lte_ue_pdsch_vars[eNB_id], phy_measurements, @@ -2961,7 +2964,7 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp0 =lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 =lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; - int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for first stream + int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for second stream int **dl_ch_rho2_ext =lte_ue_pdsch_vars->dl_ch_rho2_ext; int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; @@ -2990,8 +2993,8 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, } } // if (rho) { - rho128_0 = (__m128i *) &dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12]; - rho128_1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; + rho128_0 = (__m128i *) &dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12]; + rho128_1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12]; for (i=0;iN_RB_DL*12]; - rho128_i1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12]; + rho128_i0 = (__m128i *) &dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12]; + rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12]; @@ -3056,6 +3059,7 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); + // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 @@ -3147,7 +3151,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, ((int*)&avg128D)[2] + ((int*)&avg128D)[3])/(nb_rb*nre); - // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); + // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); } _mm_empty(); @@ -3313,14 +3317,15 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); - + avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); + dl_ch0_128+=3; dl_ch1_128+=3; } } + + avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) + (((int*)&avg_0_128D)[1])/(nb_rb*nre) + @@ -3332,17 +3337,19 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, (((int*)&avg_1_128D)[1])/(nb_rb*nre) + (((int*)&avg_1_128D)[2])/(nb_rb*nre) + (((int*)&avg_1_128D)[3])/(nb_rb*nre); - // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); + // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); } //avg_0[0] = max(avg_0[0],avg_0[1]); //avg_1[0] = max(avg_1[0],avg_1[1]); //avg_0[0]= max(avg_0[0], avg_1[0]); avg_0[0] = avg_0[0] + avg_0[1]; + // printf("From Chan_level aver stream 0 final =%d\n", avg_0[0]); avg_1[0] = avg_1[0] + avg_1[1]; - avg_0[0] = max (avg_0[0], avg_1[0]); - avg_1[0] = avg_0[0]; - + // printf("From Chan_level aver stream 1 final =%d\n", avg_1[0]); + avg_0[0] = min (avg_0[0], avg_1[0]); + avg_1[0] = avg_0[0]; + _mm_empty(); _m_empty(); @@ -4735,6 +4742,10 @@ void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); + // sprintf(fname,"dlsch%d_r%d_aver_chan_1.m",eNB_id,round); + // sprintf(vname,"dl_aver_ch1_r%d_%d",eNB_id,round); + // write_output(fname,vname,&avg_1[0],1,1,1); + sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round); write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 0fef37e30a..07cf174393 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -672,7 +672,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, // printf("dlsch_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); - + //printf("ll32p=%p , dlsch_llr=%p, symbol=%d, flag=%d \n", llr32, dlsch_llr, symbol, first_symbol_flag); for (i=0; iNcp==0) ? 14:12; for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]; - int16_t *rho_1=(int16_t*)&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]; + uint16_t *rxF = (uint16_t*)(&rxdataF_comp[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); + int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); sic_data = (uint16_t*)&sic_buffer[0][((int16_t)len_acc)]; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -720,6 +722,8 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, amp_tmp=dlsch0->sqrt_rho_b; else //pilots=0 amp_tmp=dlsch0->sqrt_rho_a; + + pbch_pss_sss_adjust=adjust_G2(frame_parms,rb_alloc,2,subframe,symbol); // printf("amp_tmp=%d\n", amp_tmp); @@ -731,44 +735,61 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, } else { len = (nb_rb*12) - pbch_pss_sss_adjust; } + + // printf("dlsch_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); len_acc+=len; //accumulated length; this is done because in sic_buffer we have only data symbols multadd_complex_vector_real_scalar((int16_t *)sic_data, amp_tmp, - (int16_t *)rho_amp_x0, + (int16_t *)rho_amp_x0, //this is in Q13 1, len); // printf ("Got x0*rho_a\n"); - mult_cpx_vector((int16_t *)rho_amp_x0, - (int16_t *)rho_1, + mult_cpx_vector((int16_t *)rho_1, //Q15 + (int16_t *)rho_amp_x0, //Q13 (int16_t*)rho_rho_amp_x0, len, - 15); + 13); + /* write_output("rho_for_multipl.m","rho_for_multipl", rho_1,len,1, + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13); - // write_output("rho_rho.m","rho2", rho_rho_amp_x0,len,1,1); - // printf ("Computed rho*rho_a*x0\n"); + write_output("rho_rho_in_llr.m","rho2", rho_rho_amp_x0,len,1, + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13); + // printf ("Computed rho*rho_a*x0\n");*/ + //rho_rho_amp_x0_512 = (int16_t)((512*(int16_t *)rho_rho_amp_x0)>>15); + + sub_cpx_vector16((int16_t *)rxF, (int16_t *)rho_rho_amp_x0, - // (int16_t *)clean_x1, - (int16_t *)rxF, + (int16_t *)clean_x1, + //(int16_t *)rxF, len*2); - + // write_output("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1); // write_output("clean_x1.m","x1", clean_x1,len,1,1); // printf ("Interference removed \n"); + /* write_output("clean_x1.m","x1", clean_x1,len,1, + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13); + + write_output("rxF_comp1.m","rxF_1_comp", rxF,len,1, + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13);*/ // printf("dlsch_qpsk_llr_SIC: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); //this is for QPSK only!!! for (i=0; i>=2; // length in quad words (4 REs) + // printf("len>>=2=%d\n", len); len+=(len_mod4==0 ? 0 : 1); - + // printf("len+=%d\n", len); for (i=0; iN_RB_DL*12]; + int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; + int16_t clean_x1[2*frame_parms->N_RB_DL*12]; + uint16_t amp_tmp; + uint32_t *llr32=(uint32_t*)dlsch_llr; + int i, len, nsymb; + uint8_t symbol, symbol_mod; + //uint8_t pilots; + int len_acc=0; + uint16_t *sic_data; + uint16_t pbch_pss_sss_adjust; + unsigned char len_mod4=0; + __m128i llr128[2]; + __m128i *ch_mag; + nsymb = (frame_parms->Ncp==0) ? 14:12; -#if defined(__x86_64__) || defined(__i386__) - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - __m128i *ch_mag; - __m128i llr128[2]; - uint32_t *llr32; -#elif defined(__arm__) - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16x8_t *ch_mag; - int16x8_t xmm0; - int16_t *llr16; -#endif - - - int i,len; - unsigned char symbol_mod,len_mod4=0; - - -#if defined(__x86_64__) || defined(__i386__) - if (first_symbol_flag==1) { - llr32 = (uint32_t*)dlsch_llr; - } else { - llr32 = (uint32_t*)*llr32p; - } -#elif defined(__arm__) - if (first_symbol_flag==1) { - llr16 = (int16_t*)dlsch_llr; - } else { - llr16 = (int16_t*)*llr32p; - } -#endif - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - -#if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; -#elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; -#endif - if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { - if (frame_parms->mode1_flag==0) - len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); - else - len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); - } else { - len = nb_rb*12 - pbch_pss_sss_adjust; - } - - // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE) - if (first_symbol_flag == 1) - *llr32p = dlsch_llr + (len<<2); - else - *llr32p += (len<<2); + for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]); + int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); + ch_mag = (__m128i*)(&dl_ch_mag[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); + sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]); + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + pbch_pss_sss_adjust=adjust_G2(frame_parms,rb_alloc,4,subframe,symbol); + + if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { + amp_tmp=dlsch0->sqrt_rho_b; + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + } else { + amp_tmp=dlsch0->sqrt_rho_a; + len = nb_rb*12 - pbch_pss_sss_adjust; + } + + len_acc+=len; + + multadd_complex_vector_real_scalar((int16_t *)sic_data, + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); + + mult_cpx_vector((int16_t *)rho_1, //Q15 + (int16_t *)rho_amp_x0, //Q13 + (int16_t*)rho_rho_amp_x0, + len, + 13); + + sub_cpx_vector16((int16_t *)rxF, + (int16_t *)rho_rho_amp_x0, + (int16_t *)clean_x1, + // (int16_t *)rxF, + len*2); len_mod4 = len&3; len>>=2; // length in quad words (4 REs) len+=(len_mod4==0 ? 0 : 1); @@ -974,12 +1003,13 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, for (i=0; i>15); ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - if (frame_parms->nb_antennas_tx == 2) { + // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); @@ -1643,6 +1645,7 @@ int dlsch_modulation_SIC(mod_sym_t **sic_buffer, amp=1; //we do full scale here for SIC gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15)); + // printf("gain=%d\n", gain_lin_QPSK); jj = 0; i = 0; @@ -1663,7 +1666,7 @@ int dlsch_modulation_SIC(mod_sym_t **sic_buffer, jj = jj + 1; - // printf("%d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); + // printf("recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); i++; diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 17436bf869..5502282b41 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -725,7 +725,8 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, short *dlsch_llr, uint8_t num_pdcch_symbols, uint16_t nb_rb, - uint16_t pbch_pss_sss_adjust, + uint8_t subframe, + uint32_t rb_alloc, LTE_UE_DLSCH_t *dlsch0); void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, @@ -749,15 +750,17 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, @param nb_rb number of RBs for this allocation @param pbch_pss_sss_adjust PBCH/PSS/SSS RE adjustment (in REs) */ -void dlsch_16qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - int16_t *dlsch_llr, - int32_t **dl_ch_mag, - uint8_t symbol, - uint8_t first_symbol_flag, - uint16_t nb_rb, - uint16_t pbch_pss_sss_adjust, - int16_t **llr128p); +void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + mod_sym_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, + LTE_UE_DLSCH_t *dlsch0); void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index 0d2389c2ae..6cded30f1f 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -189,7 +189,9 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); #endif start_meas(&phy_vars_ue->dlsch_channel_estimation_stats); - lte_dl_channel_estimation(phy_vars_ue,eNB_id,0, + lte_dl_channel_estimation(phy_vars_ue, + eNB_id, + 0, Ns, aa, l, @@ -197,7 +199,9 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, stop_meas(&phy_vars_ue->dlsch_channel_estimation_stats); for (i=0; iPHY_measurements.n_adj_cells; i++) { - lte_dl_channel_estimation(phy_vars_ue,eNB_id,i+1, + lte_dl_channel_estimation(phy_vars_ue, + eNB_id, + i+1, Ns, aa, l, diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index 73d1c56309..9fc3f5a290 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -66,10 +66,10 @@ void multadd_complex_vector_real_scalar(int16_t *x, if (zero_flag == 1) for (n=0; n>2; n++) { - //print_shorts("x_128[n]=", &x_128[n]); - //print_shorts("alpha_128", &alpha_128); + // print_shorts("x_128[n]=", &x_128[n]); + // print_shorts("alpha_128", &alpha_128); y_128[n] = mulhi_int16(x_128[n],alpha_128); - //print_shorts("y_128[n]=", &y_128[n]); //Q2.13 + // print_shorts("y_128[n]=", &y_128[n]); } else diff --git a/openair1/PHY/TOOLS/cmult_vv.c b/openair1/PHY/TOOLS/cmult_vv.c index 7b2b2a1245..999ee9521a 100755 --- a/openair1/PHY/TOOLS/cmult_vv.c +++ b/openair1/PHY/TOOLS/cmult_vv.c @@ -137,8 +137,8 @@ int mult_cpx_conj_vector(int16_t *x1, } -int mult_cpx_vector(int16_t *x1, - int16_t *x2, +int mult_cpx_vector(int16_t *x1, //Q15 + int16_t *x2,//Q13 int16_t *y, uint32_t N, int output_shift) @@ -174,26 +174,26 @@ int mult_cpx_vector(int16_t *x1, //right shift by 13 while p_a * x0 and 15 while // we compute 4 cpx multiply for each loop for(i=0; i<(N>>2); i++) { - tmp_re = _mm_sign_epi16(*x1_128,*(__m128i*)&conjug2[0]); + tmp_re = _mm_sign_epi16(*x1_128,*(__m128i*)&conjug2[0]);// Q15 //print_shorts("tmp_re1:",&tmp_re[i]); - tmp_re = _mm_madd_epi16(tmp_re,*x2_128); + tmp_re = _mm_madd_epi16(tmp_re,*x2_128); //Q28 //print_ints("tmp_re2:",&tmp_re[i]); - tmp_im = _mm_shufflelo_epi16(*x1_128,_MM_SHUFFLE(2,3,0,1)); + tmp_im = _mm_shufflelo_epi16(*x1_128,_MM_SHUFFLE(2,3,0,1)); //Q15 //print_shorts("tmp_im1:",&tmp_im[i]); - tmp_im = _mm_shufflehi_epi16(tmp_im,_MM_SHUFFLE(2,3,0,1)); + tmp_im = _mm_shufflehi_epi16(tmp_im,_MM_SHUFFLE(2,3,0,1)); //Q15 //print_shorts("tmp_im2:",&tmp_im[i]); - tmp_im = _mm_madd_epi16(tmp_im, *x2_128); + tmp_im = _mm_madd_epi16(tmp_im, *x2_128); //Q28 //print_ints("tmp_im3:",&tmp_im[i]); - tmp_re = _mm_srai_epi32(tmp_re,output_shift); + tmp_re = _mm_srai_epi32(tmp_re,output_shift);//Q(28-shift) //print_ints("tmp_re shifted:",&tmp_re[i]); - tmp_im = _mm_srai_epi32(tmp_im,output_shift); + tmp_im = _mm_srai_epi32(tmp_im,output_shift); //Q(28-shift) //print_ints("tmp_im shifted:",&tmp_im[i]); - tmpy0 = _mm_unpacklo_epi32(tmp_re,tmp_im); + tmpy0 = _mm_unpacklo_epi32(tmp_re,tmp_im); //Q(28-shift) //print_ints("unpack lo :",&tmpy0[i]); - tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im); + tmpy1 = _mm_unpackhi_epi32(tmp_re,tmp_im); //Q(28-shift) //print_ints("mrc rho0:",&tmpy1[i]); - *y_128 = _mm_packs_epi32(tmpy0,tmpy1); + *y_128 = _mm_packs_epi32(tmpy0,tmpy1); //must be Q15 //print_shorts("*y_128:",&y_128[i]); x1_128++; diff --git a/openair1/PHY/TOOLS/file_output.c b/openair1/PHY/TOOLS/file_output.c index e3a92696fe..e4a82fb0dc 100755 --- a/openair1/PHY/TOOLS/file_output.c +++ b/openair1/PHY/TOOLS/file_output.c @@ -43,9 +43,9 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d printf("Writing %d elements of type %d to %s\n",length,format,fname); - if (format == 10 || format ==11 || format == 12 ) { + if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) { fp = fopen(fname,"a+"); - } else if (format != 10 && format !=11 && format != 12 ) { + } else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) { fp = fopen(fname,"w+"); } @@ -56,7 +56,7 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d return(-1); } - if (format != 10 && format !=11 && format != 12 ) + if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) fprintf(fp,"%s = [",vname); @@ -70,7 +70,9 @@ int write_output(const char *fname,const char *vname,void *data,int length,int d break; case 1: // complex 16-bit - + case 13: + case 14: + case 15: for (i=0; iofdm_symbol_size,sizeof(float)); } chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); - llr = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // init to zero - bit = malloc(coded_bits_per_codeword0*sizeof(float)); + llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // init to zero + bit0 = malloc(coded_bits_per_codeword0*sizeof(float)); + llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // init to zero + bit1 = malloc(coded_bits_per_codeword1*sizeof(float)); llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); @@ -769,12 +771,12 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // PDSCH LLRs CW0 if (pdsch_llr != NULL) { for (i=0; ipdsch_llr,0,coded_bits_per_codeword0); - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword0,"","",""); + fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","",""); } @@ -838,12 +840,12 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // PDSCH LLRs CW1 if (pdsch_llr1 != NULL) { for (i=0; ipdsch_llr1,0,coded_bits_per_codeword1); - fl_set_xyplot_data(form->pdsch_llr1,bit,llr,coded_bits_per_codeword1,"","",""); + fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","",""); } // PDSCH I/Q of MF Output @@ -926,8 +928,10 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, free(I); free(Q); free(chest_f_abs); - free(llr); - free(bit); + free(llr0); + free(bit0); + free(llr1); + free(bit1); free(bit_pdcch); free(llr_pdcch); for (arx=0;arxnb_antennas_tx; i++) { + memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t)); + } //if (trials%100==0) eNB2UE[0]->first_run = 1; @@ -2774,6 +2776,9 @@ n(tikz_fname,"w"); &PHY_vars_eNB->dlsch_interleaving_stats )<0) exit(-1); + + + /* if (transmission_mode == 3) { if (dlsch_encoding(input_buffer1[k], @@ -3465,7 +3470,7 @@ n(tikz_fname,"w"); 0,subframe); PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword; PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); - if (n_frames==1) { + if (n_frames==2) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword, PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); @@ -3476,9 +3481,10 @@ n(tikz_fname,"w"); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword,1,0); sprintf(fname,"dlsch_cw%d_e.m", cw_non_sic); - sprintf(vname,"dlsch_cw%d_e", cw_non_sic); + sprintf(vname,"dlschcw%d_e", cw_non_sic); write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); uncoded_ber=0; + printf("trials=%d\n", trials); for (i=0;idlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { uncoded_ber_bit[i] = 1; @@ -3529,7 +3535,7 @@ n(tikz_fname,"w"); iter_trials[0]++; } - if (n_frames==1) { + if (n_frames==2) { printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); #ifdef PRINT_BYTES for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { @@ -3651,6 +3657,7 @@ n(tikz_fname,"w"); if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && rx_type==rx_SIC_dual_stream) { + remove("rho_rho_in_llr.m"); // for (round = 0 ; round < 1 ; round++) { dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; @@ -3670,7 +3677,7 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, &PHY_vars_UE->lte_frame_parms, num_pdcch_symbols, PHY_vars_UE->dlsch_eNB[eNB_id], @@ -3710,16 +3717,33 @@ n(tikz_fname,"w"); // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - - dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, + switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ + case 2: + dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], sic_buffer, PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], num_pdcch_symbols, dlsch0_eNB_harq->nb_rb, - adjust_G2(&PHY_vars_UE->lte_frame_parms,&dlsch0_eNB_harq->rb_alloc[0],2,subframe,num_pdcch_symbols), + subframe, + dlsch0_eNB_harq->rb_alloc[0], PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + case 4: + dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + } // }// round // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); @@ -3738,10 +3762,10 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword; PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); - if (n_frames==1) { + if (n_frames==2) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword, PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); - + // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); @@ -3749,9 +3773,10 @@ n(tikz_fname,"w"); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword,1,0); sprintf(fname,"dlsch_cw%d_e.m", cw_sic); - sprintf(vname,"dlsch_cw%d_e", cw_sic); + sprintf(vname,"dlschcw%d_e", cw_sic); write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); uncoded_ber=0; + printf("trials=%d\n", trials); for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { uncoded_ber_bit[i] = 1; @@ -3797,7 +3822,7 @@ n(tikz_fname,"w"); iter_trials[1]++; - if (n_frames==1) { + if (n_frames==2) { printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); #ifdef PRINT_BYTES for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { @@ -3821,13 +3846,14 @@ n(tikz_fname,"w"); else { errs[cw_sic][round]++; + // exit(0); if (cw_sic==1) { avg_iter[1] += ret[1]-1; iter_trials[1]++; } - if (n_frames==1) { + if (n_frames==2) { //if ((n_frames==1) || (SNR>=30)) { printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); #ifdef PRINT_BYTES @@ -3846,6 +3872,7 @@ n(tikz_fname,"w"); } #endif } //n_frames==1 + // exit(0); } //if (ret > PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) } //for (int cw_1=cw_to_decode_interf_free; cw_1=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); #ifdef PRINT_BYTES @@ -3896,7 +3923,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->phy_proc_rx); - if (n_frames==1) { + if (n_frames==2) { //rxsig sprintf(fname,"rxsig0_r%d.m",round); @@ -4520,7 +4547,7 @@ n(tikz_fname,"w"); } else { - if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) break; } diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 856367eff3..f763b49702 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -932,7 +932,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler, channel_offset, path_loss_dB, - 0); + 1); break; case Rayleigh1_orth_eff_ch_TM4_prec_imag: diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 24de0468c3..d7d0543fae 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -68,8 +68,35 @@ void randominit(unsigned seed_init) ir[i]= seed; /* initialize the shuffle table */ } - iy=1; -} + iy=1; +} + + +/*void randominit(unsigned seed_init) +{ + int i; + // this need to be integrated with the existing rng, like taus: navid + msg("Initializing random number generator, seed %x\n",seed_init); + + seed_init = 62110; + + if (seed_init == 0) { + srand((unsigned)time(NULL)); + + seed = (unsigned int) rand(); + } else { + seed = seed_init; + } + + if (seed % 2 == 0) seed += 1; /* seed and mod are relative prime */ + +// for (i=1; i<=97; i++) { +// seed = a*seed; /* mod 2**32 */ +// ir[i]= seed; /* initialize the shuffle table */ +// } + +// iy=1; +//} /*!\brief Uniform linear congruential random number generator on \f$[0,1)\f$. Returns a double-precision floating-point number.*/ diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c index 9a2a6f44b3..be2700d943 100644 --- a/openair1/SIMULATION/TOOLS/taus.c +++ b/openair1/SIMULATION/TOOLS/taus.c @@ -87,7 +87,44 @@ void set_taus_seed(unsigned int seed_init) s2 = result; #endif } -} +} + +/* void set_taus_seed(unsigned int seed_init) +{ + +#ifdef USER_MODE + struct drand48_data buffer; + unsigned long result = 0; +#endif + s0 = (unsigned int)0x1e23d852; + s1 = (unsigned int)0x81f38a1c; + s2 = (unsigned int)0xfe1a133e; + + return; + + if (seed_init == 0) { + s0 = (unsigned int)time(NULL); + s1 = (unsigned int)time(NULL); + s2 = (unsigned int)time(NULL); + } else { +#ifndef USER_MODE + s0 = (unsigned int)0x1e23d852; + s1 = (unsigned int)0x81f38a1c; + s2 = (unsigned int)0xfe1a133e; +#else + // Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ + // srand48_r((long int)seed_init, &buffer); + // mrand48_r(&buffer, (long int *)&result); + // s0 = result; + // mrand48_r(&buffer, (long int *)&result); + // s1 = result; + // mrand48_r(&buffer, (long int *)&result); + // s2 = result; +//#endif + // } +//} + + #ifdef MAIN From 5615a754130b5b9faa843aa1b42ce3aeae44e7f5 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 19 Apr 2016 17:04:09 +0200 Subject: [PATCH 096/571] fixing previous merge --- openair1/SIMULATION/LTE_PHY/dlsim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index c2bb73e1de..bbd9c234c8 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -229,7 +229,6 @@ int main(int argc, char **argv) short *uncoded_ber_bit=NULL; uint8_t N_RB_DL=25,osf=1; uint8_t fdd_flag = 0; - int xforms = 0; frame_t frame_type = FDD; int xforms=0; FD_lte_phy_scope_ue *form_ue = NULL; From cc9a5ede962af051d782697b9726e4bf4cb52433 Mon Sep 17 00:00:00 2001 From: lukashov Date: Tue, 19 Apr 2016 18:21:42 +0200 Subject: [PATCH 097/571] Introdducing dlsch_64qam_llr_SIC. --- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 220 ++++++++---------- openair1/PHY/LTE_TRANSPORT/proto.h | 23 +- openair1/PHY/TOOLS/cadd_sv.c | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 17 +- 4 files changed, 129 insertions(+), 133 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 07cf174393..703c7e8869 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -952,8 +952,8 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, uint16_t *sic_data; uint16_t pbch_pss_sss_adjust; unsigned char len_mod4=0; - __m128i llr128[2]; - __m128i *ch_mag; + __m128i llr128[2]; + __m128i *ch_mag; nsymb = (frame_parms->Ncp==0) ? 14:12; for (symbol=num_pdcch_symbols; symbol>=2; // length in quad words (4 REs) @@ -1002,8 +1002,12 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, for (i=0; iN_RB_DL*12)]; - __m128i *ch_mag,*ch_magb; -#elif defined(__arm__) - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)]; - int16x8_t *ch_mag,*ch_magb,xmm1,xmm2; -#endif - int i,len,len2; - unsigned char symbol_mod,len_mod4; - short *llr; + int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; + int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; + int16_t clean_x1[2*frame_parms->N_RB_DL*12]; + uint16_t amp_tmp; + uint16_t *llr32=(uint16_t*)dlsch_llr; + int i, len, nsymb, len2; + uint8_t symbol, symbol_mod; + int len_acc=0; + uint16_t *sic_data; + uint16_t pbch_pss_sss_adjust; + unsigned char len_mod4=0; int16_t *llr2; + __m128i *ch_mag,*ch_magb; + + nsymb = (frame_parms->Ncp==0) ? 14:12; - if (first_symbol_flag==1) - llr = dlsch_llr; - else - llr = *llr_save; + for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]); + int16_t *rho_1=(int16_t*)(&rho_i[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); + ch_mag = (__m128i*)(&dl_ch_mag[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); + ch_magb = (__m128i*)(&dl_ch_magb[0][((int16_t)symbol*frame_parms->N_RB_DL*12)]); + sic_data = (uint16_t*)(&sic_buffer[0][((int16_t)len_acc)]); + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + pbch_pss_sss_adjust=adjust_G2(frame_parms,rb_alloc,6,subframe,symbol); + + if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { + amp_tmp=dlsch0->sqrt_rho_b; + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + } else { + amp_tmp=dlsch0->sqrt_rho_a; + len = nb_rb*12 - pbch_pss_sss_adjust; + } + + len_acc+=len; + + multadd_complex_vector_real_scalar((int16_t *)sic_data, + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); + + mult_cpx_vector((int16_t *)rho_1, //Q15 + (int16_t *)rho_amp_x0, //Q13 + (int16_t*)rho_rho_amp_x0, + len, + 13); + + sub_cpx_vector16((int16_t *)rxF, + (int16_t *)rho_rho_amp_x0, + // (int16_t *)clean_x1, + (int16_t *)rxF, + len*2); -#if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; -#elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)]; - ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)]; -#endif - if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { - if (frame_parms->mode1_flag==0) - len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); - else - len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); - } else { - len = nb_rb*12 - pbch_pss_sss_adjust; - } - - llr2 = llr; - llr += (len*6); + llr2 = llr32; + llr32 += (len*6); len_mod4 =len&3; len2=len>>2; // length in quad words (4 REs) len2+=(len_mod4?0:1); + + for (i=0; irb_alloc[0], PHY_vars_UE->dlsch_ue[eNB_id][0]); break; - } - // }// round + case 6: + dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + }// round // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); From c4f81632469c97f0845a9abf73628ffad749e87d Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 20 Apr 2016 09:54:31 +0200 Subject: [PATCH 098/571] DEBUG flag will not work for realtime mode --- cmake_targets/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5301325bbb..83766663a0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -123,7 +123,7 @@ endmacro(add_list_string_option) #################################################### # compilation flags ############################################# -set (CMAKE_BUILD_TYPE "Debug") +#set (CMAKE_BUILD_TYPE "Debug") if (CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() From c63abc0842dea1a0e4c05c3b3683c6a0d3eb3acc Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 15 Jun 2016 16:01:15 +0200 Subject: [PATCH 099/571] Fixing merge with develop --- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 62 +++++++++---------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 17 +++-- openair1/PHY/LTE_TRANSPORT/proto.h | 52 ++++++++-------- openair1/SIMULATION/LTE_PHY/dlsim.c | 10 +-- 4 files changed, 70 insertions(+), 71 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 703c7e8869..90fdc7f82a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -686,15 +686,15 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, } int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - mod_sym_t **sic_buffer, //Q15 - int32_t **rho_i, - short *dlsch_llr, - uint8_t num_pdcch_symbols, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, - LTE_UE_DLSCH_t *dlsch0) + int32_t **rxdataF_comp, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + short *dlsch_llr, + uint8_t num_pdcch_symbols, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, + LTE_UE_DLSCH_t *dlsch0) { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; @@ -929,16 +929,16 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, - mod_sym_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, - LTE_UE_DLSCH_t *dlsch0 - ) + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, + LTE_UE_DLSCH_t *dlsch0 + ) { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; @@ -1183,18 +1183,18 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, //#if 0 void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - mod_sym_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, - LTE_UE_DLSCH_t *dlsch0 - ) + int32_t **rxdataF_comp, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, + LTE_UE_DLSCH_t *dlsch0 + ) { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 907fb90a86..49837d3891 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1611,16 +1611,15 @@ int dlsch_modulation(int32_t **txdataF, return (re_allocated); } -<<<<<<< HEAD -int dlsch_modulation_SIC(mod_sym_t **sic_buffer, - int16_t amp, - uint32_t subframe_offset, - LTE_DL_FRAME_PARMS *frame_parms, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch0, - LTE_eNB_DLSCH_t *dlsch1, - int G) +int dlsch_modulation_SIC(int32_t **sic_buffer, + int16_t amp, + uint32_t subframe_offset, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch0, + LTE_eNB_DLSCH_t *dlsch1, + int G) { uint8_t nsymb; diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index d71d60d1ba..3e5e16d460 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -211,7 +211,7 @@ int32_t dlsch_modulation(int32_t **txdataF, LTE_eNB_DLSCH_t *dlsch0, LTE_eNB_DLSCH_t *dlsch1); -int32_t dlsch_modulation_SIC(mod_sym_t **sic_buffer, +int32_t dlsch_modulation_SIC(int32_t **sic_buffer, int16_t amp, uint32_t sub_frame_offset, LTE_DL_FRAME_PARMS *frame_parms, @@ -721,14 +721,14 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp, - mod_sym_t **sic_buffer, - int **rho_i, + int32_t **sic_buffer, + int **rho_i, short *dlsch_llr, - uint8_t num_pdcch_symbols, + uint8_t num_pdcch_symbols, uint16_t nb_rb, uint8_t subframe, - uint32_t rb_alloc, - LTE_UE_DLSCH_t *dlsch0); + uint32_t rb_alloc, + LTE_UE_DLSCH_t *dlsch0); void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, @@ -753,28 +753,28 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, */ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, - mod_sym_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, - LTE_UE_DLSCH_t *dlsch0); + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, + LTE_UE_DLSCH_t *dlsch0); void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - mod_sym_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, - LTE_UE_DLSCH_t *dlsch0); + int32_t **rxdataF_comp, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, + LTE_UE_DLSCH_t *dlsch0); void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index f842e9b4f1..99fe22e3c7 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -256,7 +256,7 @@ int main(int argc, char **argv) LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; uint8_t Kmimo; - mod_sym_t **sic_buffer; + int32_t **sic_buffer; int8_t cw_to_decode_interf; int8_t cw_to_decode_interf_free; int8_t cw_non_sic; @@ -1029,9 +1029,9 @@ n(tikz_fname,"w"); } - sic_buffer = (mod_sym_t **) malloc16(frame_parms->nb_antennas_tx*sizeof(mod_sym_t*) ); + sic_buffer = (int32_t **) malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t *) ); for (i=0; inb_antennas_tx; i++) { - sic_buffer[i] = malloc16_clear(FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t)); + sic_buffer[i] = malloc16_clear(FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } if (input_fd==NULL) { @@ -2119,7 +2119,7 @@ n(tikz_fname,"w"); fflush(stdout); round=0; for (i=0; inb_antennas_tx; i++) { - memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t)); + memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } //if (trials%100==0) eNB2UE[0]->first_run = 1; @@ -2148,7 +2148,7 @@ n(tikz_fname,"w"); // printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aalte_frame_parms.nb_antennas_tx;aa++) { - memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t)); + memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } if (input_fd==NULL) { From 51e8e0ade79fb3d60644314a9e7efbe2cb40f405 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 6 Jul 2016 15:44:39 +0200 Subject: [PATCH 100/571] Fixing SIC receiver for all the combinations. Introduced >>1 shift in SIC modulation for 64QAM to avoid overflow. Shift is then compensated in llr computation. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 +- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 124 ++++++++++------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 11 +- openair1/PHY/LTE_TRANSPORT/proto.h | 4 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 131 +++++++++--------- 5 files changed, 152 insertions(+), 122 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 9b364e598e..8d33efd1d7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -829,7 +829,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128); } - else if ((rx_type==rx_IC_single_stream) || (rx_type==rx_IC_dual_stream)) { + else if (rx_type >= rx_IC_single_stream) { if (dlsch1_harq->Qm == 2) { dlsch_16qam_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, @@ -913,7 +913,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128); } - else if ((rx_type==rx_IC_single_stream) || (rx_type==rx_IC_dual_stream)) { + else if (rx_type >= rx_IC_single_stream) { if (dlsch1_harq->Qm == 2) { dlsch_64qam_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 90fdc7f82a..afe6da3e3f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -694,6 +694,7 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, uint16_t nb_rb, uint8_t subframe, uint32_t rb_alloc, + uint16_t mod_order_0, LTE_UE_DLSCH_t *dlsch0) { @@ -718,12 +719,19 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) //pilots=1 - amp_tmp=dlsch0->sqrt_rho_b; - else //pilots=0 - amp_tmp=dlsch0->sqrt_rho_a; + + + + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) //pilots=1 + amp_tmp=dlsch0->sqrt_rho_b; + else //pilots=0 + amp_tmp=dlsch0->sqrt_rho_a; + + if (mod_order_0==6) + amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation - pbch_pss_sss_adjust=adjust_G2(frame_parms,rb_alloc,2,subframe,symbol); + + pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,2,subframe,symbol); // printf("amp_tmp=%d\n", amp_tmp); @@ -741,10 +749,10 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, len_acc+=len; //accumulated length; this is done because in sic_buffer we have only data symbols multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); // printf ("Got x0*rho_a\n"); @@ -768,10 +776,10 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - (int16_t *)clean_x1, - //(int16_t *)rxF, - len*2); + (int16_t *)rho_rho_amp_x0, + //(int16_t *)clean_x1, + (int16_t *)rxF, + len*2); // write_output("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1); // write_output("clean_x1.m","x1", clean_x1,len,1,1); @@ -789,7 +797,7 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, //this is for QPSK only!!! for (i=0; i=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - pbch_pss_sss_adjust=adjust_G2(frame_parms,rb_alloc,4,subframe,symbol); + pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,4,subframe,symbol); + if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { - amp_tmp=dlsch0->sqrt_rho_b; - if (frame_parms->mode1_flag==0) - len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); - else - len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + + amp_tmp=dlsch0->sqrt_rho_b; + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); } else { - amp_tmp=dlsch0->sqrt_rho_a; - len = nb_rb*12 - pbch_pss_sss_adjust; + + amp_tmp=dlsch0->sqrt_rho_a; + len = nb_rb*12 - pbch_pss_sss_adjust; } + + if (mod_order_0==6) + amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation len_acc+=len; multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); mult_cpx_vector((int16_t *)rho_1, //Q15 (int16_t *)rho_amp_x0, //Q13 @@ -992,15 +1007,16 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, 13); sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - // (int16_t *)clean_x1, - (int16_t *)rxF, - len*2); - len_mod4 = len&3; - len>>=2; // length in quad words (4 REs) - len+=(len_mod4==0 ? 0 : 1); + (int16_t *)rho_rho_amp_x0, + //(int16_t *)clean_x1, + (int16_t *)rxF, + len*2); - for (i=0; i>=2; // length in quad words (4 REs) + len+=(len_mod4==0 ? 0 : 1); + + for (i=0; iNcp==0) ? 14:12; @@ -1221,26 +1238,31 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - pbch_pss_sss_adjust=adjust_G2(frame_parms,rb_alloc,6,subframe,symbol); + pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,6,subframe,symbol); if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { - amp_tmp=dlsch0->sqrt_rho_b; - if (frame_parms->mode1_flag==0) - len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); - else - len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + + amp_tmp = dlsch0->sqrt_rho_b; + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); } else { - amp_tmp=dlsch0->sqrt_rho_a; - len = nb_rb*12 - pbch_pss_sss_adjust; + + amp_tmp = dlsch0->sqrt_rho_a; + len = nb_rb*12 - pbch_pss_sss_adjust; } + + if (mod_order_0==6) + amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation len_acc+=len; multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); mult_cpx_vector((int16_t *)rho_1, //Q15 (int16_t *)rho_amp_x0, //Q13 @@ -1249,10 +1271,10 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, 13); sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - // (int16_t *)clean_x1, - (int16_t *)rxF, - len*2); + (int16_t *)rho_rho_amp_x0, + //(int16_t *)clean_x1, + (int16_t *)rxF, + len*2); llr2 = llr32; llr32 += (len*6); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 49837d3891..686dd19029 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1613,7 +1613,6 @@ int dlsch_modulation(int32_t **txdataF, int dlsch_modulation_SIC(int32_t **sic_buffer, - int16_t amp, uint32_t subframe_offset, LTE_DL_FRAME_PARMS *frame_parms, uint8_t num_pdcch_symbols, @@ -1627,7 +1626,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid]; LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid]; uint32_t i,jj,re_allocated=0; - uint16_t l,rb,re_offset; + uint16_t l,rb,re_offset, amp; uint32_t *rb_alloc = dlsch0_harq->rb_alloc; uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs); uint8_t *x0 = dlsch0_harq->e; @@ -1662,7 +1661,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, jj = jj + 1; - ((int16_t*)&sic_buffer[0][i])[1] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} + ((int16_t*)&sic_buffer[0][i])[1] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} jj = jj + 1; @@ -1700,7 +1699,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re]; - ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_im]; + ((int16_t *)&sic_buffer[0][i])[1]+=qam16_table[qam16_table_offset_im]; i++; @@ -1743,8 +1742,8 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, jj=jj+1; - ((int16_t *)&sic_buffer[0][i])[0]+=qam64_table[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t *)&sic_buffer[0][i])[0]+=qam64_table[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + ((int16_t *)&sic_buffer[0][i])[0]+=(qam64_table[qam64_table_offset_re])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&sic_buffer[0][i])[1]+=(qam64_table[qam64_table_offset_im])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); i++; diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 3e5e16d460..6a889c5dfb 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -212,7 +212,6 @@ int32_t dlsch_modulation(int32_t **txdataF, LTE_eNB_DLSCH_t *dlsch1); int32_t dlsch_modulation_SIC(int32_t **sic_buffer, - int16_t amp, uint32_t sub_frame_offset, LTE_DL_FRAME_PARMS *frame_parms, uint8_t num_pdcch_symbols, @@ -728,6 +727,7 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, uint16_t nb_rb, uint8_t subframe, uint32_t rb_alloc, + uint16_t mod_order_0, LTE_UE_DLSCH_t *dlsch0); void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, @@ -761,6 +761,7 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, uint16_t nb_rb, uint8_t subframe, uint32_t rb_alloc, + uint16_t mod_order_0, LTE_UE_DLSCH_t *dlsch0); void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, @@ -774,6 +775,7 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, uint16_t nb_rb, uint8_t subframe, uint32_t rb_alloc, + uint16_t mod_order_0, LTE_UE_DLSCH_t *dlsch0); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 99fe22e3c7..affe895f10 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -3675,85 +3675,92 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_UE->dlsch_eNB[eNB_id], - 0, - subframe, - &PHY_vars_UE->dlsch_rate_matching_stats, - &PHY_vars_UE->dlsch_turbo_encoding_stats, - &PHY_vars_UE->dlsch_interleaving_stats); + + dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0, + subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats); coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, - get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, - num_pdcch_symbols, - 0, - subframe); + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0, + subframe); dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_eNB[eNB_id], - coded_bits_per_codeword, - 0, - subframe<<1); + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword, + 0, + subframe<<1); re_allocated = dlsch_modulation_SIC(sic_buffer, - AMP, - subframe, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - &PHY_vars_UE->dlsch_eNB[0][0], - NULL, - coded_bits_per_codeword); + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL, + coded_bits_per_codeword); // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ - case 2: - dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - PHY_vars_UE->dlsch_ue[eNB_id][0]); + + case 2: + + dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); break; + case 4: - dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - PHY_vars_UE->dlsch_ue[eNB_id][0]); + + dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); break; case 6: - dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - PHY_vars_UE->dlsch_ue[eNB_id][0]); + dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); break; }// round From aa69c550e3552c73ceafddf1675cd42adb1c3e57 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 7 Jul 2016 14:26:00 +0200 Subject: [PATCH 101/571] A bit of clean-up. --- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 158 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 1347 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 6398 ++++++++--------- 3 files changed, 3925 insertions(+), 3978 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index afe6da3e3f..d85efebb8a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -687,15 +687,15 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, - int32_t **sic_buffer, //Q15 - int32_t **rho_i, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, short *dlsch_llr, - uint8_t num_pdcch_symbols, + uint8_t num_pdcch_symbols, uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, + uint8_t subframe, + uint32_t rb_alloc, uint16_t mod_order_0, - LTE_UE_DLSCH_t *dlsch0) + LTE_UE_DLSCH_t *dlsch0) { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; @@ -749,10 +749,10 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, len_acc+=len; //accumulated length; this is done because in sic_buffer we have only data symbols multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); // printf ("Got x0*rho_a\n"); @@ -763,12 +763,12 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, len, 13); /* write_output("rho_for_multipl.m","rho_for_multipl", rho_1,len,1, - symbol==num_pdcch_symbols ? 15 : - symbol==nsymb-1 ? 14 : 13); + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13); write_output("rho_rho_in_llr.m","rho2", rho_rho_amp_x0,len,1, - symbol==num_pdcch_symbols ? 15 : - symbol==nsymb-1 ? 14 : 13); + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13); // printf ("Computed rho*rho_a*x0\n");*/ @@ -776,21 +776,21 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - //(int16_t *)clean_x1, - (int16_t *)rxF, - len*2); + (int16_t *)rho_rho_amp_x0, + //(int16_t *)clean_x1, + (int16_t *)rxF, + len*2); // write_output("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1); // write_output("clean_x1.m","x1", clean_x1,len,1,1); // printf ("Interference removed \n"); /* write_output("clean_x1.m","x1", clean_x1,len,1, - symbol==num_pdcch_symbols ? 15 : - symbol==nsymb-1 ? 14 : 13); - - write_output("rxF_comp1.m","rxF_1_comp", rxF,len,1, - symbol==num_pdcch_symbols ? 15 : - symbol==nsymb-1 ? 14 : 13);*/ + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13); + + write_output("rxF_comp1.m","rxF_1_comp", rxF,len,1, + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13);*/ // printf("dlsch_qpsk_llr_SIC: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); @@ -937,17 +937,17 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, - int32_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, uint16_t mod_order_0, - LTE_UE_DLSCH_t *dlsch0 - ) + LTE_UE_DLSCH_t *dlsch0 + ) { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; @@ -995,10 +995,10 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, len_acc+=len; multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); mult_cpx_vector((int16_t *)rho_1, //Q15 (int16_t *)rho_amp_x0, //Q13 @@ -1007,10 +1007,10 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, 13); sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - //(int16_t *)clean_x1, - (int16_t *)rxF, - len*2); + (int16_t *)rho_rho_amp_x0, + //(int16_t *)clean_x1, + (int16_t *)rxF, + len*2); len_mod4 = len&3; len>>=2; // length in quad words (4 REs) @@ -1200,18 +1200,18 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, //#if 0 void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, - int32_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, uint16_t mod_order_0, - LTE_UE_DLSCH_t *dlsch0 - ) + LTE_UE_DLSCH_t *dlsch0 + ) { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; @@ -1227,7 +1227,7 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, uint16_t *llr2; __m128i *ch_mag,*ch_magb; - nsymb = (frame_parms->Ncp==0) ? 14:12; + nsymb = (frame_parms->Ncp==0) ? 14:12; for (symbol=num_pdcch_symbols; symbolN_RB_DL*12)]); @@ -1240,17 +1240,17 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,6,subframe,symbol); - if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { + if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { - amp_tmp = dlsch0->sqrt_rho_b; - if (frame_parms->mode1_flag==0) - len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); - else - len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + amp_tmp = dlsch0->sqrt_rho_b; + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); } else { - amp_tmp = dlsch0->sqrt_rho_a; - len = nb_rb*12 - pbch_pss_sss_adjust; + amp_tmp = dlsch0->sqrt_rho_a; + len = nb_rb*12 - pbch_pss_sss_adjust; } if (mod_order_0==6) @@ -1259,10 +1259,10 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, len_acc+=len; multadd_complex_vector_real_scalar((int16_t *)sic_data, - amp_tmp, - (int16_t *)rho_amp_x0, //this is in Q13 - 1, - len); + amp_tmp, + (int16_t *)rho_amp_x0, //this is in Q13 + 1, + len); mult_cpx_vector((int16_t *)rho_1, //Q15 (int16_t *)rho_amp_x0, //Q13 @@ -1271,10 +1271,10 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, 13); sub_cpx_vector16((int16_t *)rxF, - (int16_t *)rho_rho_amp_x0, - //(int16_t *)clean_x1, - (int16_t *)rxF, - len*2); + (int16_t *)rho_rho_amp_x0, + //(int16_t *)clean_x1, + (int16_t *)rxF, + len*2); llr2 = llr32; llr32 += (len*6); @@ -1442,7 +1442,7 @@ void qpsk_qpsk(short *stream0_in, short *stream0_out, short *rho01, int length - ) + ) { /* @@ -1702,7 +1702,7 @@ void qpsk_qam16(int16_t *stream0_in, int16_t *stream0_out, int16_t *rho01, int32_t length - ) + ) { /* This function computes the LLRs of stream 0 (s_0) in presence of the interfering stream 1 (s_1) assuming that both symbols are QPSK. It can be used for both MU-MIMO interference-aware receiver or for SU-MIMO receivers. @@ -1987,7 +1987,7 @@ void qpsk_qam64(short *stream0_in, short *stream0_out, short *rho01, int length - ) + ) { /* @@ -2239,7 +2239,7 @@ void qam16_qpsk(short *stream0_in, short *stream0_out, short *rho01, int length - ) + ) { /* @@ -2749,7 +2749,7 @@ void qam16_qam16(short *stream0_in, short *stream0_out, short *rho01, int length - ) + ) { /* @@ -3308,7 +3308,7 @@ void qam16_qam64(int16_t *stream0_in, int16_t *stream0_out, int16_t *rho01, int32_t length - ) + ) { /* @@ -3984,7 +3984,7 @@ void qam64_qpsk(int16_t *stream0_in, int16_t *stream0_out, int16_t *rho01, int32_t length - ) + ) { /* @@ -5507,7 +5507,7 @@ void qam64_qam16(short *stream0_in, short *stream0_out, short *rho01, int length - ) + ) { /* @@ -7052,7 +7052,7 @@ void qam64_qam64(short *stream0_in, short *stream0_out, short *rho01, int length - ) + ) { /* diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 686dd19029..09ab46485d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -242,19 +242,17 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, first_re=6; for (re=first_re; reofdm_symbol_size+1; tti_offset = symbol_offset + re_off + re; - // check that RE is not from Cell-specific RS + //check that RE is not from Cell-specific RS if (is_not_pilot(pilots,re,frame_parms->nushift,use2ndpilots)==1) { - // printf("re %d (jj %d)\n",re,*jj); + //printf("re %d (jj %d)\n",re,*jj); if (mimo_mode == SISO) { //SISO mapping @@ -263,7 +261,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, switch (mod_order0) { case 2: //QPSK -// printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); for (aa=0; aanb_antennas_tx; aa++) { ((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i } @@ -276,7 +274,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, *jj = *jj + 1; - // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; case 4: //16QAM @@ -308,8 +306,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, for (aa=0; aanb_antennas_tx; aa++) { ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s0[qam16_table_offset_re]; ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; - // ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - // ((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + //((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + //((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); } break; @@ -382,602 +380,598 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, ((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj=*jj+1; - // normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); - - break; - - case 4: //16QAM - - // Antenna 0 position n - - qam16_table_offset_re = 0; - qam16_table_offset_im = 0; - - if (x0[*jj] == 1) - qam16_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=2; - *jj=*jj+1; - - - if (x0[*jj] == 1) - qam16_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=1; - *jj=*jj+1; - - ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - - // Antenna 1 position n Real part -> -x1* - - qam16_table_offset_re = 0; - qam16_table_offset_im = 0; - if (x0[*jj] == 1) - qam16_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=2; - *jj=*jj+1; - - - if (x0[*jj] == 1) - qam16_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=1; - *jj=*jj+1; - - ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - - - break; - case 6: // 64-QAM - - // Antenna 0 - qam64_table_offset_re = 0; - qam64_table_offset_im = 0; + // normalization for 2 tx antennas + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + + break; + + case 4: //16QAM + + // Antenna 0 position n + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; + + if (x0[*jj] == 1) + qam16_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=2; + *jj=*jj+1; + + + if (x0[*jj] == 1) + qam16_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + // Antenna 1 position n Real part -> -x1* + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; - if (x0[*jj] == 1) - qam64_table_offset_re+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=1; - *jj=*jj+1; - - ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - - - // Antenna 1 => -x1* - qam64_table_offset_re = 0; - qam64_table_offset_im = 0; - if (x0[*jj] == 1) - qam64_table_offset_re+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=1; - *jj=*jj+1; - - ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - - break; - } - // fill in the rest of the ALAMOUTI precoding - if (is_not_pilot(pilots,re + 1,frame_parms->nushift,use2ndpilots)==1) { - ((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1 - ((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1]; - ((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0* - ((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1]; - } - else { - ((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1 - ((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1]; - ((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0* - ((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1]; - } + if (x0[*jj] == 1) + qam16_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=2; + *jj=*jj+1; + + + if (x0[*jj] == 1) + qam16_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + break; + + case 6: // 64-QAM + + // Antenna 0 + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + + if (x0[*jj] == 1) + qam64_table_offset_re+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + + // Antenna 1 => -x1* + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + if (x0[*jj] == 1) + qam64_table_offset_re+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + break; + } + // fill in the rest of the ALAMOUTI precoding + if (is_not_pilot(pilots,re + 1,frame_parms->nushift,use2ndpilots)==1) { + ((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1 + ((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1]; + ((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0* + ((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1]; + } + else { + ((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1 + ((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1]; + ((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0* + ((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1]; + } } else if (mimo_mode == LARGE_CDD) { - *re_allocated = *re_allocated + 1; + *re_allocated = *re_allocated + 1; - if (frame_parms->nb_antennas_tx == 2) { - switch (mod_order0) { - default: - LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0); - xx0_re=xx0_im=0; - break; - case 2: //QPSK - // printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj = *jj + 1; - xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj = *jj + 1; - + if (frame_parms->nb_antennas_tx == 2) { + switch (mod_order0) { + default: + LOG_E(PHY,"Unknown mod_order0 %d\n",mod_order0); + xx0_re=xx0_im=0; + break; - // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - break; - - case 4: //16QAM - - qam16_table_offset_re0 = 0; - qam16_table_offset_im0 = 0; - if (x0[*jj] == 1) - qam16_table_offset_re0+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im0+=2; - *jj=*jj+1; - - if (x0[*jj] == 1) - qam16_table_offset_re0+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im0+=1; - *jj=*jj+1; - - xx0_re = qam_table_s0[qam16_table_offset_re0]; - xx0_im = qam_table_s0[qam16_table_offset_im0]; + case 2: //QPSK + //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + xx0_re = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; + xx0_im = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; + //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + break; + + case 4: //16QAM + + qam16_table_offset_re0 = 0; + qam16_table_offset_im0 = 0; + if (x0[*jj] == 1) + qam16_table_offset_re0+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im0+=2; + *jj=*jj+1; + + if (x0[*jj] == 1) + qam16_table_offset_re0+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im0+=1; + *jj=*jj+1; + + xx0_re = qam_table_s0[qam16_table_offset_re0]; + xx0_im = qam_table_s0[qam16_table_offset_im0]; - break; - - case 6: //64QAM - - - qam64_table_offset_re0 = 0; - qam64_table_offset_im0 = 0; - - if (x0[*jj] == 1) - qam64_table_offset_re0+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im0+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re0+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im0+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re0+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im0+=1; - *jj=*jj+1; + break; + + case 6: //64QAM + + + qam64_table_offset_re0 = 0; + qam64_table_offset_im0 = 0; + + if (x0[*jj] == 1) + qam64_table_offset_re0+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im0+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re0+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im0+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re0+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im0+=1; + *jj=*jj+1; - xx0_re = qam_table_s0[qam64_table_offset_re0]; - xx0_im = qam_table_s0[qam64_table_offset_im0]; + xx0_re = qam_table_s0[qam64_table_offset_re0]; + xx0_im = qam_table_s0[qam64_table_offset_im0]; + break; + + } - break; - - } - switch (mod_order1) { - default: - LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1); - xx1_re=xx1_im=0; - break; - case 2: //QPSK - // printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj2 = *jj2 + 1; - xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj2 = *jj2 + 1; - // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - break; - - case 4: //16QAM - - qam16_table_offset_re1 = 0; - qam16_table_offset_im1 = 0; - if (x1[*jj2] == 1) - qam16_table_offset_re1+=2; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam16_table_offset_im1+=2; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam16_table_offset_re1+=1; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam16_table_offset_im1+=1; - *jj2 = *jj2 + 1; + switch (mod_order1) { - xx1_re = qam_table_s1[qam16_table_offset_re1]; - xx1_im = qam_table_s1[qam16_table_offset_im1]; + default: + LOG_E(PHY,"Unknown mod_order1 %d\n",mod_order1); + xx1_re=xx1_im=0; + break; - break; - - case 6: //64QAM - - qam64_table_offset_re1 = 0; - qam64_table_offset_im1 = 0; - - if (x1[*jj2] == 1) - qam64_table_offset_re1+=4; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam64_table_offset_im1+=4; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam64_table_offset_re1+=2; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam64_table_offset_im1+=2; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam64_table_offset_re1+=1; - *jj2 = *jj2 + 1; - if (x1[*jj2] == 1) - qam64_table_offset_im1+=1; - *jj2 = *jj2 + 1; + case 2: //QPSK + //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj2 = *jj2 + 1; + xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj2 = *jj2 + 1; + //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + break; + + case 4: //16QAM + + qam16_table_offset_re1 = 0; + qam16_table_offset_im1 = 0; + if (x1[*jj2] == 1) + qam16_table_offset_re1+=2; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam16_table_offset_im1+=2; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam16_table_offset_re1+=1; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam16_table_offset_im1+=1; + *jj2 = *jj2 + 1; - xx1_re = qam_table_s1[qam64_table_offset_re1]; - xx1_im = qam_table_s1[qam64_table_offset_im1]; + xx1_re = qam_table_s1[qam16_table_offset_re1]; + xx1_im = qam_table_s1[qam16_table_offset_im1]; + break; + + case 6: //64QAM + + qam64_table_offset_re1 = 0; + qam64_table_offset_im1 = 0; + + if (x1[*jj2] == 1) + qam64_table_offset_re1+=4; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam64_table_offset_im1+=4; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam64_table_offset_re1+=2; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam64_table_offset_im1+=2; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam64_table_offset_re1+=1; + *jj2 = *jj2 + 1; + if (x1[*jj2] == 1) + qam64_table_offset_im1+=1; + *jj2 = *jj2 + 1; - break; - - } + xx1_re = qam_table_s1[qam64_table_offset_re1]; + xx1_im = qam_table_s1[qam64_table_offset_im1]; - // This implements the Large CDD precoding for 2 TX antennas - // - - - - - - - - - - - - - //| y0 | | 1 0 || 1 0 || 1 1 || x0 | | x0 + x1 | - //| y1 | = .5 | 0 1 || 0 (-1)^i || 1 -1 || x1 | = .5| (-1)^i(x0 - x1)| - // - - - - - - - - - - - - // Note: Factor .5 is accounted for in amplitude when calling this function - ((int16_t *)&txdataF[0][tti_offset])[0]+=((xx0_re+xx1_re)>>1); - ((int16_t *)&txdataF[1][tti_offset])[0]+=(s*((xx0_re-xx1_re)>>1)); - ((int16_t *)&txdataF[0][tti_offset])[1]+=((xx0_im+xx1_im)>>1); - ((int16_t *)&txdataF[1][tti_offset])[1]+=(s*((xx0_im-xx1_im)>>1)); - /* - printf("CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n", - xx0_re,xx0_im,xx1_re,xx1_im, s, ((int16_t *)&txdataF[0][tti_offset])[0],((int16_t *)&txdataF[0][tti_offset])[1], - ((int16_t *)&txdataF[1][tti_offset])[0],((int16_t *)&txdataF[1][tti_offset])[1]); - */ - // s alternates +1/-1 for each RE - s = -s; - } + break; + + } + + // This implements the Large CDD precoding for 2 TX antennas + // - - - - - - - - - - - - + //| y0 | | 1 0 || 1 0 || 1 1 || x0 | | x0 + x1 | + //| y1 | = .5 | 0 1 || 0 (-1)^i || 1 -1 || x1 | = .5| (-1)^i(x0 - x1)| + // - - - - - - - - - - - + // Note: Factor .5 is accounted for in amplitude when calling this function + ((int16_t *)&txdataF[0][tti_offset])[0]+=((xx0_re+xx1_re)>>1); + ((int16_t *)&txdataF[1][tti_offset])[0]+=(s*((xx0_re-xx1_re)>>1)); + ((int16_t *)&txdataF[0][tti_offset])[1]+=((xx0_im+xx1_im)>>1); + ((int16_t *)&txdataF[1][tti_offset])[1]+=(s*((xx0_im-xx1_im)>>1)); + /* + printf("CDD: xx0 (%d,%d), xx1(%d,%d), s(%d), txF[0] (%d,%d), txF[1] (%d,%d)\n", + xx0_re,xx0_im,xx1_re,xx1_im, s, ((int16_t *)&txdataF[0][tti_offset])[0],((int16_t *)&txdataF[0][tti_offset])[1], + ((int16_t *)&txdataF[1][tti_offset])[0],((int16_t *)&txdataF[1][tti_offset])[1]); + */ + // s alternates +1/-1 for each RE + s = -s; + } } - else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) { - // this is for transmission modes 5-6 (1 layer) - *re_allocated = *re_allocated + 1; - amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); + else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) { + // this is for transmission modes 5-6 (1 layer) + *re_allocated = *re_allocated + 1; + amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); - switch (mod_order0) { - case 2: //QPSK + switch (mod_order0) { + case 2: - ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj = *jj + 1; - ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj = *jj + 1; + ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; + ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; - // normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); + //normalization for 2 tx antennas + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); - } + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + } - break; - - case 4: //16QAM - - qam16_table_offset_re = 0; - qam16_table_offset_im = 0; + break; + + case 4: + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; - if (x0[*jj] == 1) - qam16_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=2; - *jj=*jj+1; - - - if (x0[*jj] == 1) - qam16_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=1; - *jj=*jj+1; - - - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); + if (x0[*jj] == 1) + qam16_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=2; + *jj=*jj+1; + + + if (x0[*jj] == 1) + qam16_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=1; + *jj=*jj+1; + + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); - } + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + } - break; - - case 6: //64QAM - - - qam64_table_offset_re = 0; - qam64_table_offset_im = 0; - if (x0[*jj] == 1) - qam64_table_offset_re+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=1; - *jj=*jj+1; - - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); + break; + + case 6: - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); - } - - break; - - } + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + if (x0[*jj] == 1) + qam64_table_offset_re+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); + + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + } + + break; + } } else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) { - // this is for transmission mode 4 (1 layer) - *re_allocated = *re_allocated + 1; + // this is for transmission mode 4 (1 layer) + *re_allocated = *re_allocated + 1; + if (precoder_index==0) { + precoder_index0 = 0; //[1 1] + precoder_index1 = 1; //[1 -1] + } + else if (precoder_index==1) { + precoder_index0 = 2; //[1 j] + precoder_index1 = 3; //[1 -j] + } + else { + printf("problem with precoder in TM4\n"); + return(-1); + } - if (precoder_index==0) { - precoder_index0 = 0; //[1 1] - precoder_index1 = 1; //[1 -1] - } - else if (precoder_index==1) { - precoder_index0 = 2; //[1 j] - precoder_index1 = 3; //[1 -j] - } - else { - printf("problem with precoder in TM4\n"); - return(-1); - } + switch (mod_order0) { + case 2: - switch (mod_order0) { - case 2: //QPSK + ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; + ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj = *jj + 1; - ((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj = *jj + 1; - ((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj = *jj + 1; + //normalization for 2 tx antennas + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - // normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + } - // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); - } + break; + + case 4: + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; - break; - - case 4: //16QAM - - qam16_table_offset_re = 0; - qam16_table_offset_im = 0; + if (x0[*jj] == 1) + qam16_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=2; + *jj=*jj+1; + + if (x0[*jj] == 1) + qam16_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam16_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + } - if (x0[*jj] == 1) - qam16_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=2; - *jj=*jj+1; - - - if (x0[*jj] == 1) - qam16_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam16_table_offset_im+=1; - *jj=*jj+1; - - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); - } + break; + + case 6: + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; - break; - - case 6: //64QAM - - - qam64_table_offset_re = 0; - qam64_table_offset_im = 0; - if (x0[*jj] == 1) - qam64_table_offset_re+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=4; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=2; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_re+=1; - *jj=*jj+1; - if (x0[*jj] == 1) - qam64_table_offset_im+=1; - *jj=*jj+1; - - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); - } - - break; - - } - - if (dlsch1_harq) { - switch (mod_order1) { - case 2: //QPSK + if (x0[*jj] == 1) + qam64_table_offset_re+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=4; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=2; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_re+=1; + *jj=*jj+1; + if (x0[*jj] == 1) + qam64_table_offset_im+=1; + *jj=*jj+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + } + + break; + + } + + if (dlsch1_harq) { + switch (mod_order1) { + + case 2: - ((int16_t*)&tmp_sample1)[0] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj2 = *jj2 + 1; - ((int16_t*)&tmp_sample1)[1] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; - *jj2 = *jj2 + 1; + ((int16_t*)&tmp_sample1)[0] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj2 = *jj2 + 1; + ((int16_t*)&tmp_sample1)[1] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + *jj2 = *jj2 + 1; - // normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + //normalization for 2 tx antennas + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); - } + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + } - break; - - case 4: //16QAM - - qam16_table_offset_re = 0; - qam16_table_offset_im = 0; + break; + + case 4: + + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; - if (x1[*jj2] == 1) - qam16_table_offset_re+=2; - *jj2=*jj2+1; - if (x1[*jj2] == 1) - qam16_table_offset_im+=2; - *jj2=*jj2+1; - - - if (x1[*jj2] == 1) - qam16_table_offset_re+=1; - *jj2=*jj2+1; - if (x1[*jj2] == 1) - qam16_table_offset_im+=1; - *jj2=*jj2+1; - - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re])); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); - } + if (x1[*jj2] == 1) + qam16_table_offset_re+=2; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam16_table_offset_im+=2; + *jj2=*jj2+1; + + + if (x1[*jj2] == 1) + qam16_table_offset_re+=1; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam16_table_offset_im+=1; + *jj2=*jj2+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + } - break; - - case 6: //64QAM - - - qam64_table_offset_re = 0; - qam64_table_offset_im = 0; - if (x1[*jj2] == 1) - qam64_table_offset_re+=4; - *jj2=*jj2+1; - if (x1[*jj2] == 1) - qam64_table_offset_im+=4; - *jj2=*jj2+1; - if (x1[*jj2] == 1) - qam64_table_offset_re+=2; - *jj2=*jj2+1; - if (x1[*jj2] == 1) - qam64_table_offset_im+=2; - *jj2=*jj2+1; - if (x1[*jj2] == 1) - qam64_table_offset_re+=1; - *jj2=*jj2+1; - if (x1[*jj2] == 1) - qam64_table_offset_im+=1; - *jj2=*jj2+1; - - ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re])); - ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - - if (frame_parms->nb_antennas_tx == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); - } - - break; - - } - } + break; + + case 6: + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + if (x1[*jj2] == 1) + qam64_table_offset_re+=4; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_im+=4; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_re+=2; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_im+=2; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_re+=1; + *jj2=*jj2+1; + if (x1[*jj2] == 1) + qam64_table_offset_im+=1; + *jj2=*jj2+1; + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re])); + ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im])); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + } + + break; + + } + } } @@ -1042,7 +1036,6 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, case 6: //64QAM - qam64_table_offset_re = 0; qam64_table_offset_im = 0; @@ -1090,10 +1083,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, return(-1); } } - - } - return(0); } @@ -1145,14 +1135,14 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, tti_offset = symbol_offset + re_off + re; - // printf("re %d (jj %d)\n",re,*jj); + //printf("re %d (jj %d)\n",re,*jj); *re_allocated = *re_allocated + 1; switch (mod_order) { - case 2: //QPSK + case 2: - // printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); for (aa=0; aanb_antennas_tx; aa++) ((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i @@ -1163,10 +1153,10 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, *jj = *jj + 1; - // printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; - case 4: //16QAM + case 4: qam16_table_offset_re = 0; qam16_table_offset_im = 0; @@ -1195,14 +1185,13 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, for (aa=0; aanb_antennas_tx; aa++) { ((int16_t *)&txdataF[aa][tti_offset])[0]+=qam_table_s[qam16_table_offset_re]; ((int16_t *)&txdataF[aa][tti_offset])[1]+=qam_table_s[qam16_table_offset_im]; - // ((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - // ((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + //((int16_t *)&txdataF[aa][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + //((int16_t *)&txdataF[aa][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); } break; - case 6: //64QAM - + case 6: qam64_table_offset_re = 0; qam64_table_offset_im = 0; @@ -1374,13 +1363,13 @@ int dlsch_modulation(int32_t **txdataF, #ifdef DEBUG_DLSCH_MODULATION printf("Generating DLSCH (harq_pid %d,mimo %d, pmi_alloc0 %lx, mod0 %d, mod1 %d, rb_alloc[0] %d) in %d\n", - harq_pid, - dlsch0_harq->mimo_mode, - pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), - mod_order0, - mod_order1, - rb_alloc[0], - len); + harq_pid, + dlsch0_harq->mimo_mode, + pmi2hex_2Ar2(dlsch0_harq->pmi_alloc), + mod_order0, + mod_order1, + rb_alloc[0], + len); #endif if (frame_parms->Ncp==0) { // normal prefix @@ -1403,7 +1392,7 @@ int dlsch_modulation(int32_t **txdataF, symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); //for (aa=0;aanb_antennas_tx;aa++) - // memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2); + //memset(&txdataF[aa][symbol_offset],0,frame_parms->ofdm_symbol_size<<2); //printf("symbol_offset %d,subframe offset %d : pilots %d\n",symbol_offset,subframe_offset,pilots); for (rb=0; rbN_RB_DL; rb++) { @@ -1567,28 +1556,27 @@ int dlsch_modulation(int32_t **txdataF, if (rb_alloc_ind > 0) { // printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj); - allocate_REs_in_RB(frame_parms, - txdataF, - &jj, - &jj2, - re_offset, - symbol_offset, - dlsch0->harq_processes[harq_pid], - (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid], - pilots, - ((pilots) ? amp_rho_b : amp_rho_a), - get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), - qam_table_s0, - qam_table_s1, - &re_allocated, - skip_dc, - skip_half); + allocate_REs_in_RB(frame_parms, + txdataF, + &jj, + &jj2, + re_offset, + symbol_offset, + dlsch0->harq_processes[harq_pid], + (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid], + pilots, + ((pilots) ? amp_rho_b : amp_rho_a), + get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), + qam_table_s0, + qam_table_s1, + &re_allocated, + skip_dc, + skip_half); } re_offset+=12; // go to next RB - // check if we crossed the symbol boundary and skip DC if (re_offset >= frame_parms->ofdm_symbol_size) { if (skip_dc == 0) //even number of RBs (doesn't straddle DC) @@ -1597,11 +1585,8 @@ int dlsch_modulation(int32_t **txdataF, re_offset=7; // odd number of RBs } } - } - - #ifdef DEBUG_DLSCH_MODULATION msg("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset)); #endif @@ -1618,7 +1603,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch0, LTE_eNB_DLSCH_t *dlsch1, - int G) + int G) { uint8_t nsymb; @@ -1644,113 +1629,111 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, amp=1; //we do full scale here for SIC gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15)); - // printf("gain=%d\n", gain_lin_QPSK); + //printf("gain=%d\n", gain_lin_QPSK); jj = 0; i = 0; while (jj <= G-1) { - re_allocated = re_allocated + 1; + re_allocated = re_allocated + 1; - switch (mod_order0) { - case 2: //QPSK - /* TODO: handle more than 1 antenna */ - // printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); + switch (mod_order0) { + case 2: //QPSK + /* TODO: handle more than 1 antenna */ + //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - ((int16_t*)&sic_buffer[0][i])[0] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i + ((int16_t*)&sic_buffer[0][i])[0] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i - jj = jj + 1; + jj = jj + 1; - ((int16_t*)&sic_buffer[0][i])[1] += (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} + ((int16_t*)&sic_buffer[0][i])[1] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} - jj = jj + 1; + jj = jj + 1; - // printf("recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); - - i++; + //printf("recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); + i++; - break; + break; - case 4: //16QAM + case 4: //16QAM - qam16_table_offset_re = 0; - qam16_table_offset_im = 0; + qam16_table_offset_re = 0; + qam16_table_offset_im = 0; - if (x0[jj] == 1) - qam16_table_offset_re+=2; + if (x0[jj] == 1) + qam16_table_offset_re+=2; - jj=jj+1; + jj=jj+1; - if (x0[jj] == 1) - qam16_table_offset_im+=2; + if (x0[jj] == 1) + qam16_table_offset_im+=2; - jj=jj+1; + jj=jj+1; - if (x0[jj] == 1) - qam16_table_offset_re+=1; + if (x0[jj] == 1) + qam16_table_offset_re+=1; - jj=jj+1; + jj=jj+1; - if (x0[jj] == 1) - qam16_table_offset_im+=1; + if (x0[jj] == 1) + qam16_table_offset_im+=1; - jj=jj+1; + jj=jj+1; - ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re]; - ((int16_t *)&sic_buffer[0][i])[1]+=qam16_table[qam16_table_offset_im]; - - i++; + ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re]; + ((int16_t *)&sic_buffer[0][i])[1]+=qam16_table[qam16_table_offset_im]; + + i++; - break; + break; - case 6: //64QAM + case 6: + + qam64_table_offset_re = 0; + qam64_table_offset_im = 0; + + if (x0[jj] == 1) + qam64_table_offset_re+=4; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_im+=4; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_re+=2; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_im+=2; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_re+=1; + + jj=jj+1; + + if (x0[jj] == 1) + qam64_table_offset_im+=1; + + jj=jj+1; - qam64_table_offset_re = 0; - qam64_table_offset_im = 0; - - if (x0[jj] == 1) - qam64_table_offset_re+=4; - - jj=jj+1; - - if (x0[jj] == 1) - qam64_table_offset_im+=4; - - jj=jj+1; - - if (x0[jj] == 1) - qam64_table_offset_re+=2; - - jj=jj+1; - - if (x0[jj] == 1) - qam64_table_offset_im+=2; - - jj=jj+1; - - if (x0[jj] == 1) - qam64_table_offset_re+=1; - - jj=jj+1; - - if (x0[jj] == 1) - qam64_table_offset_im+=1; - - jj=jj+1; - - - ((int16_t *)&sic_buffer[0][i])[0]+=(qam64_table[qam64_table_offset_re])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); - ((int16_t *)&sic_buffer[0][i])[1]+=(qam64_table[qam64_table_offset_im])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - - i++; + ((int16_t *)&sic_buffer[0][i])[0]+=(qam64_table[qam64_table_offset_re])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); + ((int16_t *)&sic_buffer[0][i])[1]+=(qam64_table[qam64_table_offset_im])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); + + i++; - break; + break; } - } + } #ifdef DEBUG_DLSCH_MODULATION @@ -1807,14 +1790,13 @@ int mch_modulation(int32_t **txdataF, if ((frame_parms->N_RB_DL&1) == 1) { // ODD N_RB_DL - if (rb==(frame_parms->N_RB_DL>>1)) + if (rb==(frame_parms->N_RB_DL>>1)) skip_dc = 1; else skip_dc = 0; } - if (mod_order == 4) qam_table_s = qam16_table_a; else if (mod_order == 6) @@ -1822,7 +1804,7 @@ int mch_modulation(int32_t **txdataF, else qam_table_s = NULL; - // printf("Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp); + //printf("Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp); allocate_REs_in_RB_MCH(txdataF, &jj, re_offset, @@ -1838,7 +1820,6 @@ int mch_modulation(int32_t **txdataF, re_offset+=12; // go to next RB - // check if we crossed the symbol boundary and skip DC if (re_offset >= frame_parms->ofdm_symbol_size) { if (skip_dc == 0) //even number of RBs (doesn't straddle DC) @@ -1849,10 +1830,6 @@ int mch_modulation(int32_t **txdataF, } } - - - - #ifdef DEBUG_DLSCH_MODULATION msg("generate_dlsch(MCH) : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->rb_alloc,mod_order,1,2,0,subframe_offset)); #endif diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index affe895f10..49635d386d 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -238,7 +238,7 @@ int main(int argc, char **argv) int common_flag=0,TPC=0; double cpu_freq_GHz; - // time_stats_t ts;//,sts,usts; + //time_stats_t ts;//,sts,usts; int avg_iter[2],iter_trials[2]; int rballocset=0; int print_perf=0; @@ -252,8 +252,8 @@ int main(int argc, char **argv) int TB0_active = 1; uint32_t perfect_ce = 0; - LTE_DL_UE_HARQ_t *dlsch0_ue_harq; - LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; + LTE_DL_UE_HARQ_t *dlsch0_ue_harq; + LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; uint8_t Kmimo; int32_t **sic_buffer; @@ -435,174 +435,170 @@ int main(int argc, char **argv) case 'B': channel_model=SCM_B; break; - case 'C': channel_model=SCM_C; break; - case 'D': channel_model=SCM_D; break; - case 'E': channel_model=EPA; break; - - case 'F': - channel_model=EVA; - break; - case 'G': - channel_model=ETU; - break; - case 'H': - channel_model=Rayleigh8; - break; - case 'I': - channel_model=Rayleigh1; - break; - case 'J': - channel_model=Rayleigh1_corr; - break; - case 'K': - channel_model=Rayleigh1_anticorr; - break; - case 'L': - channel_model=Rice8; - break; - case 'M': - channel_model=Rice1; - break; - case 'N': - channel_model=AWGN; - break; - case 'P': - channel_model=Rayleigh1_orthogonal; - break; - case 'Q': - channel_model=Rayleigh1_orth_eff_ch_TM4_prec_real; // for DUALSTREAM_UNIFORM_PRECODING1 when interf is precancelled - break; - case 'R': - channel_model=Rayleigh1_orth_eff_ch_TM4_prec_imag; // for DUALSTREAM_UNIFORM_PRECODINGj when interf is precancelled - break; - case 'S': - channel_model=Rayleigh8_orth_eff_ch_TM4_prec_real;//when interf is precancelled - break; - case 'T': - channel_model=Rayleigh8_orth_eff_ch_TM4_prec_imag;//when interf is precancelled - break; - case 'U': - channel_model = TS_SHIFT; - break; - default: - msg("Unsupported channel model!\n"); - exit(-1); - } - break; + case 'F': + channel_model=EVA; + break; + case 'G': + channel_model=ETU; + break; + case 'H': + channel_model=Rayleigh8; + break; + case 'I': + channel_model=Rayleigh1; + break; + case 'J': + channel_model=Rayleigh1_corr; + break; + case 'K': + channel_model=Rayleigh1_anticorr; + break; + case 'L': + channel_model=Rice8; + break; + case 'M': + channel_model=Rice1; + break; + case 'N': + channel_model=AWGN; + break; + case 'P': + channel_model=Rayleigh1_orthogonal; + break; + case 'Q': + channel_model=Rayleigh1_orth_eff_ch_TM4_prec_real; // for DUALSTREAM_UNIFORM_PRECODING1 when interf is precancelled + break; + case 'R': + channel_model=Rayleigh1_orth_eff_ch_TM4_prec_imag; // for DUALSTREAM_UNIFORM_PRECODINGj when interf is precancelled + break; + case 'S': + channel_model=Rayleigh8_orth_eff_ch_TM4_prec_real;//when interf is precancelled + break; + case 'T': + channel_model=Rayleigh8_orth_eff_ch_TM4_prec_imag;//when interf is precancelled + break; + case 'U': + channel_model = TS_SHIFT; + break; + default: + msg("Unsupported channel model!\n"); + exit(-1); + } + break; case 'x': - transmission_mode=atoi(optarg); - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=3) && - (transmission_mode!=4) && - (transmission_mode!=5) && - (transmission_mode!=6)) { - msg("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } - if (transmission_mode>1) { - n_tx = 2; - } - break; + transmission_mode=atoi(optarg); + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=3) && + (transmission_mode!=4) && + (transmission_mode!=5) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } + if (transmission_mode>1) { + n_tx = 2; + } + break; case 'y': - n_tx=atoi(optarg); - if ((n_tx==0) || (n_tx>2)) { - msg("Unsupported number of tx antennas %d\n",n_tx); - exit(-1); - } - break; + n_tx=atoi(optarg); + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } + break; case 'z': - n_rx=atoi(optarg); - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } - break; + n_rx=atoi(optarg); + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } + break; case 'R': - num_rounds=atoi(optarg); - break; + num_rounds=atoi(optarg); + break; case 'S': - subframe=atoi(optarg); - break; + subframe=atoi(optarg); + break; case 'T': - n_rnti=atoi(optarg); - break; + n_rnti=atoi(optarg); + break; case 'u': - rx_type = (RX_type_t) atoi(optarg); - if (rx_typerx_SIC_dual_stream) { - printf("Unsupported rx type %d\n",rx_type); - exit(-1); - } - break; + rx_type = (RX_type_t) atoi(optarg); + if (rx_typerx_SIC_dual_stream) { + printf("Unsupported rx type %d\n",rx_type); + exit(-1); + } + break; case 'v': - i_mod = atoi(optarg); - if (i_mod!=2 && i_mod!=4 && i_mod!=6) { - msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); - exit(-1); - } - break; + i_mod = atoi(optarg); + if (i_mod!=2 && i_mod!=4 && i_mod!=6) { + msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + exit(-1); + } + break; case 'P': - print_perf=1; - break; + print_perf=1; + break; case 'X': - xforms = 1; - break; + xforms = 1; + break; case 'Z': - dump_table=1; - break; + dump_table=1; + break; case 'Y': - perfect_ce=1; - break; + perfect_ce=1; + break; case 'V': - interf_unaw_shift0=atoi(optarg); - break; + interf_unaw_shift0=atoi(optarg); + break; case 'W': - interf_unaw_shift1=atoi(optarg); - break; + interf_unaw_shift1=atoi(optarg); + break; case 'J': - interf_unaw_shift=atoi(optarg); - break; + interf_unaw_shift=atoi(optarg); + break; case 'h': default: - printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-c Number of PDCCH symbols\n"); - printf("-m MCS1 for TB 1\n"); - printf("-M MCS2 for TB 2\n"); - printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n"); - printf("-p Use extended prefix mode\n"); - printf("-n Number of frames to simulate\n"); - printf("-o Sample offset for receiver\n"); - printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); - printf("-f step size of SNR, default value is 1.\n"); - printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); - printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T') \n"); - printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-t MCS of interfering UE\n"); - printf("-R Number of HARQ rounds (fixed)\n"); - printf("-A Turns on calibration mode for abstraction.\n"); - printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); - printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); - printf("-I Input filename for TrCH data (binary)\n"); - printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n"); - exit(1); - break; + printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); + printf("-h This message\n"); + printf("-a Use AWGN channel and not multipath\n"); + printf("-c Number of PDCCH symbols\n"); + printf("-m MCS1 for TB 1\n"); + printf("-M MCS2 for TB 2\n"); + printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n"); + printf("-p Use extended prefix mode\n"); + printf("-n Number of frames to simulate\n"); + printf("-o Sample offset for receiver\n"); + printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); + printf("-f step size of SNR, default value is 1.\n"); + printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); + printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T') \n"); + printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-t MCS of interfering UE\n"); + printf("-R Number of HARQ rounds (fixed)\n"); + printf("-A Turns on calibration mode for abstraction.\n"); + printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); + printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); + printf("-I Input filename for TrCH data (binary)\n"); + printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n"); + exit(1); + break; - } + } } if (common_flag == 0) { @@ -668,22 +664,21 @@ int main(int argc, char **argv) n_users = 2; eNB_id_i = PHY_vars_UE->n_connected_eNB; //eNB_id_i=1; - } else eNB_id_i = eNB_id; lte_param_init(n_tx, - n_rx, - transmission_mode, - extended_prefix_flag, - frame_type, - Nid_cell, - tdd_config, - N_RB_DL, - threequarter_fs, - osf, - perfect_ce); + n_rx, + transmission_mode, + extended_prefix_flag, + frame_type, + Nid_cell, + tdd_config, + N_RB_DL, + threequarter_fs, + osf, + perfect_ce); printf("Setting mcs1 = %d\n",mcs1); @@ -721,19 +716,19 @@ int main(int argc, char **argv) printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d, Rayleigh1_orthogonal=%d, Rayleigh1_orth_eff_ch_TM4_prec_real22=%d, Rayleigh1_orth_eff_ch_TM4_prec_imag=%d, Rayleigh8_orth_eff_ch_TM4_prec_real=%d, Rayleigh8_orth_eff_ch_TM4_prec_imag=%d , TS_SHIFT=%d\n", - SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); + SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); if(transmission_mode==5) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); - else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + else + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -742,7 +737,7 @@ int main(int argc, char **argv) } fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; dci_err\n"); - if (test_perf != 0) { + if (test_perf != 0) { char hostname[1024]; @@ -769,9 +764,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pmnew.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); - else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pmnew.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pmnew.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + else + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pmnew.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); @@ -943,7 +938,7 @@ n(tikz_fname,"w"); PHY_vars_UE->lte_frame_parms.nb_antennas_rx, channel_model, N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, 0); @@ -953,9 +948,9 @@ n(tikz_fname,"w"); eNB2UE[n] = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, PHY_vars_UE->lte_frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - forgetting_factor, + N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + forgetting_factor, rx_sample_offset, 0); } @@ -1035,8 +1030,6 @@ n(tikz_fname,"w"); } if (input_fd==NULL) { - - /* // common DCI memcpy(&dci_alloc[num_dci].dci_pdu[0],&CCCH_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); @@ -1052,887 +1045,886 @@ n(tikz_fname,"w"); switch(transmission_mode) { case 1: case 2: - if (common_flag == 0) { - - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1_10MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1_20MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); - break; - } - } - else { //fdd - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - dci_length = sizeof_DCI1_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = n_rnti+k; - dci_alloc[num_dci].format = format1; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + if (common_flag == 0) { + + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1_1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1_10MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1_20MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); + break; + } + } + else { //fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format1; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format1, - PHY_vars_eNB->dlsch_eNB[0], - &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); - num_dci++; - num_ue_spec_dci++; - } - else { //common flag =1 - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } - else { // fdd - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = SI_RNTI; - dci_alloc[num_dci].format = format1A; - dci_alloc[num_dci].firstCCE = 0; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format1, + PHY_vars_eNB->dlsch_eNB[0], + &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); + num_dci++; + num_ue_spec_dci++; + } + else { //common flag =1 + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } + else { // fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - PHY_vars_eNB->dlsch_eNB[0], - &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); - - num_common_dci++; - num_dci++; - - } - break; + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_common_dci++; + num_dci++; + + } + break; case 3: //LARGE CDD - if (common_flag == 0) { - - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) {// here DCI does not contain any precoder information. matrix is fixed as identity, but dont forget aboy cycling + if (common_flag == 0) { + + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) {// here DCI does not contain any precoder information. matrix is fixed as identity, but dont forget aboy cycling - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - case 100: - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); - break; - } - } - - else { // fdd - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - case 100: - dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - } - } - } - else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { //4 antenna, needs diff precoding codebook index depeneding on layers + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 25: + dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 50: + dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 100: + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); + break; + } + } + + else { // fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 25: + dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 50: + dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 100: + dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + } + } + } + else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { //4 antenna, needs diff precoding codebook index depeneding on layers - } - - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = n_rnti+k; - dci_alloc[num_dci].format = format2A; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - - printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2A, - PHY_vars_eNB->dlsch_eNB[0], - &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); - - num_dci++; - num_ue_spec_dci++; - } - else { //commonn flag 1 - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { //tdd - - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } - else { //fdd - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = SI_RNTI; - dci_alloc[num_dci].format = format1A; - dci_alloc[num_dci].firstCCE = 0; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - PHY_vars_eNB->dlsch_eNB[0], - &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); - - num_common_dci++; - num_dci++; - - } - printf("Generated DCI format 2A (Transmission Mode 3)\n"); - break; + } + + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format2A; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_dci++; + num_ue_spec_dci++; + } + else { //commonn flag 1 + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { //tdd + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } + else { //fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_common_dci++; + num_dci++; + + } + printf("Generated DCI format 2A (Transmission Mode 3)\n"); + break; case 4: // !!! this dci format contains precoder information - if (common_flag == 0) { - - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) { + if (common_flag == 0) { + + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) { - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - break; - case 25: - dci_length = sizeof_DCI2_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 25: + dci_length = sizeof_DCI2_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - break; - case 50: - dci_length = sizeof_DCI2_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 50: + dci_length = sizeof_DCI2_10MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - break; - case 100: - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - dci_length = sizeof_DCI2_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); - break; - } - } - - else { - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - break; - case 25: - dci_length = sizeof_DCI2_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - break; - case 50: - dci_length = sizeof_DCI2_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - break; - case 100: - dci_length = sizeof_DCI2_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; - break; - } - } - } - else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { + break; + case 100: + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + dci_length = sizeof_DCI2_20MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); + break; + } + } + + else { + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 25: + dci_length = sizeof_DCI2_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 50: + dci_length = sizeof_DCI2_10MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 100: + dci_length = sizeof_DCI2_20MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + } + } + } + else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { - } - - printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); - if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { + } + + printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); + if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { - PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); - - } - - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = n_rnti+k; - dci_alloc[num_dci].format = format2; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2, - PHY_vars_eNB->dlsch_eNB[0], - &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); - - num_dci++; - num_ue_spec_dci++; - } - else { //common_flag==1 - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } - else { - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = SI_RNTI; - dci_alloc[num_dci].format = format1A; - dci_alloc[num_dci].firstCCE = 0; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); + + } + + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format2; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_dci++; + num_ue_spec_dci++; + } + else { //common_flag==1 + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } + else { + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - PHY_vars_eNB->dlsch_eNB[0], - &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); - - num_common_dci++; - num_dci++; - - } - break; + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_common_dci++; + num_dci++; + } + break; case 5: case 6: @@ -1944,7 +1936,7 @@ n(tikz_fname,"w"); dci_alloc[num_dci].firstCCE = 4*k; printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, - subframe, + subframe, &DLSCH_alloc_pdu2_1E[k], n_rnti+k, format1E_2A_M10PRB, @@ -1979,11 +1971,13 @@ n(tikz_fname,"w"); */ } - if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE); + if (n_frames==1) + printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE); numCCE = get_nCCE(num_pdcch_symbols,&PHY_vars_eNB->lte_frame_parms,get_mi(&PHY_vars_eNB->lte_frame_parms,subframe)); - if (n_frames==1) printf("%d\n",numCCE); + if (n_frames==1) + printf("%d\n",numCCE); // apply RNTI-based nCCE allocation memset(CCE_table,0,800*sizeof(int)); @@ -1991,11 +1985,11 @@ n(tikz_fname,"w"); for (i=num_common_dci; iframe_rx=0; for (i=0; i<4; i++) { - errs[0][i]=0; - errs[1][i]=0; - round_trials[i] = 0; + errs[0][i]=0; + errs[1][i]=0; + round_trials[i] = 0; } dci_errors=0; - // avg_ber = 0; + //avg_ber = 0; round=0; avg_iter[0] = 0; @@ -2115,1066 +2109,1061 @@ n(tikz_fname,"w"); initialize(&time_vector_rx_dec); for (trials = 0;trialsnb_antennas_tx; i++) { - memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); - } - //if (trials%100==0) - eNB2UE[0]->first_run = 1; + // printf("Trial %d\n",trials); + fflush(stdout); + round=0; + for (i=0; inb_antennas_tx; i++) { + memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + } + //if (trials%100==0) + eNB2UE[0]->first_run = 1; - ret[0] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; - ret[1] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; - while ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) { - // printf("Trial %d, round %d\n",trials,round); - round_trials[round]++; + ret[0] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; + ret[1] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; + while ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) { + //printf("Trial %d, round %d\n",trials,round); + round_trials[round]++; - if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) - pmi_feedback=1; - else - pmi_feedback=0; - - if (abstx) { - if (trials==0 && round==0 && SNR==snr0) //generate a new channel - hold_channel = 0; - else - hold_channel = 1; - } - else - hold_channel = 0;//(round==0) ? 0 : 1; + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) + pmi_feedback=1; + else + pmi_feedback=0; + + if (abstx) { + if (trials==0 && round==0 && SNR==snr0) //generate a new channel + hold_channel = 0; + else + hold_channel = 1; + } + else + hold_channel = 0;//(round==0) ? 0 : 1; - PMI_FEEDBACK: - - // printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); - for (aa=0; aalte_frame_parms.nb_antennas_tx;aa++) { - memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); - } - - if (input_fd==NULL) { + PMI_FEEDBACK: + + //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); + for (aa=0; aalte_frame_parms.nb_antennas_tx;aa++) { + memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + } + + if (input_fd==NULL) { - start_meas(&PHY_vars_eNB->phy_proc_tx); + start_meas(&PHY_vars_eNB->phy_proc_tx); - // Simulate HARQ procedures!!! - if (common_flag == 0) { - - if (round == 0) { // First round - TB0_active = 1; - - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - - switch (transmission_mode) { - case 1: - case 2: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); - break; - case 25: - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); - break; - case 50: - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); - break; - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); - break; - } - break; - case 3: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); - break; - case 25: - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); - break; - case 50: - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); - break; - case 100: - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); - break; - } - break; - case 4: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); - break; - case 25: - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); - break; - case 50: - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); - break; - case 100: - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); - break; - } - break; - - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; - } - } - else { // FDD - switch (transmission_mode) { - case 1: - case 2: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); - break; - case 25: - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); - break; - case 50: - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); - break; - case 100: - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); - break; - } - break; - case 3: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); - break; - case 25: - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); - break; - case 50: - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); - break; - case 100: - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); - break; - } - break; - case 4: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); - break; - case 25: - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); - break; - case 50: - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); - break; - case 100: - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); - break; - } - break; - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; - } - - } - } - else { - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; - - if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - - - switch (transmission_mode) { - case 1: - case 2: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); - break; - case 25: - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); - break; - case 50: - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); - break; - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); - break; - } - break; - case 3: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - if (TB0_active==1) { - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); - break; - case 25: - if (TB0_active==1) { - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); - break; - case 50: - if (TB0_active==1) { - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); - break; - case 100: - if (TB0_active==1) { - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); - break; - } - break; - case 4: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - if (TB0_active==1) { - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); - break; - case 25: - if (TB0_active==1) { - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); - break; - case 50: - if (TB0_active==1) { - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); - break; - case 100: - if (TB0_active==1) { - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); - break; - } - break; - - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; - } - } - else { - switch (transmission_mode) { - case 1: - case 2: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); - break; - case 25: - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); - break; - case 50: - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); - break; - case 100: - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); - break; - } - break; - case 3: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - if (TB0_active==1) { - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); - break; - case 25: - if (TB0_active==1) { - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); - break; - case 50: - if (TB0_active==1) { - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); - break; - case 100: - if (TB0_active==1) { - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); - break; - } - break; - case 4: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - if (TB0_active==1) { - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); - break; - case 25: - if (TB0_active==1) { - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); - break; - case 50: - if (TB0_active==1) { - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); - break; - case 100: - if (TB0_active==1) { - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - else { // deactivate TB0 - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); - break; - } - break; - - - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; - } - } - } - } - - num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci, - num_common_dci, - dci_alloc, - 0, - AMP, - &PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], - subframe); + // Simulate HARQ procedures!!! + if (common_flag == 0) { + + if (round == 0) { // First round + TB0_active = 1; + + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); + break; + case 25: + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); + break; + case 50: + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); + break; + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); + break; + case 25: + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); + break; + case 50: + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); + break; + case 100: + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); + break; + case 25: + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); + break; + case 50: + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); + break; + case 100: + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); + break; + } + break; + + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + } + else { // FDD + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); + break; + case 25: + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); + break; + case 50: + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); + break; + case 100: + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); + break; + case 25: + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); + break; + case 50: + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); + break; + case 100: + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); + break; + case 25: + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); + break; + case 50: + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); + break; + case 100: + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); + break; + } + break; + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + + } + } + else { + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); + break; + case 25: + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); + break; + case 50: + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); + break; + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); + break; + case 25: + if (TB0_active==1) { + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); + break; + case 50: + if (TB0_active==1) { + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); + break; + case 100: + if (TB0_active==1) { + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); + break; + case 25: + if (TB0_active==1) { + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); + break; + case 50: + if (TB0_active==1) { + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); + break; + case 100: + if (TB0_active==1) { + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); + break; + } + break; + + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + } + else { + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); + break; + case 25: + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); + break; + case 50: + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); + break; + case 100: + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); + break; + case 25: + if (TB0_active==1) { + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); + break; + case 50: + if (TB0_active==1) { + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); + break; + case 100: + if (TB0_active==1) { + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); + break; + case 25: + if (TB0_active==1) { + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); + break; + case 50: + if (TB0_active==1) { + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); + break; + case 100: + if (TB0_active==1) { + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); + break; + } + break; + + + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + } + } + } + + num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci, + num_common_dci, + dci_alloc, + 0, + AMP, + &PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + subframe); - if (num_pdcch_symbols_2 > num_pdcch_symbols) { - msg("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols); - exit(-1); - } + if (num_pdcch_symbols_2 > num_pdcch_symbols) { + msg("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols); + exit(-1); + } - for (k=0;klte_frame_parms, - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0,subframe); + for (k=0;klte_frame_parms, + PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0,subframe); -#ifdef TBS_FIX // This is for MESH operation!!! + #ifdef TBS_FIX // This is for MESH operation!!! tbs = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][cw]->nb_rb-1]/4; -#else + #else tbs = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->TBS; -#endif + #endif - rate = (double)tbs/(double)coded_bits_per_codeword; - - if ((SNR==snr0) && (trials==0) && (round==0) && (pmi_feedback==0)) - printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", - k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), - coded_bits_per_codeword, - tbs, - get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), - num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->round); + rate = (double)tbs/(double)coded_bits_per_codeword; + + if ((SNR==snr0) && (trials==0) && (round==0) && (pmi_feedback==0)) + printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", + k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), + coded_bits_per_codeword, + tbs, + get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), + num_pdcch_symbols, + PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->round); - // use the PMI from previous trial - if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); - PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); - if (n_users>1) - PHY_vars_eNB->dlsch_eNB[1][0]->harq_processes[0]->pmi_alloc = (PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); - /* - if ((trials<10) && (round==0)) { - printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[0][0]->pmi_alloc),pmi_feedback); - if (transmission_mode ==5) - printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[1][0]->pmi_alloc)); - } - */ - } - - - if (transmission_mode==4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); - PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); - } - - + // use the PMI from previous trial + if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + if (n_users>1) + PHY_vars_eNB->dlsch_eNB[1][0]->harq_processes[0]->pmi_alloc = (PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); + /* + if ((trials<10) && (round==0)) { + printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[0][0]->pmi_alloc),pmi_feedback); + if (transmission_mode ==5) + printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[1][0]->pmi_alloc)); + } + */ + } + + + if (transmission_mode==4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + - start_meas(&PHY_vars_eNB->dlsch_encoding_stats); - if (dlsch_encoding(((cw==0) ? input_buffer0[k] : input_buffer1[k]), - &PHY_vars_eNB->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][cw], - 0,subframe, - &PHY_vars_eNB->dlsch_rate_matching_stats, - &PHY_vars_eNB->dlsch_turbo_encoding_stats, - &PHY_vars_eNB->dlsch_interleaving_stats - )<0) - exit(-1); - - - - /* - if (transmission_mode == 3) { - if (dlsch_encoding(input_buffer1[k], - &PHY_vars_eNB->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][1], - 0,subframe, - &PHY_vars_eNB->dlsch_rate_matching_stats, - &PHY_vars_eNB->dlsch_turbo_encoding_stats, - &PHY_vars_eNB->dlsch_interleaving_stats - )<0) - exit(-1); - } - */ - stop_meas(&PHY_vars_eNB->dlsch_encoding_stats); + start_meas(&PHY_vars_eNB->dlsch_encoding_stats); + if (dlsch_encoding(((cw==0) ? input_buffer0[k] : input_buffer1[k]), + &PHY_vars_eNB->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_eNB->dlsch_eNB[k][cw], + 0,subframe, + &PHY_vars_eNB->dlsch_rate_matching_stats, + &PHY_vars_eNB->dlsch_turbo_encoding_stats, + &PHY_vars_eNB->dlsch_interleaving_stats)<0) + exit(-1); + + + + /* + if (transmission_mode == 3) { + if (dlsch_encoding(input_buffer1[k], + &PHY_vars_eNB->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_eNB->dlsch_eNB[k][1], + 0,subframe, + &PHY_vars_eNB->dlsch_rate_matching_stats, + &PHY_vars_eNB->dlsch_turbo_encoding_stats, + &PHY_vars_eNB->dlsch_interleaving_stats + )<0) + exit(-1); + } + */ + stop_meas(&PHY_vars_eNB->dlsch_encoding_stats); - PHY_vars_eNB->dlsch_eNB[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; - start_meas(&PHY_vars_eNB->dlsch_scrambling_stats); - dlsch_scrambling(&PHY_vars_eNB->lte_frame_parms, - 0, - PHY_vars_eNB->dlsch_eNB[k][cw], - coded_bits_per_codeword, - cw, - subframe<<1); - stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); + PHY_vars_eNB->dlsch_eNB[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; + start_meas(&PHY_vars_eNB->dlsch_scrambling_stats); + dlsch_scrambling(&PHY_vars_eNB->lte_frame_parms, + 0, + PHY_vars_eNB->dlsch_eNB[k][cw], + coded_bits_per_codeword, + cw, + subframe<<1); + stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); - if (n_frames==1) { - for (s=0;sdlsch_eNB[k][cw]->harq_processes[0]->C;s++) { - if (sdlsch_eNB[k][cw]->harq_processes[0]->Cminus) - Kr = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - // for (i=0;idlsch_eNB[k][cw]->harq_processes[0]->c[s][i]); - } - } - } - - start_meas(&PHY_vars_eNB->dlsch_modulation_stats); - re_allocated = dlsch_modulation(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], - AMP, - subframe, - &PHY_vars_eNB->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][0], - PHY_vars_eNB->dlsch_eNB[k][1] - ); - stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); - /* - if (trials==0 && round==0) - printf("RE count %d\n",re_allocated); - */ - } //n_users + if (n_frames==1) { + for (s=0;sdlsch_eNB[k][cw]->harq_processes[0]->C;s++) { + if (sdlsch_eNB[k][cw]->harq_processes[0]->Cminus) + Kr = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + // for (i=0;idlsch_eNB[k][cw]->harq_processes[0]->c[s][i]); + } + } + } + + start_meas(&PHY_vars_eNB->dlsch_modulation_stats); + re_allocated = dlsch_modulation(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + AMP, + subframe, + &PHY_vars_eNB->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_eNB->dlsch_eNB[k][0], + PHY_vars_eNB->dlsch_eNB[k][1] + ); + stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); + /* + if (trials==0 && round==0) + printf("RE count %d\n",re_allocated); + */ + } //n_users - - generate_pilots(PHY_vars_eNB, - PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], - AMP, - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - - start_meas(&PHY_vars_eNB->ofdm_mod_stats); - - do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], - PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], - (subframe*2), - &PHY_vars_eNB->lte_frame_parms); + + generate_pilots(PHY_vars_eNB, + PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + AMP, + LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + + start_meas(&PHY_vars_eNB->ofdm_mod_stats); + + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], + (subframe*2), + &PHY_vars_eNB->lte_frame_parms); - do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], - PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], - (subframe*2)+1, - &PHY_vars_eNB->lte_frame_parms); - - stop_meas(&PHY_vars_eNB->ofdm_mod_stats); - stop_meas(&PHY_vars_eNB->phy_proc_tx); - - do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], - PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], - (subframe*2)+2, - &PHY_vars_eNB->lte_frame_parms); + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], + (subframe*2)+1, + &PHY_vars_eNB->lte_frame_parms); + + stop_meas(&PHY_vars_eNB->ofdm_mod_stats); + stop_meas(&PHY_vars_eNB->phy_proc_tx); + + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], + (subframe*2)+2, + &PHY_vars_eNB->lte_frame_parms); - if (n_frames==1) { - write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) - write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); - } + if (n_frames==1) { + write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) + write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + } - tx_lev = 0; - for (aa=0; aalte_frame_parms.nb_antennas_tx; aa++) { - tx_lev += signal_energy(&PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa] - [subframe*PHY_vars_eNB->lte_frame_parms.samples_per_tti], - PHY_vars_eNB->lte_frame_parms.samples_per_tti); - } - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - - if (n_frames==1) { - printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); - write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti], - - PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1); - } - } - /* - else { // Read signal from file - i=0; - while (!feof(input_fd)) { - fscanf(input_fd,"%s %s",input_val_str,input_val_str2); - - if ((i%4)==0) { - ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); - if ((i/4)<100) - printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); - } - i++; - if (i>(FRAME_LENGTH_SAMPLES)) - break; - } - printf("Read in %d samples\n",i/4); - write_output("txsig0.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1); - // write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); - tx_lev = signal_energy(&txdata[0][0], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - } - */ - - // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,awgn_flag); - for (i=0;i<2*frame_parms->samples_per_tti;i++) { - for (aa=0;aalte_frame_parms.nb_antennas_tx;aa++) { - if (awgn_flag == 0) { - s_re[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) + (i<<1)]); - s_im[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - } - else { + tx_lev = 0; + for (aa=0; aalte_frame_parms.nb_antennas_tx; aa++) { + tx_lev += signal_energy(&PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa] + [subframe*PHY_vars_eNB->lte_frame_parms.samples_per_tti], + PHY_vars_eNB->lte_frame_parms.samples_per_tti); + } + tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + + if (n_frames==1) { + printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); + write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti], + PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1); + } + } + /* + else { // Read signal from file + i=0; + while (!feof(input_fd)) { + fscanf(input_fd,"%s %s",input_val_str,input_val_str2); + + if ((i%4)==0) { + ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); + ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); + if ((i/4)<100) + printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); + } + i++; + if (i>(FRAME_LENGTH_SAMPLES)) + break; + } + printf("Read in %d samples\n",i/4); + write_output("txsig0.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1); + // write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); + tx_lev = signal_energy(&txdata[0][0], + OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); + tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + } + */ + + // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,awgn_flag); + for (i=0;i<2*frame_parms->samples_per_tti;i++) { + for (aa=0;aalte_frame_parms.nb_antennas_tx;aa++) { + if (awgn_flag == 0) { + s_re[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) + (i<<1)]); + s_im[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + } + else { if (transmission_mode==4) { - r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - //printf("r_re0 = %d\n",r_re[0][i]); - //printf("r_im0 = %d\n",r_im[0][i]); - //printf("r_re1 = %d\n",r_re[1][i]); - //printf("r_im1 = %d\n",r_im[1][i]); - - } - else { - for (aarx=0;aarxlte_frame_parms.nb_antennas_rx;aarx++) { - if (aa==0) { - r_re[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - } - else { - r_re[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); - } - } - } - } - } - } + r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + //printf("r_re0 = %d\n",r_re[0][i]); + //printf("r_im0 = %d\n",r_im[0][i]); + //printf("r_re1 = %d\n",r_re[1][i]); + //printf("r_im1 = %d\n",r_im[1][i]); + + } + else { + for (aarx=0;aarxlte_frame_parms.nb_antennas_rx;aarx++) { + if (aa==0) { + r_re[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + } + else { + r_re[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + } + } + } + } + } + } - // Multipath channel - if (awgn_flag == 0) { - multipath_channel(eNB2UE[0],s_re,s_im,r_re,r_im, - 2*frame_parms->samples_per_tti,hold_channel); - if (PHY_vars_UE->perfect_ce==1){ - freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); - // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); - // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); - } - // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); - if(abstx==1 && num_rounds>1) - if(round==0 && hold_channel==0){ - random_channel(eNB2UE[1],0); - random_channel(eNB2UE[2],0); - random_channel(eNB2UE[3],0); - } - } - - - // freq_channel(eNB2UE[0], NB_RB,12*NB_RB + 1); - if(abstx){ - if (trials==0 && round==0) { - // calculate freq domain representation to compute SINR - freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1); - // snr=pow(10.0,.1*SNR); - fprintf(csv_fd,"%f,",SNR); - - for (u=0;u<2*NB_RB;u++){ - for (aarx=0;aarxnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { - channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; - channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } - } - - if(num_rounds>1){ - freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1); - - for (u=0;u<2*NB_RB;u++){ - for (aarx=0;aarxnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { - channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; - channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } - } - freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1); - - for (u=0;u<2*NB_RB;u++){ - for (aarx=0;aarxnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { - channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; - channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } - } - - freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1); - - for (u=0;u<2*NB_RB;u++){ - for (aarx=0;aarxnb_rx;aarx++) { - for (aatx=0;aatxnb_tx;aatx++) { - channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; - channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } - } - } - } - } - - //AWGN - // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated); - sigma2 = pow(10,sigma2_dB/10); - if (n_frames==1) - printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated)); - - for (i=0; i<2*frame_parms->samples_per_tti; i++) { - for (aa=0;aalte_frame_parms.nb_antennas_rx;aa++) { - //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); - ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] = - (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i+1] = - (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - } - } - - // lte_sync_time_init(PHY_vars_eNB->lte_frame_parms,lte_ue_common_vars); - // lte_sync_time(lte_ue_common_vars->rxdata, PHY_vars_eNB->lte_frame_parms); - // lte_sync_time_free(); - - /* - // optional: read rx_frame from file - if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL) - { - printf("Cannot open rx_frame.m data file\n"); - exit(0); - } - - result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); - printf("Read %d bytes\n",result); - result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); - printf("Read %d bytes\n",result); - - fclose(rx_frame_file); - */ - - if (n_frames==1) { - printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); - printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); - printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); - printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); - } - - if (PHY_vars_eNB->lte_frame_parms.Ncp == 0) { // normal prefix - pilot1 = 4; - pilot2 = 7; - pilot3 = 11; - } - else { // extended prefix - pilot1 = 3; - pilot2 = 6; - pilot3 = 9; - } - - start_meas(&PHY_vars_UE->phy_proc_rx); - // Inner receiver scheduling for 3 slots - for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) { - for (l=0;lofdm_demod_stats); - slot_fep(PHY_vars_UE, - l, - Ns%20, - 0, - 0, - 0); + // Multipath channel + if (awgn_flag == 0) { + multipath_channel(eNB2UE[0],s_re,s_im,r_re,r_im, + 2*frame_parms->samples_per_tti,hold_channel); + if (PHY_vars_UE->perfect_ce==1){ + freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); + // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); + } + // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); + if(abstx==1 && num_rounds>1) + if(round==0 && hold_channel==0){ + random_channel(eNB2UE[1],0); + random_channel(eNB2UE[2],0); + random_channel(eNB2UE[3],0); + } + } + + + // freq_channel(eNB2UE[0], NB_RB,12*NB_RB + 1); + if(abstx){ + if (trials==0 && round==0) { + // calculate freq domain representation to compute SINR + freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1); + // snr=pow(10.0,.1*SNR); + fprintf(csv_fd,"%f,",SNR); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; + channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + if(num_rounds>1){ + freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; + channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; + channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; + channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + } + } + } + + //AWGN + // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated); + sigma2 = pow(10,sigma2_dB/10); + if (n_frames==1) + printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated)); + + for (i=0; i<2*frame_parms->samples_per_tti; i++) { + for (aa=0;aalte_frame_parms.nb_antennas_rx;aa++) { + //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); + ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] = + (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i+1] = + (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + } + } + + // lte_sync_time_init(PHY_vars_eNB->lte_frame_parms,lte_ue_common_vars); + // lte_sync_time(lte_ue_common_vars->rxdata, PHY_vars_eNB->lte_frame_parms); + // lte_sync_time_free(); + + /* + // optional: read rx_frame from file + if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL) + { + printf("Cannot open rx_frame.m data file\n"); + exit(0); + } + + result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); + printf("Read %d bytes\n",result); + result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); + printf("Read %d bytes\n",result); + + fclose(rx_frame_file); + */ + + if (n_frames==1) { + printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); + printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); + } + + if (PHY_vars_eNB->lte_frame_parms.Ncp == 0) { // normal prefix + pilot1 = 4; + pilot2 = 7; + pilot3 = 11; + } + else { // extended prefix + pilot1 = 3; + pilot2 = 6; + pilot3 = 9; + } + + start_meas(&PHY_vars_UE->phy_proc_rx); + // Inner receiver scheduling for 3 slots + for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) { + for (l=0;lofdm_demod_stats); + slot_fep(PHY_vars_UE, + l, + Ns%20, + 0, + 0, + 0); stop_meas(&PHY_vars_UE->ofdm_demod_stats); if (PHY_vars_UE->perfect_ce==1) { if (awgn_flag==0) { - for(k=0; knb_antennas_tx; aa++) { for (aarx=0; aarxnb_antennas_rx; aarx++) { for (i=0; iN_RB_DL*12; i++) { - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= + (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= + (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); } } } } + }else { + if (transmission_mode==4) { + for (i=0; iN_RB_DL*12; i++) { + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + } } else { - if (transmission_mode==4) { - for (i=0; iN_RB_DL*12; i++) { - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; - } - } - else{ - for(aa=0; aanb_antennas_tx; aa++) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { - for (i=0; iN_RB_DL*12; i++) { - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; - } - } - } - } - } - } + for(aa=0; aanb_antennas_tx; aa++) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (i=0; iN_RB_DL*12; i++) { + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; + } + } + } + } + } + } + if ((Ns==((2*subframe))) && (l==0)) { lte_ue_measurements(PHY_vars_UE, subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti, 1, 0); - // printf ("Trial %d, Measurements are done \n", trials); - /* - debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n", - PHY_vars_UE->PHY_measurements.rx_rssi_dBm[0] - ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx==2) ? 3 : 0), - PHY_vars_UE->PHY_measurements.wideband_cqi_dB[0][0], - PHY_vars_UE->PHY_measurements.wideband_cqi_dB[0][1], - PHY_vars_UE->PHY_measurements.wideband_cqi[0][0], - PHY_vars_UE->PHY_measurements.wideband_cqi[0][1], - PHY_vars_UE->PHY_measurements.rx_power_avg_dB[0], - PHY_vars_UE->PHY_measurements.rx_power_avg[0], - PHY_vars_UE->rx_total_gain_dB); - debug_msg("N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n", - PHY_vars_UE->PHY_measurements.n0_power_tot_dBm, - PHY_vars_UE->PHY_measurements.n0_power_dB[0], - PHY_vars_UE->PHY_measurements.n0_power_dB[1], - PHY_vars_UE->PHY_measurements.n0_power[0], - PHY_vars_UE->PHY_measurements.n0_power[1], - PHY_vars_UE->PHY_measurements.n0_power_avg_dB, - PHY_vars_UE->PHY_measurements.n0_power_avg); - debug_msg("Wideband CQI tot %d dB, wideband cqi avg %d dB\n", - PHY_vars_UE->PHY_measurements.wideband_cqi_tot[0], - PHY_vars_UE->PHY_measurements.wideband_cqi_avg[0]); - */ + //printf ("Trial %d, Measurements are done \n", trials); + /* + debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n", + PHY_vars_UE->PHY_measurements.rx_rssi_dBm[0] - ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx==2) ? 3 : 0), + PHY_vars_UE->PHY_measurements.wideband_cqi_dB[0][0], + PHY_vars_UE->PHY_measurements.wideband_cqi_dB[0][1], + PHY_vars_UE->PHY_measurements.wideband_cqi[0][0], + PHY_vars_UE->PHY_measurements.wideband_cqi[0][1], + PHY_vars_UE->PHY_measurements.rx_power_avg_dB[0], + PHY_vars_UE->PHY_measurements.rx_power_avg[0], + PHY_vars_UE->rx_total_gain_dB); + debug_msg("N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n", + PHY_vars_UE->PHY_measurements.n0_power_tot_dBm, + PHY_vars_UE->PHY_measurements.n0_power_dB[0], + PHY_vars_UE->PHY_measurements.n0_power_dB[1], + PHY_vars_UE->PHY_measurements.n0_power[0], + PHY_vars_UE->PHY_measurements.n0_power[1], + PHY_vars_UE->PHY_measurements.n0_power_avg_dB, + PHY_vars_UE->PHY_measurements.n0_power_avg); + debug_msg("Wideband CQI tot %d dB, wideband cqi avg %d dB\n", + PHY_vars_UE->PHY_measurements.wideband_cqi_tot[0], + PHY_vars_UE->PHY_measurements.wideband_cqi_avg[0]); + */ if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) { if (pmi_feedback == 1) { pmi_feedback = 0; hold_channel = 1; - // printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback); + //printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback); goto PMI_FEEDBACK; } } @@ -3183,909 +3172,890 @@ n(tikz_fname,"w"); if ((Ns==(2*subframe)) && (l==pilot1)) {// process symbols 0,1,2 - if (dci_flag == 1) { PHY_vars_UE->UE_mode[0] = PUSCH; - - start_meas(&PHY_vars_UE->dlsch_rx_pdcch_stats); - rx_pdcch(&PHY_vars_UE->lte_ue_common_vars, - PHY_vars_UE->lte_ue_pdcch_vars, - &PHY_vars_UE->lte_frame_parms, - subframe, - 0, - (PHY_vars_UE->lte_frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI, - PHY_vars_UE->high_speed_flag, - 0); - stop_meas(&PHY_vars_UE->dlsch_rx_pdcch_stats); - // overwrite number of pdcch symbols - PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; + start_meas(&PHY_vars_UE->dlsch_rx_pdcch_stats); - dci_cnt = dci_decoding_procedure(PHY_vars_UE, - dci_alloc_rx,1, - eNB_id, - subframe); - // printf("dci_cnt %d\n",dci_cnt); - - if (dci_cnt==0) { - dlsch_active = 0; - if (round==0) { - dci_errors++; - round=5; - errs[0][0]++; - //round_trials[0]++; + rx_pdcch(&PHY_vars_UE->lte_ue_common_vars, + PHY_vars_UE->lte_ue_pdcch_vars, + &PHY_vars_UE->lte_frame_parms, + subframe, + 0, + (PHY_vars_UE->lte_frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI, + PHY_vars_UE->high_speed_flag, + 0); - if (n_frames==1) - printf("DCI error trial %d errs[0][0] %d\n",trials,errs[0][0]); - } - // for (i=1;i<=round;i++) - // round_trials[i]--; - // round=5; - } - - for (i=0;idlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->first_tx=1; - PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->first_tx=1; - } - if ((dci_alloc_rx[i].rnti == n_rnti) && - (generate_ue_dlsch_params_from_dci(0, - subframe, - dci_alloc_rx[i].dci_pdu, - dci_alloc_rx[i].rnti, - dci_alloc_rx[i].format, - PHY_vars_UE->dlsch_ue[0], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI)==0)) { - dump_dci(&PHY_vars_UE->lte_frame_parms,&dci_alloc_rx[i]); - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb, - PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), - PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl, - PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, - 0,subframe); - /* - rate = (double)dlsch_tbs25[get_I_TBS(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs)][PHY_vars_UE->dlsch_ue[0][0]->nb_rb-1]/(coded_bits_per_codeword); - rate*=get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs); - */ - printf("num_pdcch_symbols %d, G %d, TBS %d\n",PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->TBS); + stop_meas(&PHY_vars_UE->dlsch_rx_pdcch_stats); + // overwrite number of pdcch symbols + PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; - dlsch_active = 1; - } - else { - dlsch_active = 0; - if (round==0) { - dci_errors++; - errs[0][0]++; - //round_trials[0]++; - round=5; - - if (n_frames==1) - printf("DCI misdetection trial %d\n",trials); - - } - // for (i=1;i<=round;i++) - // round_trials[i]--; - // round=5; - } - } - } // if dci_flag==1 - else { //dci_flag == 0 - - PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = n_rnti; - PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; - if (round == 0) { - PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx=1; - PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->first_tx=1; - } - switch (transmission_mode) { - case 1: - case 2: - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - (common_flag==0)? C_RNTI : SI_RNTI, - (common_flag==0)? format1 : format1A, - PHY_vars_UE->dlsch_ue[0], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI); - break; - case 3: - // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx); - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - (common_flag==0)? C_RNTI : SI_RNTI, - (common_flag==0)? format2A : format1A, - PHY_vars_UE->dlsch_ue[0], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI); - // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx); - break; - case 4: - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - (common_flag==0)? C_RNTI : SI_RNTI, - (common_flag==0)? format2 : format1A,//format1A only for a codeblock - PHY_vars_UE->dlsch_ue[0], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI); - - break; - case 5: - case 6: - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu2_1E[0], - C_RNTI, - format1E_2A_M10PRB, - PHY_vars_UE->dlsch_ue[0], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI); - break; - - } - dlsch_active = 1; - } // if dci_flag == 1 - } - - if (dlsch_active == 1) { - if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix) - - - if (transmission_mode == 5) { - if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->dl_power_off==0) && - (openair_daq_vars.use_ia_receiver ==1)) { - rx_type = rx_IC_single_stream; - } else { - rx_type = rx_standard; - } - } - - - start_meas(&PHY_vars_UE->dlsch_llr_stats); + dci_cnt = dci_decoding_procedure(PHY_vars_UE, + dci_alloc_rx,1, + eNB_id, + subframe); + //printf("dci_cnt %d\n",dci_cnt); - for (m=PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols; - mlte_ue_pdcch_vars[0]->num_pdcch_symbols)?1:0, - rx_type, - i_mod, - PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1) - { - dlsch_active = 0; - break; - } - } - stop_meas(&PHY_vars_UE->dlsch_llr_stats); - } - - if ((Ns==(1+(2*subframe))) && (l==pilot1)) - {// process symbols (6 Extended Prefix),7,8,9 - start_meas(&PHY_vars_UE->dlsch_llr_stats); - for (m=pilot2; - mdlsch_ue[0][0]->current_harq_pid)==-1) - { - dlsch_active=0; - break; - } - } - stop_meas(&PHY_vars_UE->dlsch_llr_stats); - } - - if ((Ns==(2+(2*subframe))) && (l==0)) // process symbols 10,11,(12,13 Normal Prefix) do deinterleaving for TTI - { - start_meas(&PHY_vars_UE->dlsch_llr_stats); - for (m=pilot3; - mlte_frame_parms.symbols_per_tti; - m++) - { - if (rx_pdsch(PHY_vars_UE, - PDSCH, - eNB_id, - eNB_id_i, - subframe, - m, - 0, - rx_type, - i_mod, - PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1) - { - dlsch_active=0; - break; - } - } - stop_meas(&PHY_vars_UE->dlsch_llr_stats); - } - } - } - } + if (dci_cnt==0) { + dlsch_active = 0; + if (round==0) { + dci_errors++; + round=5; + errs[0][0]++; + //round_trials[0]++; - //saving PMI in case of Transmission Mode > 5 + if (n_frames==1) + printf("DCI error trial %d errs[0][0] %d\n",trials,errs[0][0]); + } + //for (i=1;i<=round;i++) + //round_trials[i]--; + //round=5; + } + + for (i=0;idlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->first_tx=1; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->first_tx=1; + } + if ((dci_alloc_rx[i].rnti == n_rnti) && + (generate_ue_dlsch_params_from_dci(0, + subframe, + dci_alloc_rx[i].dci_pdu, + dci_alloc_rx[i].rnti, + dci_alloc_rx[i].format, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI)==0)) { + dump_dci(&PHY_vars_UE->lte_frame_parms,&dci_alloc_rx[i]); + coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl, + PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, + 0, + subframe); + /* + rate = (double)dlsch_tbs25[get_I_TBS(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs)][PHY_vars_UE->dlsch_ue[0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs); + */ + printf("num_pdcch_symbols %d, G %d, TBS %d\n",PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->TBS); - if(abstx){ - if (trials==0 && round==0 && transmission_mode>=4){ - for (iii=0; iiilte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[iii])); - fprintf(csv_fd,"%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); - //printf("%x ",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); - } - } - } - - if (rx_type==rx_SIC_dual_stream){ - cw_to_decode_interf=1; - cw_to_decode_interf_free=1; - } - else { - cw_to_decode_interf=Kmimo; - } - - for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0,subframe); - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword; - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); - if (n_frames==2) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword, - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); - - // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_non_sic); - sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword,1,0); - sprintf(fname,"dlsch_cw%d_e.m", cw_non_sic); - sprintf(vname,"dlschcw%d_e", cw_non_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); - uncoded_ber=0; - printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { - uncoded_ber_bit[i] = 1; - uncoded_ber++; - } - else - uncoded_ber_bit[i] = 0; - - uncoded_ber/=coded_bits_per_codeword; - avg_ber += uncoded_ber; - sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_non_sic); - sprintf(vname,"uncoded_ber_bit_cw%d", cw_non_sic); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); - printf("cw %d, uncoded ber %f\n",cw_non_sic,uncoded_ber); - + dlsch_active = 1; + } else { + dlsch_active = 0; + if (round==0) { + dci_errors++; + errs[0][0]++; + //round_trials[0]++; + round=5; - free(uncoded_ber_bit); - uncoded_ber_bit = NULL; + if (n_frames==1) + printf("DCI misdetection trial %d\n",trials); + + } + // for (i=1;i<=round;i++) + // round_trials[i]--; + // round=5; + } + } + } else { //dci_flag == 0 + PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = n_rnti; + PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; + if (round == 0) { + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx=1; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->first_tx=1; + } + switch (transmission_mode) { + case 1: + case 2: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format1 : format1A, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); + break; + case 3: + //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx); + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format2A : format1A, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); + //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx); + break; + case 4: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format2 : format1A,//format1A only for a codeblock + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); - } + break; + case 5: + case 6: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu2_1E[0], + C_RNTI, + format1E_2A_M10PRB, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); + break; + } + dlsch_active = 1; + } // if dci_flag == 1 + } - start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_ue[0][cw_non_sic], - coded_bits_per_codeword, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], - cw_non_sic, - subframe<<1); - stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - - start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret[cw_non_sic] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw_non_sic], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid], - subframe, - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid, - 1,llr8_flag); - stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - - - if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { - - if (cw_non_sic==0) { - avg_iter[0] += ret[0]; - iter_trials[0]++; - } - - if (n_frames==2) { - printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); -#ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); - } -#endif - } - - PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->current_harq_pid]->TBS; - - // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER - //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) - if (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC - /* - //for (round = 0 ; round < PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round ; round++) { - // we assume here that the second stream has a lower MCS and is thus more likely to be decoded - // re-encoding of second stream - dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq->mimo_mode = LARGE_CDD; - dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; - dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; - dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; - dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; - dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; - dlsch0_eNB_harq->round = dlsch0_ue_harq->round; - - dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; - dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; - dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - - PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; - PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; - PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - - dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_UE->dlsch_eNB[eNB_id], - 0,subframe, - &PHY_vars_UE->dlsch_rate_matching_stats, - &PHY_vars_UE->dlsch_turbo_encoding_stats, - &PHY_vars_UE->dlsch_interleaving_stats - ); - - coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, - get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, - num_pdcch_symbols, - 0,subframe); - - - //scrambling - dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_eNB[eNB_id], - coded_bits_per_codeword, - 0, - subframe<<1); - - - //modulation - re_allocated = dlsch_modulation(sic_buffer, - AMP, - subframe, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - &PHY_vars_UE->dlsch_eNB[0][0], - NULL); - // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding - // precoding is contained in effective channel estimate - // compute the norm of the effective channel for both receive antennas -> alphha[0], alphha[2] - // multiply with the norm of the effective channnel - */ - - //stripping (from matched filter output of first stream = rxdataF_comp0) - // this is pseudocode - /* - for (i=0; inb_antennas_rx; i++) { - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext[i] -= alpha[i].*sic_buffer[i]; - } - */ - - //apply rho to output - /* - dlsch_channel_compensation(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].dl_ch_rho_ext[harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1, - NULL, - frame_parms, - symbol, - first_symbol_flag, - i_mod, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->log2_maxh, - phy_measurements); // log2_maxh+I0_shift - */ + if (dlsch_active == 1) { + if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix + if (transmission_mode == 5) { + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->dl_power_off==0) && + (openair_daq_vars.use_ia_receiver ==1)) { + rx_type = rx_IC_single_stream; + } else { + rx_type = rx_standard; + } + } - //detection of second stream - //} - - } - - if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && - rx_type==rx_SIC_dual_stream) { - remove("rho_rho_in_llr.m"); - - // for (round = 0 ; round < 1 ; round++) { - dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - - dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; - dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; - dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; - dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; - dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; - dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; - dlsch0_eNB_harq->round = dlsch0_ue_harq->round; - dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; - dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; - dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - - PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; - PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; - PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - - dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_UE->dlsch_eNB[eNB_id], - 0, - subframe, - &PHY_vars_UE->dlsch_rate_matching_stats, - &PHY_vars_UE->dlsch_turbo_encoding_stats, - &PHY_vars_UE->dlsch_interleaving_stats); - - - coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, - get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, - num_pdcch_symbols, - 0, - subframe); - - dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_eNB[eNB_id], - coded_bits_per_codeword, - 0, - subframe<<1); - - re_allocated = dlsch_modulation_SIC(sic_buffer, - subframe, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - &PHY_vars_UE->dlsch_eNB[0][0], - NULL, - coded_bits_per_codeword); - - // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); - // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - - switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ - - case 2: - - dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - dlsch0_eNB_harq->nb_rb, + start_meas(&PHY_vars_UE->dlsch_llr_stats); + + for (m=PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols; mlte_ue_pdcch_vars[0]->num_pdcch_symbols)?1:0, + rx_type, + i_mod, + PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1){ + dlsch_active = 0; + break; + } + } + stop_meas(&PHY_vars_UE->dlsch_llr_stats); + } + + if ((Ns==(1+(2*subframe))) && (l==pilot1)){// process symbols (6 Extended Prefix),7,8,9 + start_meas(&PHY_vars_UE->dlsch_llr_stats); + for (m=pilot2;mrb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); - break; + m, + 0, + rx_type, + i_mod, + PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1){ + dlsch_active=0; + break; + } + } + stop_meas(&PHY_vars_UE->dlsch_llr_stats); + } + + if ((Ns==(2+(2*subframe))) && (l==0)) { // process symbols 10,11,(12,13 Normal Prefix) do deinterleaving for TTI + start_meas(&PHY_vars_UE->dlsch_llr_stats); + for (m=pilot3; mlte_frame_parms.symbols_per_tti; m++) { + if (rx_pdsch(PHY_vars_UE, + PDSCH, + eNB_id, + eNB_id_i, + subframe, + m, + 0, + rx_type, + i_mod, + PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1) { + dlsch_active=0; + break; + } + } + stop_meas(&PHY_vars_UE->dlsch_llr_stats); + } + } + } + } - case 4: + //saving PMI in case of Transmission Mode > 5 - dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); - break; - case 6: - dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); - break; - }// round - - // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); - - for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0, - subframe); - - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword; - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); - - if (n_frames==2) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword, - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); - - // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_sic); - sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword,1,0); - sprintf(fname,"dlsch_cw%d_e.m", cw_sic); - sprintf(vname,"dlschcw%d_e", cw_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); - uncoded_ber=0; - printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { - uncoded_ber_bit[i] = 1; - uncoded_ber++; - } else - uncoded_ber_bit[i] = 0; - - uncoded_ber/=coded_bits_per_codeword; - avg_ber += uncoded_ber; - sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); - sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); - printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); - free(uncoded_ber_bit); - uncoded_ber_bit = NULL; - } + if(abstx){ + if (trials==0 && round==0 && transmission_mode>=4){ + for (iii=0; iiilte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[iii])); + fprintf(csv_fd,"%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + //printf("%x ",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + } + } + } + + if (rx_type==rx_SIC_dual_stream){ + cw_to_decode_interf=1; + cw_to_decode_interf_free=1; + } + else { + cw_to_decode_interf=Kmimo; + } + + for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0,subframe); + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword; + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); + if (n_frames==2) { + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword, + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); + + // calculate uncoded BER + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_non_sic); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword,1,0); + sprintf(fname,"dlsch_cw%d_e.m", cw_non_sic); + sprintf(vname,"dlschcw%d_e", cw_non_sic); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + uncoded_ber=0; + printf("trials=%d\n", trials); + for (i=0;idlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } + else + uncoded_ber_bit[i] = 0; + + uncoded_ber/=coded_bits_per_codeword; + avg_ber += uncoded_ber; + sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_non_sic); + sprintf(vname,"uncoded_ber_bit_cw%d", cw_non_sic); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); + printf("cw %d, uncoded ber %f\n",cw_non_sic,uncoded_ber); + - start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_ue[0][cw_sic], - coded_bits_per_codeword, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], - cw_sic, - subframe<<1); - stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + free(uncoded_ber_bit); + uncoded_ber_bit = NULL; - start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret[1] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw_sic], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], - subframe, - PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, - 1,llr8_flag); - stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - - - if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) - - avg_iter[1] += ret[1]; - iter_trials[1]++; - - - if (n_frames==2) { - printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); -#ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); - } -#endif - } - - } - - - else { - errs[cw_sic][round]++; - // exit(0); - - if (cw_sic==1) { - avg_iter[1] += ret[1]-1; - iter_trials[1]++; - } - - if (n_frames==2) { - //if ((n_frames==1) || (SNR>=30)) { - printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); -#ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); - } -#endif - } //n_frames==1 - // exit(0); - } //if (ret > PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) - } //for (int cw_1=cw_to_decode_interf_free; cw_1dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) - else { - errs[cw_non_sic][round]++; - - if (cw_non_sic==0) { - avg_iter[0] += ret[0]-1; - iter_trials[0]++; - } - - if (rx_type==rx_SIC_dual_stream) { - errs[1][round]++; - } - - if (cw_non_sic==1) { - avg_iter[1] += ret[1]-1; - iter_trials[1]++; - } - - - if (n_frames==2) { - //if ((n_frames==1) || (SNR>=30)) { - printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); -#ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); - } -#endif - } - } - } - - stop_meas(&PHY_vars_UE->phy_proc_rx); - - if (n_frames==2) { + } - //rxsig - sprintf(fname,"rxsig0_r%d.m",round); - sprintf(vname,"rxs0_r%d",round); - write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); - sprintf(fname,"rxsigF0_r%d.m",round); - sprintf(vname,"rxs0F_r%d",round); - write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); - if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { - sprintf(fname,"rxsig1_r%d.m",round); - sprintf(vname,"rxs1_r%d",round); - write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdata[1],PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); - sprintf(fname,"rxsig1F_r%d.m",round); - sprintf(vname,"rxs1F_r%d",round); - write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdataF[1],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); - } + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_ue[0][cw_non_sic], + coded_bits_per_codeword, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], + cw_non_sic, + subframe<<1); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - //channel - write_output("chanF11.m","chF11",eNB2UE[0]->chF[0],12*NB_RB,1,8); - write_output("chan11.m","ch11",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); - if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx==2 && PHY_vars_eNB->lte_frame_parms.nb_antennas_tx==1 ){ - write_output("chan21.m","ch21",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); - } - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1){ - write_output("chan12.m","ch12",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); - if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx>1){ - write_output("chan21.m","ch21",eNB2UE[0]->ch[2],eNB2UE[0]->channel_length,1,8); - write_output("chan22.m","ch22",eNB2UE[0]->ch[3],eNB2UE[0]->channel_length,1,8); - } - } + start_meas(&PHY_vars_UE->dlsch_decoding_stats); + ret[cw_non_sic] = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][cw_non_sic], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid, + 1,llr8_flag); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + + + if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { - //channel estimates - sprintf(fname,"dlsch00_r%d.m",round); - sprintf(vname,"dl00_r%d",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][0][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { - sprintf(fname,"dlsch01_r%d.m",round); - sprintf(vname,"dl01_r%d",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][1][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - } - if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) { - sprintf(fname,"dlsch10_r%d.m",round); - sprintf(vname,"dl10_r%d",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][2][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - } - if ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) && (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)) { - sprintf(fname,"dlsch11_r%d.m",round); - sprintf(vname,"dl11_r%d",round); - write_output(fname,vname, - &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][3][0]), - PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); - } - //pdsch_vars - dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round,PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid); - /* - write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); - write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); - write_output("dlsch_eNB_w.m","w",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - write_output("dlsch_UE_w.m","w",PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); - */ + if (cw_non_sic==0) { + avg_iter[0] += ret[0]; + iter_trials[0]++; + } + + if (n_frames==2) { + printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); + } + #endif + } + + PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->current_harq_pid]->TBS; - //pdcch_vars - write_output("pdcchF0_ext.m","pdcchF_ext", PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->llr,2400,1,4); - - - if (round == 3) exit(-1); - } + // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER + //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) + if (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + /* + //for (round = 0 ; round < PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round ; round++) { + // we assume here that the second stream has a lower MCS and is thus more likely to be decoded + // re-encoding of second stream + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq->mimo_mode = LARGE_CDD; + dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; + dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; + dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; + dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; + dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; + dlsch0_eNB_harq->round = dlsch0_ue_harq->round; + + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; + dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; + dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; + + dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0,subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats + ); + + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0,subframe); + + + //scrambling + dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword, + 0, + subframe<<1); + + + //modulation + re_allocated = dlsch_modulation(sic_buffer, + AMP, + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL); + // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding + // precoding is contained in effective channel estimate + // compute the norm of the effective channel for both receive antennas -> alphha[0], alphha[2] + // multiply with the norm of the effective channnel + */ + + //stripping (from matched filter output of first stream = rxdataF_comp0) + // this is pseudocode + /* + for (i=0; inb_antennas_rx; i++) { + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext[i] -= alpha[i].*sic_buffer[i]; + } + */ + + //apply rho to output + /* + dlsch_channel_compensation(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].dl_ch_rho_ext[harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1, + NULL, + frame_parms, + symbol, + first_symbol_flag, + i_mod, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + phy_measurements); // log2_maxh+I0_shift + */ - if (xforms==1) { - phy_scope_UE(form_ue, - PHY_vars_UE, - eNB_id, - 0,// UE_id - subframe); - } - - round++; - } //round - //if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) - // break; - - //len = chbch_stats_read(stats_buffer,NULL,0,4096); - //printf("%s\n\n",stats_buffer); - - if (PHY_vars_UE->frame_rx % 10 == 0) { - PHY_vars_UE->bitrate[eNB_id] = (PHY_vars_UE->total_TBS[eNB_id] - PHY_vars_UE->total_TBS_last[eNB_id])*10; - LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",PHY_vars_UE->Mod_id,PHY_vars_UE->total_TBS[eNB_id],PHY_vars_UE->total_TBS_last[eNB_id],PHY_vars_UE->bitrate[eNB_id]/1000); - PHY_vars_UE->total_TBS_last[eNB_id] = PHY_vars_UE->total_TBS[eNB_id]; - } + //detection of second stream + //} + + } + + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + rx_type==rx_SIC_dual_stream) { + remove("rho_rho_in_llr.m"); + + // for (round = 0 ; round < 1 ; round++) { + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + + dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; + dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; + dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; + dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; + dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; + dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; + dlsch0_eNB_harq->round = dlsch0_ue_harq->round; + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; + dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; + dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; + + dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0, + subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats); + + + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0, + subframe); - - PHY_vars_UE->frame_rx++; - - /* calculate the total processing time for each packet, - * get the max, min, and number of packets that exceed t>2000us - */ - double t_tx = (double)PHY_vars_eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)PHY_vars_eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)PHY_vars_eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)PHY_vars_eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - - - double t_rx = (double)PHY_vars_UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)PHY_vars_UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)PHY_vars_UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)PHY_vars_UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword, + 0, + subframe<<1); + + re_allocated = dlsch_modulation_SIC(sic_buffer, + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL, + coded_bits_per_codeword); + + // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); + // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + + switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ + + case 2: + + dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + + case 4: + + dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + case 6: + dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + }// round - if (t_tx > t_tx_max) - t_tx_max = t_tx; - if (t_tx < t_tx_min) - t_tx_min = t_tx; - if (t_rx > t_rx_max) - t_rx_max = t_rx; - if (t_rx < t_rx_min) - t_rx_min = t_rx; - if (t_tx > 2000) - n_tx_dropped++; - if (t_rx > 2000) - n_rx_dropped++; + // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); + for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe); + + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword; + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); + + if (n_frames==2) { + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword, + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); + + // calculate uncoded BER + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_sic); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword,1,0); + sprintf(fname,"dlsch_cw%d_e.m", cw_sic); + sprintf(vname,"dlschcw%d_e", cw_sic); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + uncoded_ber=0; + printf("trials=%d\n", trials); + for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } else + uncoded_ber_bit[i] = 0; + + uncoded_ber/=coded_bits_per_codeword; + avg_ber += uncoded_ber; + sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); + sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); + printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); + free(uncoded_ber_bit); + uncoded_ber_bit = NULL; + } - push_front(&time_vector_tx, t_tx); - push_front(&time_vector_tx_ifft, t_tx_ifft); - push_front(&time_vector_tx_mod, t_tx_mod); - push_front(&time_vector_tx_enc, t_tx_enc); - - push_front(&time_vector_rx, t_rx); - push_front(&time_vector_rx_fft, t_rx_fft); - push_front(&time_vector_rx_demod, t_rx_demod); - push_front(&time_vector_rx_dec, t_rx_dec); + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_ue[0][cw_sic], + coded_bits_per_codeword, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + cw_sic, + subframe<<1); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + + start_meas(&PHY_vars_UE->dlsch_decoding_stats); + ret[1] = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][cw_sic], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, + 1,llr8_flag); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + + + if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + + avg_iter[1] += ret[1]; + iter_trials[1]++; + + + if (n_frames==2) { + printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + } + #endif + } + + } + + + else { + errs[cw_sic][round]++; + // exit(0); + + if (cw_sic==1) { + avg_iter[1] += ret[1]-1; + iter_trials[1]++; + } + + if (n_frames==2) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + } + #endif + } //n_frames==1 + // exit(0); + } //if (ret > PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + } //for (int cw_1=cw_to_decode_interf_free; cw_1dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) + else { + errs[cw_non_sic][round]++; + + if (cw_non_sic==0) { + avg_iter[0] += ret[0]-1; + iter_trials[0]++; + } + + if (rx_type==rx_SIC_dual_stream) { + errs[1][round]++; + } + + if (cw_non_sic==1) { + avg_iter[1] += ret[1]-1; + iter_trials[1]++; + } + + + if (n_frames==2) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); + } + #endif + } + } + } + + stop_meas(&PHY_vars_UE->phy_proc_rx); + + if (n_frames==2) { + + //rxsig + sprintf(fname,"rxsig0_r%d.m",round); + sprintf(vname,"rxs0_r%d",round); + write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsigF0_r%d.m",round); + sprintf(vname,"rxs0F_r%d",round); + write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); + if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { + sprintf(fname,"rxsig1_r%d.m",round); + sprintf(vname,"rxs1_r%d",round); + write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdata[1],PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsig1F_r%d.m",round); + sprintf(vname,"rxs1F_r%d",round); + write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdataF[1],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); + } + + //channel + write_output("chanF11.m","chF11",eNB2UE[0]->chF[0],12*NB_RB,1,8); + write_output("chan11.m","ch11",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx==2 && PHY_vars_eNB->lte_frame_parms.nb_antennas_tx==1 ){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + } + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1){ + write_output("chan12.m","ch12",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx>1){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[2],eNB2UE[0]->channel_length,1,8); + write_output("chan22.m","ch22",eNB2UE[0]->ch[3],eNB2UE[0]->channel_length,1,8); + } + } + + //channel estimates + sprintf(fname,"dlsch00_r%d.m",round); + sprintf(vname,"dl00_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][0][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { + sprintf(fname,"dlsch01_r%d.m",round); + sprintf(vname,"dl01_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][1][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + } + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) { + sprintf(fname,"dlsch10_r%d.m",round); + sprintf(vname,"dl10_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][2][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + } + if ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) && (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)) { + sprintf(fname,"dlsch11_r%d.m",round); + sprintf(vname,"dl11_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][3][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + } + //pdsch_vars + dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round,PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid); + /* + write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); + write_output("dlsch_eNB_w.m","w",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); + write_output("dlsch_UE_w.m","w",PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + */ + + //pdcch_vars + write_output("pdcchF0_ext.m","pdcchF_ext", PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->llr,2400,1,4); + + + if (round == 3) exit(-1); + } + + if (xforms==1) { + phy_scope_UE(form_ue, + PHY_vars_UE, + eNB_id, + 0,// UE_id + subframe); + } + + round++; + } //round + + //if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) + // break; + + //len = chbch_stats_read(stats_buffer,NULL,0,4096); + //printf("%s\n\n",stats_buffer); + + if (PHY_vars_UE->frame_rx % 10 == 0) { + PHY_vars_UE->bitrate[eNB_id] = (PHY_vars_UE->total_TBS[eNB_id] - PHY_vars_UE->total_TBS_last[eNB_id])*10; + LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",PHY_vars_UE->Mod_id,PHY_vars_UE->total_TBS[eNB_id],PHY_vars_UE->total_TBS_last[eNB_id],PHY_vars_UE->bitrate[eNB_id]/1000); + PHY_vars_UE->total_TBS_last[eNB_id] = PHY_vars_UE->total_TBS[eNB_id]; + } + + + PHY_vars_UE->frame_rx++; + + /* calculate the total processing time for each packet, + * get the max, min, and number of packets that exceed t>2000us + */ + double t_tx = (double)PHY_vars_eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; + double t_tx_ifft = (double)PHY_vars_eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_mod = (double)PHY_vars_eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_enc = (double)PHY_vars_eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; + + + double t_rx = (double)PHY_vars_UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)PHY_vars_UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_demod = (double)PHY_vars_UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_dec = (double)PHY_vars_UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + + if (t_tx > t_tx_max) + t_tx_max = t_tx; + if (t_tx < t_tx_min) + t_tx_min = t_tx; + if (t_rx > t_rx_max) + t_rx_max = t_rx; + if (t_rx < t_rx_min) + t_rx_min = t_rx; + if (t_tx > 2000) + n_tx_dropped++; + if (t_rx > 2000) + n_rx_dropped++; + + + push_front(&time_vector_tx, t_tx); + push_front(&time_vector_tx_ifft, t_tx_ifft); + push_front(&time_vector_tx_mod, t_tx_mod); + push_front(&time_vector_tx_enc, t_tx_enc); + + push_front(&time_vector_rx, t_rx); + push_front(&time_vector_rx_fft, t_rx_fft); + push_front(&time_vector_rx_demod, t_rx_demod); + push_front(&time_vector_rx_dec, t_rx_dec); - } //trials + } //trials // round_trials[0]: number of code word : goodput the protocol double table_tx[time_vector_tx.size]; @@ -4177,40 +4147,40 @@ n(tikz_fname,"w"); effective_rate = ((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n", - SNR, - (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), - sigma2_dB); + SNR, + (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), + sigma2_dB); printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e)), dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f)\n", - errs[0][0], - errs[1][0], - round_trials[0], - errs[0][1], - errs[1][1], - round_trials[1], - errs[0][2], - errs[1][2], - round_trials[2], - errs[0][3], - errs[1][3], - round_trials[3], - (double)errs[0][0]/(round_trials[0]), - (double)errs[1][0]/(round_trials[0]), - (double)errs[0][1]/(round_trials[1]), - (double)errs[1][1]/(round_trials[1]), - (double)errs[0][2]/(round_trials[2]), - (double)errs[1][2]/(round_trials[2]), - (double)errs[0][3]/(round_trials[3]), - (double)errs[1][3]/(round_trials[3]), - dci_errors, - round_trials[0], - (double)dci_errors/(round_trials[0]), - rate*effective_rate, - 100*effective_rate, - rate, - rate*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); + errs[0][0], + errs[1][0], + round_trials[0], + errs[0][1], + errs[1][1], + round_trials[1], + errs[0][2], + errs[1][2], + round_trials[2], + errs[0][3], + errs[1][3], + round_trials[3], + (double)errs[0][0]/(round_trials[0]), + (double)errs[1][0]/(round_trials[0]), + (double)errs[0][1]/(round_trials[1]), + (double)errs[1][1]/(round_trials[1]), + (double)errs[0][2]/(round_trials[2]), + (double)errs[1][2]/(round_trials[2]), + (double)errs[0][3]/(round_trials[3]), + (double)errs[1][3]/(round_trials[3]), + dci_errors, + round_trials[0], + (double)dci_errors/(round_trials[0]), + rate*effective_rate, + 100*effective_rate, + rate, + rate*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); if (print_perf==1) { @@ -4317,269 +4287,269 @@ n(tikz_fname,"w"); } if ((transmission_mode != 3) && (transmission_mode != 4)) { - fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", - SNR, - mcs1, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - rate, - errs[0][0], - round_trials[0], - errs[0][1], - round_trials[1], - errs[0][2], - round_trials[2], - errs[0][3], - round_trials[3], - dci_errors); + fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + SNR, + mcs1, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + rate, + errs[0][0], + round_trials[0], + errs[0][1], + round_trials[1], + errs[0][2], + round_trials[2], + errs[0][3], + round_trials[3], + dci_errors); } else { - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", - SNR, - mcs1,mcs2, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, - rate, - errs[0][0], - errs[1][0], - round_trials[0], - errs[0][1], - errs[1][1], - round_trials[1], - errs[0][2], - errs[1][2], - round_trials[2], - errs[0][3], - errs[1][3], - round_trials[3], - dci_errors); + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + SNR, + mcs1,mcs2, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, + rate, + errs[0][0], + errs[1][0], + round_trials[0], + errs[0][1], + errs[1][1], + round_trials[1], + errs[0][2], + errs[1][2], + round_trials[2], + errs[0][3], + errs[1][3], + round_trials[3], + dci_errors); } if(abstx){ //ABSTRACTION - if ((transmission_mode != 3)&& (transmission_mode != 4)) { - blerr[0][0] = (double)errs[0][0]/(round_trials[0]); - - if(num_rounds>1){ - blerr[0][1] = (double)errs[0][1]/(round_trials[1]); - - blerr[0][2] = (double)errs[0][2]/(round_trials[2]); - - blerr[0][3] = (double)errs[0][3]/(round_trials[3]); - - fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]); - } - else { - fprintf(csv_fd,"%e;\n",blerr[0][0]); - } - } - else { - blerr[0][0] = (double)errs[0][0]/(round_trials[0]); - blerr[1][0] = (double)errs[1][0]/(round_trials[0]); - if(num_rounds>1){ - blerr[0][1] = (double)errs[0][1]/(round_trials[1]); - blerr[1][1] = (double)errs[1][1]/(round_trials[1]); - blerr[0][2] = (double)errs[0][2]/(round_trials[2]); - blerr[1][2] = (double)errs[1][2]/(round_trials[2]); - blerr[0][3] = (double)errs[0][3]/(round_trials[3]); - blerr[1][3] = (double)errs[1][3]/(round_trials[3]); - fprintf(csv_fd,"%e;%e;%e;%e;%e;%e;%e;%e;\n",blerr[0][0],blerr[1][0],blerr[0][1],blerr[1][1],blerr[0][2],blerr[1][2], blerr[0][3], blerr[1][3]); - } - else { - fprintf(csv_fd,"%e,%e;\n",blerr[0][0], blerr[1][0]); - } - } + if ((transmission_mode != 3)&& (transmission_mode != 4)) { + blerr[0][0] = (double)errs[0][0]/(round_trials[0]); + + if(num_rounds>1){ + blerr[0][1] = (double)errs[0][1]/(round_trials[1]); + + blerr[0][2] = (double)errs[0][2]/(round_trials[2]); + + blerr[0][3] = (double)errs[0][3]/(round_trials[3]); + + fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]); + } + else { + fprintf(csv_fd,"%e;\n",blerr[0][0]); + } + } + else { + blerr[0][0] = (double)errs[0][0]/(round_trials[0]); + blerr[1][0] = (double)errs[1][0]/(round_trials[0]); + if(num_rounds>1){ + blerr[0][1] = (double)errs[0][1]/(round_trials[1]); + blerr[1][1] = (double)errs[1][1]/(round_trials[1]); + blerr[0][2] = (double)errs[0][2]/(round_trials[2]); + blerr[1][2] = (double)errs[1][2]/(round_trials[2]); + blerr[0][3] = (double)errs[0][3]/(round_trials[3]); + blerr[1][3] = (double)errs[1][3]/(round_trials[3]); + fprintf(csv_fd,"%e;%e;%e;%e;%e;%e;%e;%e;\n",blerr[0][0],blerr[1][0],blerr[0][1],blerr[1][1],blerr[0][2],blerr[1][2], blerr[0][3], blerr[1][3]); + } + else { + fprintf(csv_fd,"%e,%e;\n",blerr[0][0], blerr[1][0]); + } + } } if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); - if ((transmission_mode != 3) && (transmission_mode != 4)) { - fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", - SNR, - mcs1, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - rate, - errs[0][0], - round_trials[0], - errs[0][1], - round_trials[1], - errs[0][2], - round_trials[2], - errs[0][3], - round_trials[3], - dci_errors); + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); + if ((transmission_mode != 3) && (transmission_mode != 4)) { + fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + SNR, + mcs1, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + rate, + errs[0][0], + round_trials[0], + errs[0][1], + round_trials[1], + errs[0][2], + round_trials[2], + errs[0][3], + round_trials[3], + dci_errors); - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); - fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", - SNR, - mcs1, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - rate*effective_rate, - 100*effective_rate, - rate, - (double)avg_iter[0]/iter_trials[0], - errs[0][0], - round_trials[0], - errs[0][1], - round_trials[1], - errs[0][2], - round_trials[2], - errs[0][3], - round_trials[3], - (double)errs[0][0]/(round_trials[0]), - (double)errs[0][1]/(round_trials[0]), - (double)errs[0][2]/(round_trials[0]), - (double)errs[0][3]/(round_trials[0]), - dci_errors, - round_trials[0], - (double)dci_errors/(round_trials[0]), - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); - } - else { - fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", - SNR, - mcs1,mcs2, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, - rate, - errs[0][0], - round_trials[0], - errs[0][1], - round_trials[1], - errs[0][2], - round_trials[2], - errs[0][3], - round_trials[3], - dci_errors); - - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); - fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", - SNR, - mcs1,mcs2, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, - rate*effective_rate, - 100*effective_rate, - rate, - (double)avg_iter[0]/iter_trials[0], - errs[0][0], - round_trials[0], - errs[0][1], - round_trials[1], - errs[0][2], - round_trials[2], - errs[0][3], - round_trials[3], - (double)errs[0][0]/(round_trials[0]), - (double)errs[0][1]/(round_trials[0]), - (double)errs[0][2]/(round_trials[0]), - (double)errs[0][3]/(round_trials[0]), - dci_errors, - round_trials[0], - (double)dci_errors/(round_trials[0]), - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); - } - //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", - fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", - PHY_vars_eNB->phy_proc_tx.trials, - PHY_vars_eNB->ofdm_mod_stats.trials, - PHY_vars_eNB->dlsch_modulation_stats.trials, - PHY_vars_eNB->dlsch_scrambling_stats.trials, - PHY_vars_eNB->dlsch_encoding_stats.trials, - PHY_vars_UE->phy_proc_rx.trials, - PHY_vars_UE->ofdm_demod_stats.trials, - PHY_vars_UE->dlsch_rx_pdcch_stats.trials, - PHY_vars_UE->dlsch_llr_stats.trials, - PHY_vars_UE->dlsch_unscrambling_stats.trials, - PHY_vars_UE->dlsch_decoding_stats.trials - ); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;", - get_time_meas_us(&PHY_vars_eNB->phy_proc_tx), - get_time_meas_us(&PHY_vars_eNB->ofdm_mod_stats), - get_time_meas_us(&PHY_vars_eNB->dlsch_modulation_stats), - get_time_meas_us(&PHY_vars_eNB->dlsch_scrambling_stats), - get_time_meas_us(&PHY_vars_eNB->dlsch_encoding_stats), - get_time_meas_us(&PHY_vars_UE->phy_proc_rx), - nsymb*get_time_meas_us(&PHY_vars_UE->ofdm_demod_stats), - get_time_meas_us(&PHY_vars_UE->dlsch_rx_pdcch_stats), - 3*get_time_meas_us(&PHY_vars_UE->dlsch_llr_stats), - get_time_meas_us(&PHY_vars_UE->dlsch_unscrambling_stats), - get_time_meas_us(&PHY_vars_UE->dlsch_decoding_stats) - ); - //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); - - //fprintf(time_meas_fd,"IFFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - - //fprintf(time_meas_fd,"MOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - - //fprintf(time_meas_fd,"ENC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - - - //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); + fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + SNR, + mcs1, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + rate*effective_rate, + 100*effective_rate, + rate, + (double)avg_iter[0]/iter_trials[0], + errs[0][0], + round_trials[0], + errs[0][1], + round_trials[1], + errs[0][2], + round_trials[2], + errs[0][3], + round_trials[3], + (double)errs[0][0]/(round_trials[0]), + (double)errs[0][1]/(round_trials[0]), + (double)errs[0][2]/(round_trials[0]), + (double)errs[0][3]/(round_trials[0]), + dci_errors, + round_trials[0], + (double)dci_errors/(round_trials[0]), + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); + } + else { + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + SNR, + mcs1,mcs2, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, + rate, + errs[0][0], + round_trials[0], + errs[0][1], + round_trials[1], + errs[0][2], + round_trials[2], + errs[0][3], + round_trials[3], + dci_errors); + + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + SNR, + mcs1,mcs2, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, + rate*effective_rate, + 100*effective_rate, + rate, + (double)avg_iter[0]/iter_trials[0], + errs[0][0], + round_trials[0], + errs[0][1], + round_trials[1], + errs[0][2], + round_trials[2], + errs[0][3], + round_trials[3], + (double)errs[0][0]/(round_trials[0]), + (double)errs[0][1]/(round_trials[0]), + (double)errs[0][2]/(round_trials[0]), + (double)errs[0][3]/(round_trials[0]), + dci_errors, + round_trials[0], + (double)dci_errors/(round_trials[0]), + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); + } + //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", + fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", + PHY_vars_eNB->phy_proc_tx.trials, + PHY_vars_eNB->ofdm_mod_stats.trials, + PHY_vars_eNB->dlsch_modulation_stats.trials, + PHY_vars_eNB->dlsch_scrambling_stats.trials, + PHY_vars_eNB->dlsch_encoding_stats.trials, + PHY_vars_UE->phy_proc_rx.trials, + PHY_vars_UE->ofdm_demod_stats.trials, + PHY_vars_UE->dlsch_rx_pdcch_stats.trials, + PHY_vars_UE->dlsch_llr_stats.trials, + PHY_vars_UE->dlsch_unscrambling_stats.trials, + PHY_vars_UE->dlsch_decoding_stats.trials + ); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;", + get_time_meas_us(&PHY_vars_eNB->phy_proc_tx), + get_time_meas_us(&PHY_vars_eNB->ofdm_mod_stats), + get_time_meas_us(&PHY_vars_eNB->dlsch_modulation_stats), + get_time_meas_us(&PHY_vars_eNB->dlsch_scrambling_stats), + get_time_meas_us(&PHY_vars_eNB->dlsch_encoding_stats), + get_time_meas_us(&PHY_vars_UE->phy_proc_rx), + nsymb*get_time_meas_us(&PHY_vars_UE->ofdm_demod_stats), + get_time_meas_us(&PHY_vars_UE->dlsch_rx_pdcch_stats), + 3*get_time_meas_us(&PHY_vars_UE->dlsch_llr_stats), + get_time_meas_us(&PHY_vars_UE->dlsch_unscrambling_stats), + get_time_meas_us(&PHY_vars_UE->dlsch_decoding_stats) + ); + //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); + + //fprintf(time_meas_fd,"IFFT;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); + + //fprintf(time_meas_fd,"MOD;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); + + //fprintf(time_meas_fd,"ENC;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); + + + //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - //fprintf(time_meas_fd,"FFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - - //fprintf(time_meas_fd,"DEMOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); - - //fprintf(time_meas_fd,"DEC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - + //fprintf(time_meas_fd,"FFT;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); + + //fprintf(time_meas_fd,"DEMOD;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); + + //fprintf(time_meas_fd,"DEC;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); + - /* - fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", - PHY_vars_eNB->phy_proc_tx.trials, - PHY_vars_eNB->ofdm_mod_stats.trials, - PHY_vars_eNB->dlsch_modulation_stats.trials, - PHY_vars_eNB->dlsch_scrambling_stats.trials, - PHY_vars_eNB->dlsch_encoding_stats.trials, - PHY_vars_UE->phy_proc_rx.trials, - PHY_vars_UE->ofdm_demod_stats.trials, - PHY_vars_UE->dlsch_rx_pdcch_stats.trials, - PHY_vars_UE->dlsch_llr_stats.trials, - PHY_vars_UE->dlsch_unscrambling_stats.trials, - PHY_vars_UE->dlsch_decoding_stats.trials); - */ - printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); - break; + /* + fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + PHY_vars_eNB->phy_proc_tx.trials, + PHY_vars_eNB->ofdm_mod_stats.trials, + PHY_vars_eNB->dlsch_modulation_stats.trials, + PHY_vars_eNB->dlsch_scrambling_stats.trials, + PHY_vars_eNB->dlsch_encoding_stats.trials, + PHY_vars_UE->phy_proc_rx.trials, + PHY_vars_UE->ofdm_demod_stats.trials, + PHY_vars_UE->dlsch_rx_pdcch_stats.trials, + PHY_vars_UE->dlsch_llr_stats.trials, + PHY_vars_UE->dlsch_unscrambling_stats.trials, + PHY_vars_UE->dlsch_decoding_stats.trials); + */ + printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); + break; } else if (test_perf !=0 ){ - printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); + printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); } - if (abstx == 1) { - if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { - if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) - break; - } - else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-2) - break; - - } - } - else { - - if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { - if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) - break; - } - else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-3) - break; - - } - - } - + if (abstx == 1) { + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { + if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) + break; + } + else{ + if (((double)errs[0][0]/(round_trials[0]))<1e-2) + break; + + } + } + else { + + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { + if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) + break; + } + else{ + if (((double)errs[0][0]/(round_trials[0]))<1e-3) + break; + + } + + } + if (n_frames==1) - break; + break; }// SNR From 4e8e70795114773b768e13f1e6fc19b355528539 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 7 Jul 2016 16:44:36 +0200 Subject: [PATCH 102/571] Some more clean up + adding second option for a precoder. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 1024 ++++++++++---------- openair1/SIMULATION/LTE_PHY/dlsim.c | 653 +++++++------ openair1/SIMULATION/TOOLS/random_channel.c | 4 +- 3 files changed, 841 insertions(+), 840 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 9e111f0901..a9e8c78f3f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -481,9 +481,9 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { case 15: if (vrb<12) { if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11 - return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); + return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13 - return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); + return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); } if (vrb==12) return (3+(7*odd_slot)) % 14; @@ -500,43 +500,43 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { if (Ngap==0) { // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27 if (vrb>=23) - offset=4; + offset=4; else - offset=0; + offset=0; if (vrb<44) { - if ((vrb&3)>=2) - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; - else - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; + if ((vrb&3)>=2) + return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; + else + return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; } if (vrb==44) // even: 44->11, odd: 45->34 - return offset+((23*odd_slot) + 22-12+1); + return offset+((23*odd_slot) + 22-12+1); if (vrb==45) // even: 45->10, odd: 45->33 - return offset+((23*odd_slot) + 22+12); + return offset+((23*odd_slot) + 22+12); if (vrb==46) - return offset+46+((23*odd_slot) + 23-12+1) % 46; + return offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==47) - return offset+46+((23*odd_slot) + 23+12) % 46; + return offset+46+((23*odd_slot) + 23+12) % 46; if (vrb==48) - return offset+46+((23*odd_slot) + 23-12+1) % 46; + return offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==49) - return offset+46+((23*odd_slot) + 23+12) % 46; + return offset+46+((23*odd_slot) + 23+12) % 46; } else { // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27 if (vrb>=9) - offset=18; + offset=18; else - offset=0; + offset=0; if (vrb<12) { - if ((vrb&3)>=2) - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; - else - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; + if ((vrb&3)>=2) + return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; + else + return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; } else { - return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); + return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); } } break; @@ -742,7 +742,7 @@ void generate_RIV_tables() nVRB_even_dist = get_prb(100,0,nVRB,0); // if ((RBstart==0) && (Lcrbs<=8)) -// printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist); +// printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist); if (nVRB_even_dist<32) @@ -750,16 +750,16 @@ void generate_RIV_tables() else if (nVRB_even_dist<64) allocdist1_0_even |= (1<<(nVRB_even_dist-32)); else if (nVRB_even_dist<96) - allocdist2_0_even |= (1<<(nVRB_even_dist-64)); + allocdist2_0_even |= (1<<(nVRB_even_dist-64)); else - allocdist3_0_even |= (1<<(nVRB_even_dist-96)); + allocdist3_0_even |= (1<<(nVRB_even_dist-96)); /* if ((RBstart==0) && (Lcrbs<=8)) - printf("rballoc =>(%08x.%08x.%08x.%08x)\n", - allocdist0_0_even, - allocdist1_0_even, - allocdist2_0_even, - allocdist3_0_even - ); + printf("rballoc =>(%08x.%08x.%08x.%08x)\n", + allocdist0_0_even, + allocdist1_0_even, + allocdist2_0_even, + allocdist3_0_even + ); */ // Distributed Gap1, odd slot nVRB_odd_dist = get_prb(100,1,nVRB,0); @@ -768,9 +768,9 @@ void generate_RIV_tables() else if (nVRB_odd_dist<64) allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); else if (nVRB_odd_dist<96) - allocdist2_0_odd |= (1<<(nVRB_odd_dist-64)); + allocdist2_0_odd |= (1<<(nVRB_odd_dist-64)); else - allocdist3_0_odd |= (1<<(nVRB_odd_dist-96)); + allocdist3_0_odd |= (1<<(nVRB_odd_dist-96)); // Distributed Gap2, even slot @@ -780,9 +780,9 @@ void generate_RIV_tables() else if (nVRB_even_dist<64) allocdist1_1_even |= (1<<(nVRB_even_dist-32)); else if (nVRB_even_dist<96) - allocdist2_1_even |= (1<<(nVRB_even_dist-64)); + allocdist2_1_even |= (1<<(nVRB_even_dist-64)); else - allocdist3_1_even |= (1<<(nVRB_even_dist-96)); + allocdist3_1_even |= (1<<(nVRB_even_dist-96)); // Distributed Gap2, odd slot @@ -792,9 +792,9 @@ void generate_RIV_tables() else if (nVRB_odd_dist<64) allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); else if (nVRB_odd_dist<96) - allocdist2_1_odd |= (1<<(nVRB_odd_dist-64)); + allocdist2_1_odd |= (1<<(nVRB_odd_dist-64)); else - allocdist3_1_odd |= (1<<(nVRB_odd_dist-96)); + allocdist3_1_odd |= (1<<(nVRB_odd_dist-96)); RIV=computeRIV(100,RBstart,Lcrbs); @@ -860,7 +860,7 @@ uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti) } int generate_eNB_dlsch_params_from_dci(int frame, - uint8_t subframe, + uint8_t subframe, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, @@ -871,7 +871,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, uint16_t ra_rnti, uint16_t p_rnti, uint16_t DL_pmi_single - ) + ) { uint8_t harq_pid = UINT8_MAX; @@ -928,11 +928,11 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; if (vrb_type==LOCALIZED) { - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rballoc]; + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rballoc]; } else { - LOG_E(PHY,"Distributed RB allocation not done yet\n"); - mac_xface->macphy_exit("exiting"); + LOG_E(PHY,"Distributed RB allocation not done yet\n"); + mac_xface->macphy_exit("exiting"); } dlsch0_harq->vrb_type = vrb_type; dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc];//NPRB; @@ -966,11 +966,11 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (vrb_type==LOCALIZED) { - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rballoc]; + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rballoc]; } else { - LOG_E(PHY,"Distributed RB allocation not done yet\n"); - mac_xface->macphy_exit("exiting"); + LOG_E(PHY,"Distributed RB allocation not done yet\n"); + mac_xface->macphy_exit("exiting"); } dlsch0_harq->vrb_type = vrb_type; dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc];//NPRB; @@ -999,12 +999,12 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; if (vrb_type==LOCALIZED) { - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rballoc]; } else { - LOG_E(PHY,"Distributed RB allocation not done yet\n"); - mac_xface->macphy_exit("exiting"); + LOG_E(PHY,"Distributed RB allocation not done yet\n"); + mac_xface->macphy_exit("exiting"); } @@ -1036,14 +1036,14 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq->vrb_type = vrb_type; if (vrb_type==LOCALIZED) { - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rballoc]; } else { - LOG_E(PHY,"Distributed RB allocation not done yet\n"); - mac_xface->macphy_exit("exiting"); + LOG_E(PHY,"Distributed RB allocation not done yet\n"); + mac_xface->macphy_exit("exiting"); } @@ -1564,64 +1564,64 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; - switch (tpmi) { - case 0: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); - break; - case 1: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; + switch (tpmi) { + case 0: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + break; + case 1: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); - break; - case 2: // PUSCH precoding - dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch0_harq->pmi_alloc = DL_pmi_single; - dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = DL_pmi_single; - break; - default: - break; - } + break; + case 2: // PUSCH precoding + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch0_harq->pmi_alloc = DL_pmi_single; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->pmi_alloc = DL_pmi_single; + break; + default: + break; + } } else { // only one is active - dlsch0_harq->dl_power_off = 1; - dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - switch (tpmi) { - case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); - break; - case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); - break; - case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); - break; - case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); - break; - case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - dlsch0_harq->pmi_alloc = DL_pmi_single; - break; - case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - dlsch0_harq->pmi_alloc = DL_pmi_single; - break; - } + dlsch0_harq->dl_power_off = 1; + dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + switch (tpmi) { + case 0 : + dlsch0_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); + break; + case 2: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); + break; + case 3: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); + break; + case 4: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); + break; + case 5: + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + dlsch0_harq->pmi_alloc = DL_pmi_single; + break; + case 6: + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + dlsch0_harq->pmi_alloc = DL_pmi_single; + break; + } } } else if (frame_parms->nb_antennas_tx == 4) { // fill in later @@ -1917,7 +1917,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; if ((dlsch0->active==1) && (dlsch1->active==1)) { - + dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->dl_power_off = 1; @@ -2154,8 +2154,8 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); + rballoc, + frame_parms->N_RB_DL); dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; dlsch0_harq->mcs = mcs1; @@ -3109,7 +3109,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) case 6: LOG_D(PHY,"DCI format1C (1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n", - ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]); + ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]); LOG_D(PHY,"MCS %d\n",((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->mcs); break; @@ -3838,7 +3838,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) int generate_ue_dlsch_params_from_dci(int frame, - uint8_t subframe, + uint8_t subframe, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, @@ -3914,16 +3914,16 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT6[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; + dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; } if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc]; + dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc]; } else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; } dlsch0_harq->vrb_type = vrb_type; @@ -3970,16 +3970,16 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT25[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; + dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; } if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc]; + dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc]; } else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; } dlsch0_harq->vrb_type = vrb_type; dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc]; @@ -4023,30 +4023,30 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT50[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; + dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; } if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; - // printf("rballoc: %08x.%08x\n",dlsch0_harq->rb_alloc_even[0],dlsch0_harq->rb_alloc_even[1]); + dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; + // printf("rballoc: %08x.%08x\n",dlsch0_harq->rb_alloc_even[0],dlsch0_harq->rb_alloc_even[1]); } else { // DISTRIBUTED - if ((rballoc&(1<<10)) == 0) { - rballoc = rballoc&(~(1<<10)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } - else { - rballoc = rballoc&(~(1<<10)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } + if ((rballoc&(1<<10)) == 0) { + rballoc = rballoc&(~(1<<10)); + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } + else { + rballoc = rballoc&(~(1<<10)); + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } } dlsch0_harq->vrb_type = vrb_type; @@ -4090,41 +4090,41 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT100[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; + dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; } if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; } else { - if ((rballoc&(1<<10)) == 0) { //Gap 1 - rballoc = rballoc&(~(1<<12)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; - } - else { //Gap 2 - rballoc = rballoc&(~(1<<12)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; - } + if ((rballoc&(1<<10)) == 0) { //Gap 1 + rballoc = rballoc&(~(1<<12)); + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + } + else { //Gap 2 + rballoc = rballoc&(~(1<<12)); + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + } } dlsch0_harq->vrb_type = vrb_type; @@ -4153,7 +4153,7 @@ int generate_ue_dlsch_params_from_dci(int frame, // if ((dlsch0_harq->round == 4) || ( { dlsch0_harq->round = 0; dlsch0_harq->first_tx = 1; - // } + // } // if (dlsch0_harq->round == 0) // ndi = 1-dlsch0_harq->DCINdi; @@ -4168,14 +4168,14 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->dl_power_off = 1; //no power offset LOG_D(PHY,"UE (%x/%d): Subframe %d Format1A DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d, round %d\n", - dlsch[0]->rnti, - harq_pid, - subframe, - ndi, - dlsch0_harq->DCINdi, - dlsch0_harq->first_tx, - dlsch0_harq->status, - dlsch0_harq->round); + dlsch[0]->rnti, + harq_pid, + subframe, + ndi, + dlsch0_harq->DCINdi, + dlsch0_harq->first_tx, + dlsch0_harq->status, + dlsch0_harq->round); if ((ndi!=dlsch0_harq->DCINdi)|| // DCI has been toggled or this is the first transmission (dlsch0_harq->first_tx==1)) { dlsch0_harq->round = 0; @@ -4228,7 +4228,7 @@ int generate_ue_dlsch_params_from_dci(int frame, RIV_max = RIV_max25; // printf("Format1C : %x : mcs %d, rballoc %d=>%d=>%x\n",((uint32_t*)dci_pdu)[0], - // mcs,((DCI1C_5MHz_t *)dci_pdu)->rballoc,rballoc,dlsch0_harq->rb_alloc_even[0]); + // mcs,((DCI1C_5MHz_t *)dci_pdu)->rballoc,rballoc,dlsch0_harq->rb_alloc_even[0]); break; case 50: @@ -4237,16 +4237,16 @@ int generate_ue_dlsch_params_from_dci(int frame, Ngap = ((DCI1C_10MHz_t *)dci_pdu)->Ngap; dlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc]; if (Ngap == 0) { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; } else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; } RIV_max = RIV_max50; @@ -4258,35 +4258,35 @@ int generate_ue_dlsch_params_from_dci(int frame, Ngap = ((DCI1C_20MHz_t *)dci_pdu)->Ngap; dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc]; if (Ngap==0) { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; } else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; } RIV_max = RIV_max100; /* printf("Format1C : %x : mcs %d, rballoc %d=>%d=>(%08x.%08x.%08x.%08x), Ngap %d\n",((uint32_t*)dci_pdu)[0], - mcs,((DCI1C_20MHz_t *)dci_pdu)->rballoc,rballoc, - dlsch0_harq->rb_alloc_even[0], - dlsch0_harq->rb_alloc_even[1], - dlsch0_harq->rb_alloc_even[2], - dlsch0_harq->rb_alloc_even[3], - Ngap - ); + mcs,((DCI1C_20MHz_t *)dci_pdu)->rballoc,rballoc, + dlsch0_harq->rb_alloc_even[0], + dlsch0_harq->rb_alloc_even[1], + dlsch0_harq->rb_alloc_even[2], + dlsch0_harq->rb_alloc_even[3], + Ngap + ); */ break; @@ -4307,9 +4307,9 @@ int generate_ue_dlsch_params_from_dci(int frame, if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321 if (((frame&1) == 0) && (subframe == 5)) - dlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 + dlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 else - dlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs + dlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs } else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3 dlsch0_harq->rvidx = 0; @@ -4321,11 +4321,11 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->dl_power_off = 1; //no power offset LOG_D(PHY,"UE (%x/%d): Subframe %d Format1C DCI: harq_status %d, round %d\n", - dlsch[0]->rnti, - harq_pid, - subframe, - dlsch0_harq->status, - dlsch0_harq->round); + dlsch[0]->rnti, + harq_pid, + subframe, + dlsch0_harq->status, + dlsch0_harq->round); dlsch0_harq->mcs = mcs; @@ -4416,7 +4416,7 @@ int generate_ue_dlsch_params_from_dci(int frame, rah = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah; rballoc = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC; + TPC = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid; } @@ -4525,245 +4525,245 @@ int generate_ue_dlsch_params_from_dci(int frame, case 6: if (frame_parms->nb_antennas_tx_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi; + } } else if (frame_parms->nb_antennas_tx_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + } } else { - LOG_E(PHY,"UE: subframe %d Format2 DCI: unsupported number of TX antennas %d\n",subframe,frame_parms->nb_antennas_tx_eNB); + LOG_E(PHY,"UE: subframe %d Format2 DCI: unsupported number of TX antennas %d\n",subframe,frame_parms->nb_antennas_tx_eNB); } break; case 25: if (frame_parms->nb_antennas_tx_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; + } } else if (frame_parms->nb_antennas_tx_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + } } break; case 50: if (frame_parms->nb_antennas_tx_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; + } } else if (frame_parms->nb_antennas_tx_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; + } } else { - LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); } break; case 100: if (frame_parms->nb_antennas_tx_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; + } } else if (frame_parms->nb_antennas_tx_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; - } + if (frame_type == TDD) { + mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; + } + else { + mcs1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; + } } else { - LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB); } break; @@ -4814,8 +4814,8 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); + rballoc, + frame_parms->N_RB_DL); dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; dlsch0_harq->mcs = mcs1; @@ -4864,60 +4864,60 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->dl_power_off = 1; switch (tpmi) { case 0: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - break; + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + break; case 1: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); - break; + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + break; case 2: // PUSCH precoding - dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; - break; + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; + break; default: - break; + break; } } else { dlsch0_harq->dl_power_off = 1; switch (tpmi) { case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; + dlsch0_harq->mimo_mode = ALAMOUTI; + break; case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); + break; case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + break; case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - LOG_E(PHY,"Unsupported TPMI\n"); - return(-1); - break; + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + LOG_E(PHY,"Unsupported TPMI\n"); + return(-1); + break; } } @@ -4927,46 +4927,46 @@ int generate_ue_dlsch_params_from_dci(int frame, if (dlsch0->active == 1) { if ((ndi1!=dlsch0_harq->DCINdi) || - (dlsch0_harq->first_tx==1)) { - dlsch0_harq->round = 0; - dlsch0_harq->status = ACTIVE; - dlsch0_harq->DCINdi = ndi1; - if (dlsch0_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); - dlsch0_harq->first_tx = 0; - } + (dlsch0_harq->first_tx==1)) { + dlsch0_harq->round = 0; + dlsch0_harq->status = ACTIVE; + dlsch0_harq->DCINdi = ndi1; + if (dlsch0_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); + dlsch0_harq->first_tx = 0; + } } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received - - dlsch0->harq_ack[subframe].ack = 1; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch0->harq_ack[subframe].send_harq_status = 1; - dlsch0->active = 0; + + dlsch0->harq_ack[subframe].ack = 1; + dlsch0->harq_ack[subframe].harq_id = harq_pid; + dlsch0->harq_ack[subframe].send_harq_status = 1; + dlsch0->active = 0; } } if (dlsch1->active == 1) { if ((ndi2!=dlsch1_harq->DCINdi) || - (dlsch1_harq->first_tx==1)) { - dlsch1_harq->round = 0; - dlsch1_harq->status = ACTIVE; - dlsch1_harq->DCINdi = ndi2; - if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); - dlsch1_harq->first_tx = 0; - } + (dlsch1_harq->first_tx==1)) { + dlsch1_harq->round = 0; + dlsch1_harq->status = ACTIVE; + dlsch1_harq->DCINdi = ndi2; + if (dlsch1_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); + dlsch1_harq->first_tx = 0; + } } else if (dlsch1_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received - - dlsch1->harq_ack[subframe].ack = 1; - dlsch1->harq_ack[subframe].harq_id = harq_pid; - dlsch1->harq_ack[subframe].send_harq_status = 1; - dlsch1->active = 0; + + dlsch1->harq_ack[subframe].ack = 1; + dlsch1->harq_ack[subframe].harq_id = harq_pid; + dlsch1->harq_ack[subframe].send_harq_status = 1; + dlsch1->active = 0; } } @@ -4975,11 +4975,11 @@ int generate_ue_dlsch_params_from_dci(int frame, if (dlsch0_harq->nb_rb>1) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; if (mcs1 <= 28) - dlsch0_harq->Qm = get_Qm(mcs1); + dlsch0_harq->Qm = get_Qm(mcs1); else if (mcs1<=31) - dlsch0_harq->Qm = (mcs1-28)<<1; + dlsch0_harq->Qm = (mcs1-28)<<1; else - LOG_E(PHY,"invalid mcs1 %d\n",mcs1); + LOG_E(PHY,"invalid mcs1 %d\n",mcs1); } else dlsch0_harq->TBS =0; @@ -5001,9 +5001,9 @@ int generate_ue_dlsch_params_from_dci(int frame, if (dlsch1_harq->nb_rb>1) { dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; if (mcs2 <= 28) - dlsch1_harq->Qm = get_Qm(mcs2); + dlsch1_harq->Qm = get_Qm(mcs2); else if (mcs1<=31) - dlsch1_harq->Qm = (mcs2-28)<<1; + dlsch1_harq->Qm = (mcs2-28)<<1; else LOG_E(PHY,"invalid mcs2 %d\n",mcs2); } else @@ -5894,14 +5894,16 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) else if (rank==1) { for (aarx=0; aarxnb_antennas_rx; aarx++) { pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; - //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]); + //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]); pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; - //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); + //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); } - if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im))) - pmiq = PMI_2A_R1_11; - else - pmiq = PMI_2A_R1_1j; + if (pmi_re >= pmi_im) // this is not orthogonal + // this is orthogonal + //if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im))) + pmiq = PMI_2A_R1_11; + else + pmiq = PMI_2A_R1_1j; // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); // printf("subband %d, pmi%d \n",i,pmiq); @@ -7278,8 +7280,8 @@ int generate_eNB_ulsch_params_from_dci(void *dci_pdu, harq_pid = subframe2harq_pid(frame_parms, pdcch_alloc2ul_frame(frame_parms, - phy_vars_eNB->proc[sched_subframe].frame_tx, - subframe), + phy_vars_eNB->proc[sched_subframe].frame_tx, + subframe), pdcch_alloc2ul_subframe(frame_parms,subframe)); // printf("eNB: sched_subframe %d, subframe %d, frame_tx %d\n",sched_subframe,subframe,phy_vars_eNB->proc[sched_subframe].frame_tx); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 49635d386d..c840ee2cf0 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -476,7 +476,7 @@ int main(int argc, char **argv) break; case 'Q': channel_model=Rayleigh1_orth_eff_ch_TM4_prec_real; // for DUALSTREAM_UNIFORM_PRECODING1 when interf is precancelled - break; + break; case 'R': channel_model=Rayleigh1_orth_eff_ch_TM4_prec_imag; // for DUALSTREAM_UNIFORM_PRECODINGj when interf is precancelled break; @@ -525,49 +525,49 @@ int main(int argc, char **argv) break; case 'R': - num_rounds=atoi(optarg); - break; + num_rounds=atoi(optarg); + break; case 'S': - subframe=atoi(optarg); - break; + subframe=atoi(optarg); + break; case 'T': - n_rnti=atoi(optarg); - break; + n_rnti=atoi(optarg); + break; case 'u': - rx_type = (RX_type_t) atoi(optarg); - if (rx_typerx_SIC_dual_stream) { - printf("Unsupported rx type %d\n",rx_type); - exit(-1); - } - break; + rx_type = (RX_type_t) atoi(optarg); + if (rx_typerx_SIC_dual_stream) { + printf("Unsupported rx type %d\n",rx_type); + exit(-1); + } + break; case 'v': - i_mod = atoi(optarg); - if (i_mod!=2 && i_mod!=4 && i_mod!=6) { - msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); - exit(-1); - } - break; + i_mod = atoi(optarg); + if (i_mod!=2 && i_mod!=4 && i_mod!=6) { + msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + exit(-1); + } + break; case 'P': - print_perf=1; - break; + print_perf=1; + break; case 'X': - xforms = 1; - break; + xforms = 1; + break; case 'Z': - dump_table=1; - break; + dump_table=1; + break; case 'Y': - perfect_ce=1; - break; + perfect_ce=1; + break; case 'V': - interf_unaw_shift0=atoi(optarg); - break; + interf_unaw_shift0=atoi(optarg); + break; case 'W': - interf_unaw_shift1=atoi(optarg); - break; + interf_unaw_shift1=atoi(optarg); + break; case 'J': - interf_unaw_shift=atoi(optarg); - break; + interf_unaw_shift=atoi(optarg); + break; case 'h': default: printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); @@ -721,14 +721,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pnort.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_pnort.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pnort.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pmnew.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pnort.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -764,9 +764,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pmnew.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pnort.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pmnew.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pnort.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); @@ -3412,9 +3412,9 @@ n(tikz_fname,"w"); if(abstx){ if (trials==0 && round==0 && transmission_mode>=4){ for (iii=0; iiilte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[iii])); - fprintf(csv_fd,"%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); - //printf("%x ",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + //fprintf(csv_fd, "%d, %d", (PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[iii])); + fprintf(csv_fd,"%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + //printf("%x ",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); } } } @@ -3430,17 +3430,17 @@ n(tikz_fname,"w"); for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0,subframe); + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0,subframe); PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword; PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); if (n_frames==2) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword, - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); @@ -3454,12 +3454,12 @@ n(tikz_fname,"w"); uncoded_ber=0; printf("trials=%d\n", trials); for (i=0;idlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { - uncoded_ber_bit[i] = 1; - uncoded_ber++; - } - else - uncoded_ber_bit[i] = 0; + if (PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } + else + uncoded_ber_bit[i] = 0; uncoded_ber/=coded_bits_per_codeword; avg_ber += uncoded_ber; @@ -3476,50 +3476,49 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_ue[0][cw_non_sic], - coded_bits_per_codeword, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], - cw_non_sic, - subframe<<1); + 0, + PHY_vars_UE->dlsch_ue[0][cw_non_sic], + coded_bits_per_codeword, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], + cw_non_sic, + subframe<<1); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); ret[cw_non_sic] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw_non_sic], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid], - subframe, - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid, - 1,llr8_flag); + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][cw_non_sic], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid, + 1,llr8_flag); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { - if (cw_non_sic==0) { - avg_iter[0] += ret[0]; - iter_trials[0]++; + avg_iter[0] += ret[0]; + iter_trials[0]++; } if (n_frames==2) { - printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); - #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); - } - #endif + printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); + } + #endif } PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->current_harq_pid]->TBS; @@ -3622,250 +3621,250 @@ n(tikz_fname,"w"); } - if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && - rx_type==rx_SIC_dual_stream) { - remove("rho_rho_in_llr.m"); + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + rx_type==rx_SIC_dual_stream) { + remove("rho_rho_in_llr.m"); // for (round = 0 ; round < 1 ; round++) { - dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - - dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; - dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; - dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; - dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; - dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; - dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; - dlsch0_eNB_harq->round = dlsch0_ue_harq->round; - dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; - dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; - dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - - PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; - PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; - PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - - dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_UE->dlsch_eNB[eNB_id], - 0, - subframe, - &PHY_vars_UE->dlsch_rate_matching_stats, - &PHY_vars_UE->dlsch_turbo_encoding_stats, - &PHY_vars_UE->dlsch_interleaving_stats); - - - coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, - get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), - PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, - num_pdcch_symbols, - 0, - subframe); - - dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_eNB[eNB_id], - coded_bits_per_codeword, - 0, - subframe<<1); - - re_allocated = dlsch_modulation_SIC(sic_buffer, - subframe, - &PHY_vars_UE->lte_frame_parms, - num_pdcch_symbols, - &PHY_vars_UE->dlsch_eNB[0][0], - NULL, - coded_bits_per_codeword); - - // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); - // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - - switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ - - case 2: - - dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); - break; - - case 4: - - dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); - break; - case 6: - dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], - num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, - dlsch0_eNB_harq->nb_rb, - subframe, - dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); - break; - }// round - - // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); - - for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0, - subframe); - - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword; - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); - - if (n_frames==2) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword, - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); - - // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_sic); - sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword,1,0); - sprintf(fname,"dlsch_cw%d_e.m", cw_sic); - sprintf(vname,"dlschcw%d_e", cw_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); - uncoded_ber=0; - printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { - uncoded_ber_bit[i] = 1; - uncoded_ber++; - } else - uncoded_ber_bit[i] = 0; - - uncoded_ber/=coded_bits_per_codeword; - avg_ber += uncoded_ber; - sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); - sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); - printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); - free(uncoded_ber_bit); - uncoded_ber_bit = NULL; - } - - start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_ue[0][cw_sic], - coded_bits_per_codeword, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], - cw_sic, - subframe<<1); - stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); - - start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret[1] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw_sic], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], - subframe, - PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, - 1,llr8_flag); - stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - - - if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) - - avg_iter[1] += ret[1]; - iter_trials[1]++; - - - if (n_frames==2) { - printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); - #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); - } - #endif - } - - } - - - else { - errs[cw_sic][round]++; - // exit(0); - - if (cw_sic==1) { - avg_iter[1] += ret[1]-1; - iter_trials[1]++; - } - - if (n_frames==2) { - //if ((n_frames==1) || (SNR>=30)) { - printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); - #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); - } - #endif - } //n_frames==1 - // exit(0); - } //if (ret > PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) - } //for (int cw_1=cw_to_decode_interf_free; cw_1dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + + dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; + dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; + dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; + dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; + dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; + dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; + dlsch0_eNB_harq->round = dlsch0_ue_harq->round; + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; + dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; + dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; + dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0, + subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats); + + + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0, + subframe); + + dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword, + 0, + subframe<<1); + + re_allocated = dlsch_modulation_SIC(sic_buffer, + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL, + coded_bits_per_codeword); + + // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); + // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + + switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ + + case 2: + + dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + + case 4: + + dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + case 6: + dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + }// round - } //if SIC + // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); + + for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe); + + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword; + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); + + if (n_frames==2) { + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword, + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); + + // calculate uncoded BER + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_sic); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword,1,0); + sprintf(fname,"dlsch_cw%d_e.m", cw_sic); + sprintf(vname,"dlschcw%d_e", cw_sic); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + uncoded_ber=0; + printf("trials=%d\n", trials); + for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } else + uncoded_ber_bit[i] = 0; + + uncoded_ber/=coded_bits_per_codeword; + avg_ber += uncoded_ber; + sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); + sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); + printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); + free(uncoded_ber_bit); + uncoded_ber_bit = NULL; + } + + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_ue[0][cw_sic], + coded_bits_per_codeword, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + cw_sic, + subframe<<1); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + + start_meas(&PHY_vars_UE->dlsch_decoding_stats); + ret[1] = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][cw_sic], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, + 1,llr8_flag); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + + + if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + + avg_iter[1] += ret[1]; + iter_trials[1]++; + + + if (n_frames==2) { + printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + } + #endif + } + + } + + + else { + errs[cw_sic][round]++; + // exit(0); + + if (cw_sic==1) { + avg_iter[1] += ret[1]-1; + iter_trials[1]++; + } + + if (n_frames==2) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + } + #endif + } //n_frames==1 + // exit(0); + } //if (ret > PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + } //for (int cw_1=cw_to_decode_interf_free; cw_1dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index f763b49702..48c1fcb4af 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -51,7 +51,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, struct complex** R_sqrt, double Td, double sampling_rate, - double channel_bandwidth, + double channel_bandwidth, double ricean_factor, double aoa, double forgetting_factor, @@ -81,7 +81,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, chan_desc->delays[i] = ((double)i)*delta_tau; } else - chan_desc->delays = delays; + chan_desc->delays = delays; chan_desc->Td = Td; chan_desc->sampling_rate = sampling_rate; chan_desc->channel_bandwidth = channel_bandwidth; From 8cc39130e0ed7b0c0344b077287406fd34313595 Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 8 Jul 2016 01:46:54 +0200 Subject: [PATCH 103/571] Now dlsim computes throughput for both streams. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 201 +++++++++++++++------------- 1 file changed, 109 insertions(+), 92 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index c840ee2cf0..ab8a761651 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -142,7 +142,7 @@ int main(int argc, char **argv) int s,Kr,Kr_bytes; - double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1,rate; + double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1,rate[2]; double snr_step=1,input_snr_step=1, snr_int=30; LTE_DL_FRAME_PARMS *frame_parms; @@ -170,7 +170,7 @@ int main(int argc, char **argv) unsigned char *input_buffer0[2],*input_buffer1[2]; unsigned short input_buffer_length0,input_buffer_length1; unsigned int ret[2]; - unsigned int coded_bits_per_codeword=0,nsymb,dci_cnt,tbs=0; + unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[2][4],round_trials[4]={0,0,0,0},dci_errors=0,dlsch_active=0,num_layers; @@ -736,7 +736,7 @@ int main(int argc, char **argv) exit(-1); } - fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; dci_err\n"); + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); if (test_perf != 0) { char hostname[1024]; @@ -2705,7 +2705,7 @@ n(tikz_fname,"w"); for (k=0;klte_frame_parms, + coded_bits_per_codeword[cw] = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->nb_rb, PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->rb_alloc, get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), @@ -2715,18 +2715,18 @@ n(tikz_fname,"w"); #ifdef TBS_FIX // This is for MESH operation!!! - tbs = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][cw]->nb_rb-1]/4; + tbs[cw] = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][cw]->nb_rb-1]/4; #else - tbs = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->TBS; + tbs[cw] = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->TBS; #endif - rate = (double)tbs/(double)coded_bits_per_codeword; + rate[cw] = (double)tbs[cw]/(double)coded_bits_per_codeword[cw]; if ((SNR==snr0) && (trials==0) && (round==0) && (pmi_feedback==0)) printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", - k,cw,rate,rate*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), - coded_bits_per_codeword, - tbs, + k,cw,rate[cw],rate[cw]*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), + coded_bits_per_codeword[cw], + tbs[cw], get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), num_pdcch_symbols, PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->round); @@ -2789,7 +2789,7 @@ n(tikz_fname,"w"); dlsch_scrambling(&PHY_vars_eNB->lte_frame_parms, 0, PHY_vars_eNB->dlsch_eNB[k][cw], - coded_bits_per_codeword, + coded_bits_per_codeword[cw], cw, subframe<<1); stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); @@ -3230,7 +3230,7 @@ n(tikz_fname,"w"); 0, P_RNTI)==0)) { dump_dci(&PHY_vars_UE->lte_frame_parms,&dci_alloc_rx[i]); - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + coded_bits_per_codeword[0]= get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb, PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc_even, get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), @@ -3242,7 +3242,7 @@ n(tikz_fname,"w"); rate = (double)dlsch_tbs25[get_I_TBS(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs)][PHY_vars_UE->dlsch_ue[0][0]->nb_rb-1]/(coded_bits_per_codeword); rate*=get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs); */ - printf("num_pdcch_symbols %d, G %d, TBS %d\n",PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->TBS); + printf("num_pdcch_symbols %d, G %d, TBS %d\n",PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword [0],PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->TBS); dlsch_active = 1; } else { @@ -3429,31 +3429,31 @@ n(tikz_fname,"w"); for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, + coded_bits_per_codeword[cw_non_sic] = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->rb_alloc, get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs), PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, num_pdcch_symbols, 0,subframe); - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword; + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_non_sic]; PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); if (n_frames==2) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword, + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword[cw_non_sic], PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_non_sic]); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_non_sic); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword,1,0); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword[cw_non_sic],1,0); sprintf(fname,"dlsch_cw%d_e.m", cw_non_sic); sprintf(vname,"dlschcw%d_e", cw_non_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_non_sic],1,4); uncoded_ber=0; printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; @@ -3461,11 +3461,11 @@ n(tikz_fname,"w"); else uncoded_ber_bit[i] = 0; - uncoded_ber/=coded_bits_per_codeword; + uncoded_ber/=coded_bits_per_codeword[cw_non_sic]; avg_ber += uncoded_ber; sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_non_sic); sprintf(vname,"uncoded_ber_bit_cw%d", cw_non_sic); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[cw_non_sic],1,0); printf("cw %d, uncoded ber %f\n",cw_non_sic,uncoded_ber); @@ -3478,7 +3478,7 @@ n(tikz_fname,"w"); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, 0, PHY_vars_UE->dlsch_ue[0][cw_non_sic], - coded_bits_per_codeword, + coded_bits_per_codeword[cw_non_sic], PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], cw_non_sic, subframe<<1); @@ -3656,7 +3656,7 @@ n(tikz_fname,"w"); &PHY_vars_UE->dlsch_interleaving_stats); - coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, + coded_bits_per_codeword[cw_non_sic]= get_G(&PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), @@ -3668,7 +3668,7 @@ n(tikz_fname,"w"); dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, 0, PHY_vars_UE->dlsch_eNB[eNB_id], - coded_bits_per_codeword, + coded_bits_per_codeword[cw_non_sic], 0, subframe<<1); @@ -3678,7 +3678,7 @@ n(tikz_fname,"w"); num_pdcch_symbols, &PHY_vars_UE->dlsch_eNB[0][0], NULL, - coded_bits_per_codeword); + coded_bits_per_codeword[cw_non_sic]); // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); @@ -3737,45 +3737,45 @@ n(tikz_fname,"w"); for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, + coded_bits_per_codeword[cw_sic]= get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, num_pdcch_symbols, 0, subframe); - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword; + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_sic]; PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); if (n_frames==2) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword, + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword[cw_sic], PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_sic]); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_sic); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword,1,0); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword[cw_sic],1,0); sprintf(fname,"dlsch_cw%d_e.m", cw_sic); sprintf(vname,"dlschcw%d_e", cw_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_sic],1,4); uncoded_ber=0; printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } else uncoded_ber_bit[i] = 0; - uncoded_ber/=coded_bits_per_codeword; + uncoded_ber/=coded_bits_per_codeword[cw_sic]; avg_ber += uncoded_ber; sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword,1,0); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[cw_sic],1,0); printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); free(uncoded_ber_bit); uncoded_ber_bit = NULL; @@ -3783,12 +3783,12 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, - 0, - PHY_vars_UE->dlsch_ue[0][cw_sic], - coded_bits_per_codeword, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], - cw_sic, - subframe<<1); + 0, + PHY_vars_UE->dlsch_ue[0][cw_sic], + coded_bits_per_codeword[cw_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + cw_sic, + subframe<<1); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); @@ -3970,7 +3970,7 @@ n(tikz_fname,"w"); PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); } //pdsch_vars - dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword,round,PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid); + dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword[0],round,PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid); /* write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); @@ -4146,11 +4146,13 @@ n(tikz_fname,"w"); effective_rate = ((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n", - SNR, - (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), - sigma2_dB); + SNR, + (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), + sigma2_dB); - printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e)), dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f)\n", + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e))," + "dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f), " + "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n", errs[0][0], errs[1][0], round_trials[0], @@ -4174,12 +4176,21 @@ n(tikz_fname,"w"); dci_errors, round_trials[0], (double)dci_errors/(round_trials[0]), - rate*effective_rate, + rate[0]*effective_rate, 100*effective_rate, - rate, - rate*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); + rate[0], + rate[0]*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+ + 4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2]) + +4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0]), + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0])), + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0]))+ + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), + rate[0], + rate[1]); + if (print_perf==1) { @@ -4285,43 +4296,49 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_tc_intl2_stats.trials); } - if ((transmission_mode != 3) && (transmission_mode != 4)) { - fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", - SNR, - mcs1, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - rate, - errs[0][0], - round_trials[0], - errs[0][1], - round_trials[1], - errs[0][2], - round_trials[2], - errs[0][3], - round_trials[3], - dci_errors); + if ((transmission_mode != 3) && (transmission_mode != 4)) { + fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + SNR, + mcs1, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + rate[0], + errs[0][0], + round_trials[0], + errs[0][1], + round_trials[1], + errs[0][2], + round_trials[2], + errs[0][3], + round_trials[3], + dci_errors); } else { - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", - SNR, - mcs1,mcs2, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, - rate, - errs[0][0], - errs[1][0], - round_trials[0], - errs[0][1], - errs[1][1], - round_trials[1], - errs[0][2], - errs[1][2], - round_trials[2], - errs[0][3], - errs[1][3], - round_trials[3], - dci_errors); - } + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%d\n", + SNR, + mcs1, + mcs2, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, + rate[0], + rate[1], + errs[0][0], + errs[1][0], + round_trials[0], + errs[0][1], + errs[1][1], + round_trials[1], + errs[0][2], + errs[1][2], + round_trials[2], + errs[0][3], + errs[1][3], + round_trials[3], + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0])), + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0]))+ + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), + dci_errors); + } if(abstx){ //ABSTRACTION @@ -4382,7 +4399,7 @@ n(tikz_fname,"w"); SNR, mcs1, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - rate*effective_rate, + rate[0]*effective_rate, 100*effective_rate, rate, (double)avg_iter[0]/iter_trials[0], @@ -4427,7 +4444,7 @@ n(tikz_fname,"w"); mcs1,mcs2, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, - rate*effective_rate, + rate[0]*effective_rate, 100*effective_rate, rate, (double)avg_iter[0]/iter_trials[0], @@ -4516,10 +4533,10 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_unscrambling_stats.trials, PHY_vars_UE->dlsch_decoding_stats.trials); */ - printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); + printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate ); break; } else if (test_perf !=0 ){ - printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); + printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate[0]*effective_rate, 100*effective_rate, rate); } if (abstx == 1) { if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { From ce15e0e97b4d705380e72e21f523df0e35cabfac Mon Sep 17 00:00:00 2001 From: lukashov Date: Fri, 8 Jul 2016 10:49:53 +0200 Subject: [PATCH 104/571] Fixing warning and changing target precission to 10^(-2). --- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index ab8a761651..a70f0bb242 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -4383,7 +4383,7 @@ n(tikz_fname,"w"); SNR, mcs1, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - rate, + rate[0], errs[0][0], round_trials[0], errs[0][1], @@ -4401,7 +4401,7 @@ n(tikz_fname,"w"); PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, rate[0]*effective_rate, 100*effective_rate, - rate, + rate[0], (double)avg_iter[0]/iter_trials[0], errs[0][0], round_trials[0], @@ -4427,7 +4427,7 @@ n(tikz_fname,"w"); mcs1,mcs2, PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, - rate, + rate[0], errs[0][0], round_trials[0], errs[0][1], @@ -4446,7 +4446,7 @@ n(tikz_fname,"w"); PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, rate[0]*effective_rate, 100*effective_rate, - rate, + rate[0], (double)avg_iter[0]/iter_trials[0], errs[0][0], round_trials[0], @@ -4533,10 +4533,10 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_unscrambling_stats.trials, PHY_vars_UE->dlsch_decoding_stats.trials); */ - printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate ); + printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate[0]); break; } else if (test_perf !=0 ){ - printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate[0]*effective_rate, 100*effective_rate, rate); + printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate[0]*effective_rate, 100*effective_rate, rate[0]); } if (abstx == 1) { if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { From f7989c5ce9d98bc995b00bd497a9ea877c5fa464 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 23 Aug 2016 10:41:28 +0200 Subject: [PATCH 105/571] adding scheduling for TM4 (fallback to Alamouti for the moment) --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 156 ++++++++++++++++++++-- 1 file changed, 147 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index b841fa9364..958798445c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1418,18 +1418,156 @@ schedule_ue_spec( break; - /* - // disabled for now as this needs to be done properly case 4: - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = round&3; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc; + if (frame_parms[CC_id]->frame_type == TDD) { + switch (frame_parms[CC_id]->N_RB_DL) { + case 6: + // fall back to alamouti for now + ((DCI2_1_5MHz_2A_TDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_1_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_1_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_1_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_1_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = 0; + + // deactivate TB2 + ((DCI2A_1_5MHz_2A_TDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2A_1_5MHz_2A_TDD_t*)DLSCH_dci)->rv2 = 1; + + ((DCI2A_1_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + ((DCI2A_1_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc; + break; + + case 25: + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv2 = 1; + + LOG_D(MAC,"Format2 DCI: harq_pid %d, ndi %d\n",harq_pid,((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1); + break; + + case 50: + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_10MHz_2A_TDD_t*)DLSCH_dci)->rv2 = 1; + break; + + case 100: + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_20MHz_2A_TDD_t*)DLSCH_dci)->rv2 = 1; + break; + + default: + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv2 = 1; + break; + } + } else { + switch (frame_parms[CC_id]->N_RB_DL) { + case 6: + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_1_5MHz_2A_FDD_t*)DLSCH_dci)->rv2 = 1; + break; + + case 25: + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->rv2 = 1; + + LOG_I(MAC,"Format2 DCI: harq_pid %d, ndi %d\n",harq_pid,((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->ndi1); + break; + + case 50: + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->TPC = tpc; + // deactivate TB2 + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_10MHz_2A_FDD_t*)DLSCH_dci)->rv2 = 1; + break; + + case 100: + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_20MHz_2A_FDD_t*)DLSCH_dci)->rv2 = 1; + break; + + default: + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->tpmi = 0; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->mcs1 = mcs; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->harq_pid = harq_pid; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->ndi1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->TPC = tpc; + + // deactivate TB2 + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->mcs2 = 0; + ((DCI2_5MHz_2A_FDD_t*)DLSCH_dci)->rv2 = 1; + break; + } + } break; - + /* + // disabled for now as this needs to be done properly case 5: ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = mcs; From 5fda0110439ee5dd854803b4c882f8af78bf3932 Mon Sep 17 00:00:00 2001 From: lukashov Date: Mon, 5 Sep 2016 12:36:09 +0200 Subject: [PATCH 106/571] 1. Rician channel now operates with AoA 45 degrees. 2. Fixed a bug for HARQ rounds for TM1 frequency selective with PCE. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 27 +++++++++++----------- openair1/SIMULATION/TOOLS/abstraction.c | 2 +- openair1/SIMULATION/TOOLS/random_channel.c | 4 ++-- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a70f0bb242..4749d8e4cb 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -721,14 +721,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pnort.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_pnort.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pnort.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pnort.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -764,9 +764,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pnort.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pnort.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); @@ -2934,23 +2934,22 @@ n(tikz_fname,"w"); // Multipath channel if (awgn_flag == 0) { - multipath_channel(eNB2UE[0],s_re,s_im,r_re,r_im, + multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, 2*frame_parms->samples_per_tti,hold_channel); - if (PHY_vars_UE->perfect_ce==1){ - freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); - // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); - // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); - } // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); if(abstx==1 && num_rounds>1) if(round==0 && hold_channel==0){ random_channel(eNB2UE[1],0); random_channel(eNB2UE[2],0); - random_channel(eNB2UE[3],0); + random_channel(eNB2UE[3],0); } + if (PHY_vars_UE->perfect_ce==1){ + freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); + // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); + } } - // freq_channel(eNB2UE[0], NB_RB,12*NB_RB + 1); if(abstx){ if (trials==0 && round==0) { diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c index 938c8cdacd..680b284835 100644 --- a/openair1/SIMULATION/TOOLS/abstraction.c +++ b/openair1/SIMULATION/TOOLS/abstraction.c @@ -122,7 +122,7 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) start_meas(&desc->interp_freq); - for (f=-n_samples_max/2,f2=-n_samples/2; f<=n_samples_max/2; f+=d,f2++) { + for (f=-n_samples_max/2,f2=-n_samples/2; f Date: Sat, 10 Sep 2016 11:55:14 +0200 Subject: [PATCH 107/571] Changing round trial conditions in dlsim. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 8 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 57 ++++++++++++++++++-------- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 3e01ea5b5e..d7765a88a3 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1522,11 +1522,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, frame_parms->N_RB_DL, dlsch0_harq->rb_alloc); - dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; + dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL); + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; if (dlsch0_harq->nb_rb == 0) return(-1); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 4749d8e4cb..4bea75ec7f 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -169,6 +169,12 @@ int main(int argc, char **argv) unsigned char *input_buffer0[2],*input_buffer1[2]; unsigned short input_buffer_length0,input_buffer_length1; + + /* A variable "ret" is a nuumber of turbo iterations, that are performed in the turbo-decoder for each CW. + The decoder checks CRC, and if CRC test fails, it increments "ret". Ret is between 1 and 4, where 4 is for + the max number of turbo iterations. If the CRC is passed, ret is equal to a current iteration. + This is done separately for each CW inside decoding process. + Again: this is not a HARQ retransmission!*/ unsigned int ret[2]; unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; @@ -984,7 +990,7 @@ n(tikz_fname,"w"); for (k=0; kdlsch_eNB[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0); if (!PHY_vars_eNB->dlsch_eNB[k][i]) { @@ -1626,8 +1632,8 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; case 25: dci_length = sizeof_DCI2_5MHz_2A_TDD_t; @@ -2053,7 +2059,9 @@ n(tikz_fname,"w"); for (i=0; i<4; i++) { errs[0][i]=0; errs[1][i]=0; - round_trials[i] = 0; + /*Let see, how it will work, if */ + round_trials[i] = 0; + // round_trials_1[i] = 0; } dci_errors=0; //avg_ber = 0; @@ -2109,7 +2117,7 @@ n(tikz_fname,"w"); initialize(&time_vector_rx_dec); for (trials = 0;trialsnb_antennas_tx; i++) { @@ -2120,10 +2128,21 @@ n(tikz_fname,"w"); ret[0] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; ret[1] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; - while ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) { - //printf("Trial %d, round %d\n",trials,round); + + /*This condition indicates, that the round_trials must go on, while CRC keeps failing at + least for one of the CW and round < num_rounds. This also means that round_trials is a unique + variable for both CW*/ + + while ((round < num_rounds) && ((ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) \ + || (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations))) { + + //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); + //printf("round_trials %d round %d\n", round_trials[round], round); + round_trials[round]++; + //printf("round_trials %d round %d\n", round_trials[round], round); + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) pmi_feedback=1; else @@ -2258,8 +2277,8 @@ n(tikz_fname,"w"); } else { // FDD switch (transmission_mode) { - case 1: - case 2: + case 1: + case 2: switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; @@ -2642,6 +2661,7 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + //change tpmi } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); break; @@ -3192,7 +3212,7 @@ n(tikz_fname,"w"); dci_alloc_rx,1, eNB_id, subframe); - //printf("dci_cnt %d\n",dci_cnt); + printf("dci_cnt %d\n",dci_cnt); if (dci_cnt==0) { dlsch_active = 0; @@ -3427,6 +3447,7 @@ n(tikz_fname,"w"); } for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[cw_non_sic] = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, @@ -3435,23 +3456,28 @@ n(tikz_fname,"w"); PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, num_pdcch_symbols, 0,subframe); + PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_non_sic]; PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); - if (n_frames==2) { + + if (n_frames==1) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword[cw_non_sic], PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_non_sic]); + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_non_sic); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword[cw_non_sic],1,0); sprintf(fname,"dlsch_cw%d_e.m", cw_non_sic); sprintf(vname,"dlschcw%d_e", cw_non_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_non_sic],1,4); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_non_sic],1,4); uncoded_ber=0; printf("trials=%d\n", trials); + for (i=0;idlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { uncoded_ber_bit[i] = 1; @@ -3495,7 +3521,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { + if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { //If CRC for the first CW did not fail if (cw_non_sic==0) { avg_iter[0] += ret[0]; iter_trials[0]++; @@ -3623,7 +3649,6 @@ n(tikz_fname,"w"); if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && rx_type==rx_SIC_dual_stream) { - remove("rho_rho_in_llr.m"); // for (round = 0 ; round < 1 ; round++) { dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; @@ -3730,7 +3755,7 @@ n(tikz_fname,"w"); get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), PHY_vars_UE->dlsch_ue[eNB_id][0]); break; - }// round + } // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); @@ -3866,7 +3891,7 @@ n(tikz_fname,"w"); } //if SIC - } //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) + } //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) else { errs[cw_non_sic][round]++; From 856bb3abe9ce2a013ba03ee666dc760d5b7246e0 Mon Sep 17 00:00:00 2001 From: lukashov Date: Thu, 15 Sep 2016 13:51:19 +0200 Subject: [PATCH 108/571] Fixing previous commit. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 4bea75ec7f..34dd932d18 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2133,8 +2133,9 @@ n(tikz_fname,"w"); least for one of the CW and round < num_rounds. This also means that round_trials is a unique variable for both CW*/ - while ((round < num_rounds) && ((ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) \ - || (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations))) { + while (((transmission_mode == 3 || transmission_mode == 4) && ((round < num_rounds) && ((ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) + || (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) || + ((transmission_mode!=4 && transmission_mode != 3)&& ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) { //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); //printf("round_trials %d round %d\n", round_trials[round], round); From e202953ccb4750244f3b7b41b9d72b84d6a70e76 Mon Sep 17 00:00:00 2001 From: lukashov Date: Wed, 21 Sep 2016 11:51:16 +0200 Subject: [PATCH 109/571] 1.Fixing llr scaling for TM1 and TM2 in dlsch_demodulation.c 2.Fixing modulation for TM2 in dlsch_modulation.c The branch now passes dlsim tests. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 24 +++++++++---------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 19 ++++++++------- openair1/SIMULATION/LTE_PHY/dlsim.c | 24 ++++++++++--------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 8d33efd1d7..02b2126faa 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -212,7 +212,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, subframe, phy_vars_ue->high_speed_flag, frame_parms, - dlsch0_harq->mimo_mode); + dlsch0_harq->mimo_mode); //#ifdef DEBUG_DLSCH_MOD /* printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); for (rb=0;rbmimo_modedl_ch_estimates_ext, + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, @@ -330,7 +330,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avgs = cmax(avgs,avg[(aatx<<1)+aarx]); // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2); //+ interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1; //+ interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; // printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh); } @@ -625,11 +625,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, nb_rb); if (first_symbol_flag==1) { - dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - avg, - symbol, - nb_rb); + dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_rb); #ifdef DEBUG_PHY LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]); #endif @@ -4249,7 +4249,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, unsigned char subframe, uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms, - MIMO_mode_t mimo_mode) { + MIMO_mode_t mimo_mode) { int prb,nb_rb=0; int prb_off,prb_off2; @@ -4388,9 +4388,9 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int)); memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int)); memcpy(rxF_ext,rxF,12*sizeof(int)); - dl_ch0_ext +=12; - dl_ch1_ext +=12; - rxF_ext +=12; + dl_ch0_ext +=12; + dl_ch1_ext +=12; + rxF_ext +=12; } else { // pilots==1 j=0; for (i=0; i<12; i++) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 38af03db6d..781add5d95 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -410,10 +410,11 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj=*jj+1; - //((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15; - ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; + ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + + //((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15; + //((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; // Antenna 1 position n Real part -> -x1* @@ -435,11 +436,11 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, qam16_table_offset_im+=1; *jj=*jj+1; - //((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - ((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re]; - ((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; + //((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re]; + //((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; break; @@ -1248,7 +1249,7 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, return(0); } -uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb) +uint8_t get_pmi(uint8_t N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb) { /* MIMO_mode_t mode = dlsch_harq->mimo_mode; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 34dd932d18..2c0a39e1bf 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -4025,8 +4025,10 @@ n(tikz_fname,"w"); round++; } //round - //if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) - // break; + if(transmission_mode != 3 && transmission_mode !=4 ){ + if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) + break; + } //len = chbch_stats_read(stats_buffer,NULL,0,4096); //printf("%s\n\n",stats_buffer); @@ -4183,21 +4185,21 @@ n(tikz_fname,"w"); round_trials[0], errs[0][1], errs[1][1], - round_trials[1], + round_trials[0], errs[0][2], errs[1][2], - round_trials[2], + round_trials[0], errs[0][3], errs[1][3], - round_trials[3], + round_trials[0], (double)errs[0][0]/(round_trials[0]), (double)errs[1][0]/(round_trials[0]), - (double)errs[0][1]/(round_trials[1]), - (double)errs[1][1]/(round_trials[1]), - (double)errs[0][2]/(round_trials[2]), - (double)errs[1][2]/(round_trials[2]), - (double)errs[0][3]/(round_trials[3]), - (double)errs[1][3]/(round_trials[3]), + (double)errs[0][1]/(round_trials[0]), + (double)errs[1][1]/(round_trials[0]), + (double)errs[0][2]/(round_trials[0]), + (double)errs[1][2]/(round_trials[0]), + (double)errs[0][3]/(round_trials[0]), + (double)errs[1][3]/(round_trials[0]), dci_errors, round_trials[0], (double)dci_errors/(round_trials[0]), From f62063276a43de6a6138de978a6056f026361a2b Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 30 Sep 2016 16:23:49 +0200 Subject: [PATCH 110/571] timing measurement fixes --- openair1/PHY/TOOLS/time_meas.h | 12 ++++++++++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h index 3e621ac281..62bfceca5c 100644 --- a/openair1/PHY/TOOLS/time_meas.h +++ b/openair1/PHY/TOOLS/time_meas.h @@ -52,6 +52,7 @@ typedef struct { long long diff_square; /*!< \brief process duration square */ long long max; int trials; + int meas_flag; } time_stats_t; #elif defined(__arm__) typedef struct { @@ -105,9 +106,14 @@ static inline void start_meas(time_stats_t *ts) { if (opp_enabled) { - + if (ts->meas_flag==0) { ts->trials++; ts->in = rdtsc_oai(); + ts->meas_flag=1; + } + else { + ts->in = rdtsc_oai(); + } } } @@ -127,7 +133,8 @@ static inline void stop_meas(time_stats_t *ts) if ((out-ts->in) > ts->max) ts->max = out-ts->in; - + + ts->meas_flag=0; } } @@ -139,6 +146,7 @@ static inline void reset_meas(time_stats_t *ts) { ts->p_time=0; ts->diff_square=0; ts->max=0; + ts->meas_flag=0; } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 2c0a39e1bf..645ea3dc8e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2086,6 +2086,7 @@ n(tikz_fname,"w"); reset_meas(&PHY_vars_UE->dlsch_channel_estimation_stats); reset_meas(&PHY_vars_UE->dlsch_freq_offset_estimation_stats); reset_meas(&PHY_vars_UE->rx_dft_stats); + reset_meas(&PHY_vars_UE->dlsch_llr_stats); reset_meas(&PHY_vars_UE->dlsch_decoding_stats); reset_meas(&PHY_vars_UE->dlsch_turbo_decoding_stats); reset_meas(&PHY_vars_UE->dlsch_deinterleaving_stats); @@ -4241,7 +4242,7 @@ n(tikz_fname,"w"); std_phy_proc_tx_enc = sqrt((double)PHY_vars_eNB->dlsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, 2)/PHY_vars_eNB->dlsch_encoding_stats.trials - pow((double)PHY_vars_eNB->dlsch_encoding_stats.diff/PHY_vars_eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000,2)); printf("DLSCH encoding time :%f us (%d trials)\n",(double)PHY_vars_eNB->dlsch_encoding_stats.diff/PHY_vars_eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000.0, - PHY_vars_eNB->dlsch_modulation_stats.trials); + PHY_vars_eNB->dlsch_encoding_stats.trials); printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); printf("|__ DLSCH turbo encoding time :%f us (%d trials)\n", ((double)PHY_vars_eNB->dlsch_turbo_encoding_stats.trials/PHY_vars_eNB->dlsch_encoding_stats.trials)*(double) @@ -4257,7 +4258,7 @@ n(tikz_fname,"w"); std_phy_proc_rx = sqrt((double)PHY_vars_UE->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, 2)/PHY_vars_UE->phy_proc_rx.trials - pow((double)PHY_vars_UE->phy_proc_rx.diff/PHY_vars_UE->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); printf("Total PHY proc rx :%f us (%d trials)\n",(double)PHY_vars_UE->phy_proc_rx.diff/PHY_vars_UE->phy_proc_rx.trials/cpu_freq_GHz/1000.0, - PHY_vars_UE->phy_proc_rx.trials*2/3); + PHY_vars_UE->phy_proc_rx.trials); printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); std_phy_proc_rx_fft = sqrt((double)PHY_vars_UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, From 64116b90e1884d183c91650ce6d6e2ab2380afe8 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Sun, 23 Oct 2016 21:38:58 +0200 Subject: [PATCH 111/571] Adding HARQ support for TM4. No fallback to Alamouti yet. Counting for the number of 2CWs or 1CW retransmissions. Adding corresponding changes to the phy_scope. --- openair1/PHY/INIT/lte_init.c | 41 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 380 ++++++++----- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 34 +- openair1/PHY/TOOLS/lte_phy_scope.c | 4 +- openair1/PHY/defs.h | 7 + openair1/PHY/impl_defs_lte.h | 4 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 524 ++++++++++-------- 7 files changed, 570 insertions(+), 424 deletions(-) mode change 100644 => 100755 openair1/PHY/INIT/lte_init.c mode change 100644 => 100755 openair1/PHY/LTE_TRANSPORT/dci_tools.c mode change 100644 => 100755 openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c mode change 100644 => 100755 openair1/PHY/TOOLS/lte_phy_scope.c mode change 100644 => 100755 openair1/PHY/impl_defs_lte.h mode change 100644 => 100755 openair1/SIMULATION/LTE_PHY/dlsim.c diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c old mode 100644 new mode 100755 index 9105be5fdc..0e4c90799f --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -984,8 +984,8 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); pdsch->dl_ch_mag0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); pdsch->dl_ch_magb0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_mag1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_magb1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + //pdsch->dl_ch_mag1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + //pdsch->dl_ch_magb1 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); // the allocated memory size is fixed: AssertFatal( frame_parms->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); @@ -999,8 +999,8 @@ void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_mag0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_magb0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_mag1[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_magb1[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + //pdsch->dl_ch_mag1[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + //pdsch->dl_ch_magb1[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); } } } @@ -1172,29 +1172,34 @@ int phy_init_lte_ue(PHY_VARS_UE *phy_vars_ue, ue_pdsch_vars[eNB_id]->rho = (int32_t**)malloc16_clear( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); for (int i=0; inb_antennas_rx; i++) - ue_pdsch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(frame_parms->N_RB_DL*12*7*2) ); + ue_pdsch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(frame_parms->N_RB_DL*12*7*2) ); ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); for (i=0; inb_antennas_rx; i++) for (j=0; j<4; j++) { const int idx = (j<<1)+i; - const size_t num = 7*2*frame_parms->N_RB_DL*12+4; - ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + const size_t num = 7*2*frame_parms->N_RB_DL*12+4; + ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); } const size_t num = 7*2*frame_parms->N_RB_DL*12+4; for (k=0;k<8;k++) { //harq_pid - for (l=0;l<8;l++) { //round - ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - // ue_pdsch_vars[eNB_id]->clean_x1[k][l] = (int16_t*)malloc16_clear( sizeof(int32_t) * num); - - for (int i=0; inb_antennas_rx; i++) - for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) - const int idx = (j<<1)+i; - ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } + for (l=0;l<8;l++) { //round + ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + ue_pdsch_vars[eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + ue_pdsch_vars[eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + + // ue_pdsch_vars[eNB_id]->clean_x1[k][l] = (int16_t*)malloc16_clear( sizeof(int32_t) * num); + + for (int i=0; inb_antennas_rx; i++) + for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) + const int idx = (j<<1)+i; + ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + ue_pdsch_vars[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + ue_pdsch_vars[eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + ue_pdsch_vars[eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + } } } diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c old mode 100644 new mode 100755 index d7765a88a3..e685ca3da6 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -860,7 +860,7 @@ uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti) } int generate_eNB_dlsch_params_from_dci(int frame, - uint8_t subframe, + uint8_t subframe, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, @@ -871,7 +871,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, uint16_t ra_rnti, uint16_t p_rnti, uint16_t DL_pmi_single - ) + ) { uint8_t harq_pid = UINT8_MAX; @@ -1551,68 +1551,101 @@ int generate_eNB_dlsch_params_from_dci(int frame, } if (frame_parms->nb_antennas_tx == 2) { - if (dlsch1->active == 1) { // both TBs are active + if (dlsch0->active == 1 && dlsch1->active == 1) { // both TBs are active dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; - switch (tpmi) { - case 0: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); - break; - case 1: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; + switch (tpmi) { + case 0: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,1); + break; + case 1: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); - break; - case 2: // PUSCH precoding - dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch0_harq->pmi_alloc = DL_pmi_single; - dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = DL_pmi_single; - break; - default: - break; - } + break; + case 2: // PUSCH precoding + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch0_harq->pmi_alloc = DL_pmi_single; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->pmi_alloc = DL_pmi_single; + break; + default: + break; + } } - else { // only one is active - dlsch0_harq->dl_power_off = 1; - dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - switch (tpmi) { - case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); - break; - case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); - break; - case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); - break; - case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); - break; - case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - dlsch0_harq->pmi_alloc = DL_pmi_single; - break; - case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - dlsch0_harq->pmi_alloc = DL_pmi_single; - break; - } + else if (dlsch1->active == 0) { // only one is active + dlsch0_harq->dl_power_off = 1; + dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + switch (tpmi) { + case 0 : + dlsch0_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); + break; + case 2: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,0); + break; + case 3: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2,0); + break; + case 4: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3,0); + break; + case 5: + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + dlsch0_harq->pmi_alloc = DL_pmi_single; + break; + case 6: + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + dlsch0_harq->pmi_alloc = DL_pmi_single; + break; + } + } + else if (dlsch0->active == 0) { // only one is active + dlsch1_harq->dl_power_off = 1; + dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; + switch (tpmi) { + case 0 : + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,0); + break; + case 2: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1,0); + break; + case 3: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2,0); + break; + case 4: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3,0); + break; + case 5: + dlsch1_harq->mimo_mode = PUSCH_PRECODING0; + dlsch1_harq->pmi_alloc = DL_pmi_single; + break; + case 6: + dlsch1_harq->mimo_mode = PUSCH_PRECODING1; + dlsch1_harq->pmi_alloc = DL_pmi_single; + break; + } } } else if (frame_parms->nb_antennas_tx == 4) { // fill in later @@ -2670,6 +2703,20 @@ int generate_eNB_dlsch_params_from_dci(int frame, printf("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode); } + if (dlsch1) { + printf("dlsch1 eNB: dlsch1 %p\n",dlsch1); + printf("dlsch1 eNB: rnti %x\n",dlsch1->rnti); + printf("dlsch1 eNB: NBRB %d\n",dlsch1_harq->nb_rb); + printf("dlsch1 eNB: rballoc %x\n",dlsch1_harq->rb_alloc[0]); + printf("dlsch1 eNB: harq_pid %d\n",harq_pid); + printf("dlsch1 eNB: round %d\n",dlsch1_harq->round); + printf("dlsch1 eNB: rvidx %d\n",dlsch1_harq->rvidx); + printf("dlsch1 eNB: TBS %d (NPRB %d)\n",dlsch1_harq->TBS,NPRB); + printf("dlsch1 eNB: mcs %d\n",dlsch1_harq->mcs); + printf("dlsch1 eNB: tpmi %d\n",tpmi); + printf("dlsch1 eNB: mimo_mode %d\n",dlsch1_harq->mimo_mode); + } + #endif // compute DL power control parameters @@ -3794,7 +3841,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) int generate_ue_dlsch_params_from_dci(int frame, - uint8_t subframe, + uint8_t subframe, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, @@ -4730,10 +4777,11 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); } - if (frame_type == TDD) + /*if (frame_type == TDD) tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; else - tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;*/ + if (tbswap == 0) { dlsch0 = dlsch[0]; @@ -4769,16 +4817,16 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + dlsch0_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; dlsch0_harq->mcs = mcs1; dlsch1_harq->mcs = mcs2; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; dlsch[1]->g_pucch += delta_PUCCH_lut[TPC&3]; /* @@ -4789,8 +4837,8 @@ int generate_ue_dlsch_params_from_dci(int frame, */ - dlsch0_harq->rvidx = rv1; - dlsch1_harq->rvidx = rv2; + dlsch0_harq->rvidx = rv1; + dlsch1_harq->rvidx = rv2; // assume both TBs are active dlsch0_harq->Nl = 1; @@ -4802,11 +4850,14 @@ int generate_ue_dlsch_params_from_dci(int frame, // check if either TB is disabled (see 36-213 V8.6 p. 26) if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { + dlsch0_harq->status = DISABLED; + dlsch0->active = 0; } if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { dlsch1_harq->status = DISABLED; + dlsch1->active = 0; } dlsch0_harq->Nl = 1; @@ -4815,65 +4866,98 @@ int generate_ue_dlsch_params_from_dci(int frame, // dlsch0->layer_index = tbswap; // dlsch1->layer_index = 1-tbswap; - if (dlsch1->active==1) { //two codewords + if (dlsch0->active==1 && dlsch1->active==1) { //two TB dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; switch (tpmi) { case 0: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - break; + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + break; case 1: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); - break; + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + break; case 2: // PUSCH precoding - dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; - break; + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; + break; default: - break; + break; } - } - else { + } else if (dlsch1_harq->status == DISABLED) { dlsch0_harq->dl_power_off = 1; switch (tpmi) { case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; + dlsch0_harq->mimo_mode = ALAMOUTI; + break; case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); + break; case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + break; case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - LOG_E(PHY,"Unsupported TPMI\n"); - return(-1); - break; + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + LOG_E(PHY,"Unsupported TPMI\n"); + return(-1); + break; + } + } else if (dlsch0_harq->status == DISABLED) { + dlsch1_harq->dl_power_off = 1; + switch (tpmi) { + case 0 : + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); + break; + case 2: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; + case 3: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + break; + case 4: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; + case 5: + dlsch1_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; + case 6: + dlsch1_harq->mimo_mode = PUSCH_PRECODING1; + LOG_E(PHY,"Unsupported TPMI\n"); + return(-1); + break; } } @@ -4882,61 +4966,59 @@ int generate_ue_dlsch_params_from_dci(int frame, if (dlsch0->active == 1) { - if ((ndi1!=dlsch0_harq->DCINdi) || - (dlsch0_harq->first_tx==1)) { - dlsch0_harq->round = 0; - dlsch0_harq->status = ACTIVE; - dlsch0_harq->DCINdi = ndi1; - if (dlsch0_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); - dlsch0_harq->first_tx = 0; - } + if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { + dlsch0_harq->round = 0; + dlsch0_harq->status = ACTIVE; + dlsch0_harq->DCINdi = ndi1; + + if (dlsch0_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); + dlsch0_harq->first_tx = 0; + } } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received - dlsch0->harq_ack[subframe].ack = 1; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch0->harq_ack[subframe].send_harq_status = 1; - dlsch0->active = 0; + dlsch0->harq_ack[subframe].ack = 1; + dlsch0->harq_ack[subframe].harq_id = harq_pid; + dlsch0->harq_ack[subframe].send_harq_status = 1; + dlsch0->active = 0; } } if (dlsch1->active == 1) { - if ((ndi2!=dlsch1_harq->DCINdi) || - (dlsch1_harq->first_tx==1)) { - dlsch1_harq->round = 0; - dlsch1_harq->status = ACTIVE; - dlsch1_harq->DCINdi = ndi2; - if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); - dlsch1_harq->first_tx = 0; - } - } + if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { + dlsch1_harq->round = 0; + dlsch1_harq->status = ACTIVE; + dlsch1_harq->DCINdi = ndi2; + if (dlsch1_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); + dlsch1_harq->first_tx = 0; + } + } else if (dlsch1_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received - dlsch1->harq_ack[subframe].ack = 1; - dlsch1->harq_ack[subframe].harq_id = harq_pid; - dlsch1->harq_ack[subframe].send_harq_status = 1; - dlsch1->active = 0; + dlsch1->harq_ack[subframe].ack = 1; + dlsch1->harq_ack[subframe].harq_id = harq_pid; + dlsch1->harq_ack[subframe].send_harq_status = 1; + dlsch1->active = 0; } } - dlsch0_harq->mcs = mcs1; + // dlsch0_harq->mcs = mcs1; if (dlsch0_harq->nb_rb>1) { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; if (mcs1 <= 28) - dlsch0_harq->Qm = get_Qm(mcs1); + dlsch0_harq->Qm = get_Qm(mcs1); else if (mcs1<=31) - dlsch0_harq->Qm = (mcs1-28)<<1; + dlsch0_harq->Qm = (mcs1-28)<<1; else - LOG_E(PHY,"invalid mcs1 %d\n",mcs1); - + LOG_E(PHY,"invalid mcs1 %d\n",mcs1); } else dlsch0_harq->TBS =0; @@ -4952,14 +5034,14 @@ int generate_ue_dlsch_params_from_dci(int frame, } dlsch1_harq->DCINdi = ndi2; - dlsch1_harq->mcs = mcs2; + // dlsch1_harq->mcs = mcs2; if (dlsch1_harq->nb_rb>1) { - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; if (mcs2 <= 28) - dlsch1_harq->Qm = get_Qm(mcs2); + dlsch1_harq->Qm = get_Qm(mcs2); else if (mcs1<=31) - dlsch1_harq->Qm = (mcs2-28)<<1; + dlsch1_harq->Qm = (mcs2-28)<<1; else LOG_E(PHY,"invalid mcs2 %d\n",mcs2); } else diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c old mode 100644 new mode 100755 index 02b2126faa..b3bbbda114 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -233,7 +233,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, subframe, phy_vars_ue->high_speed_flag, frame_parms, - dlsch0_harq->mimo_mode); + dlsch0_harq->mimo_mode); else nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], @@ -246,7 +246,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, subframe, phy_vars_ue->high_speed_flag, frame_parms, - dlsch0_harq->mimo_mode); + dlsch0_harq->mimo_mode); } } // if n_tx>1 else { @@ -475,7 +475,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); @@ -517,13 +517,13 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, frame_parms, dlsch_ue, symbol, - nb_rb); + nb_rb); dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, - nb_rb); + nb_rb); /* compute new log2_maxh for effective channel */ if (first_symbol_flag==1) { @@ -734,7 +734,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; - dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1; + dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round]; } else { rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0; @@ -1011,7 +1011,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_16qam_llr(frame_parms, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->llr[1], - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); @@ -1024,8 +1024,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch_64qam_llr(frame_parms, rxdataF_comp_ptr, lte_ue_pdsch_vars[eNB_id]->llr[1], - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[harq_pid][round], symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); @@ -1040,7 +1040,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } } - return(0); + return(0); } @@ -1900,9 +1900,9 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; - int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; + int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1[harq_pid][round]; int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; - int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; + int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1[harq_pid][round]; int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; unsigned char *pmi_ext = lte_ue_pdsch_vars->pmi_ext; @@ -2290,9 +2290,9 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; - int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; + int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1[harq_pid][round]; int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; - int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; + int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1[harq_pid][round]; int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; @@ -2968,9 +2968,9 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for second stream int **dl_ch_rho2_ext =lte_ue_pdsch_vars->dl_ch_rho2_ext; int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; - int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1; + int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1[harq_pid][round]; int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; - int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1; + int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1[harq_pid][round]; if (frame_parms->nb_antennas_rx>1) { @@ -3107,7 +3107,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, short rb; unsigned char aatx,aarx,nre=12,symbol_mod; - __m128i *dl_ch128,avg128D; + __m128i *dl_ch128, avg128D; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c old mode 100644 new mode 100755 index 8c8357850b..85670502b8 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -624,9 +624,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[0][0])[0]; //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0]; pdsch_mag0 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0[0]; - pdsch_mag1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[0]; + pdsch_mag1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[0][0])[0]; pdsch_magb0 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0[0]; - pdsch_magb1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[0]; + pdsch_magb1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[0][0])[0]; fl_freeze_form(form->lte_phy_scope_ue); diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 26239b024c..9d941d3bd6 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -678,6 +678,13 @@ typedef struct { time_stats_t dlsch_tc_intl2_stats; time_stats_t tx_prach; + //for SIC + time_stats_t dlsch_encoding_SIC_stats; + time_stats_t dlsch_scrambling_SIC_stats; + time_stats_t dlsch_modulation_SIC_stats; + time_stats_t dlsch_llr_stripping_unit_SIC_stats; + time_stats_t dlsch_unscrambling_SIC_stats; + #if ENABLE_RAL hash_table_t *ral_thresholds_timed; SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h old mode 100644 new mode 100755 index b42ce4f784..e1736c9c9a --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -819,7 +819,7 @@ typedef struct { /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level). /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_mag1; + int32_t **dl_ch_mag1[8][8]; /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level). /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ @@ -827,7 +827,7 @@ typedef struct { /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level). /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ - int32_t **dl_ch_magb1; + int32_t **dl_ch_magb1[8][8]; /// \brief Cross-correlation of two eNB signals. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: symbol [0..] diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c old mode 100644 new mode 100755 index 2c0a39e1bf..335002a5ea --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -154,7 +154,7 @@ int main(int argc, char **argv) uint16_t Nid_cell=0; int8_t eNB_id = 0, eNB_id_i = 1; - unsigned char mcs1=0,mcs2=0,mcs_i=0,awgn_flag=0,round,dci_flag=0; + unsigned char mcs1=0,mcs2=0,mcs_i=0,awgn_flag=0,dci_flag=0; unsigned char i_mod = 2; unsigned short NB_RB; unsigned char Ns,l,m; @@ -178,7 +178,8 @@ int main(int argc, char **argv) unsigned int ret[2]; unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[2][4],round_trials[4]={0,0,0,0},dci_errors=0,dlsch_active=0,num_layers; + unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, round_sic=0; + unsigned int dci_errors=0, dlsch_active=0, num_layers; int re_allocated; char fname[32],vname[32]; @@ -187,7 +188,7 @@ int main(int argc, char **argv) FILE *time_meas_fd; char time_meas_fname[256]; - //FILE *tikz_fd; + //qFILE *tikz_fd; //char tikz_fname[256]; FILE *input_trch_fd=NULL; @@ -208,7 +209,7 @@ int main(int argc, char **argv) int n_frames; int n_ch_rlz = 1; - channel_desc_t *eNB2UE[4]; + channel_desc_t *eNB2UE[8]; uint8_t num_pdcch_symbols=1,num_pdcch_symbols_2=0; uint8_t pilot1,pilot2,pilot3; uint8_t rx_sample_offset = 0; @@ -227,6 +228,10 @@ int main(int argc, char **argv) int pmi_feedback=0; int hold_channel=0; + // temporarily for retransmissions: + unsigned char resend_cw1=0; //if 0 resend only cw0 + unsigned char resend_cw0_cw1=1; //if 0 resend both cw in a normal way + // void *data; // int ii; int bler; @@ -894,7 +899,7 @@ n(tikz_fname,"w"); PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = n_rnti; PHY_vars_UE->transmission_mode[eNB_id]=transmission_mode; - if (PHY_vars_UE->transmission_mode[eNB_id] !=4) + if (PHY_vars_UE->transmission_mode[eNB_id] !=4) // add TM3 exception PHY_vars_UE->PHY_measurements.rank[eNB_id]=0; else PHY_vars_UE->PHY_measurements.rank[eNB_id]=1; @@ -940,26 +945,29 @@ n(tikz_fname,"w"); DLSCH_alloc_pdu2_1E[1].tpmi = (transmission_mode>=5 ? 5 : 0) ; // precoding DLSCH_alloc_pdu2_1E[1].dl_power_off = (transmission_mode==5 ? 0 : 1); - eNB2UE[0] = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, - PHY_vars_UE->lte_frame_parms.nb_antennas_rx, - channel_model, - N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - forgetting_factor, - rx_sample_offset, - 0); - if(num_rounds>1) { - for(n=1; n<4; n++) - eNB2UE[n] = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, - PHY_vars_UE->lte_frame_parms.nb_antennas_rx, - channel_model, - N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - forgetting_factor, - rx_sample_offset, - 0); + eNB2UE[0] = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, + PHY_vars_UE->lte_frame_parms.nb_antennas_rx, + channel_model, + N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + forgetting_factor, + rx_sample_offset, + 0); + + if(num_rounds>1) { // 8 is because the round counters are independent across the CW + for(n=1; n<8; n++) + eNB2UE[n] = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, + PHY_vars_UE->lte_frame_parms.nb_antennas_rx, + channel_model, + N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + forgetting_factor, + rx_sample_offset, + 0); } + + if (eNB2UE[0]==NULL) { msg("Problem generating channel model. Exiting.\n"); @@ -1640,8 +1648,8 @@ n(tikz_fname,"w"); dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; @@ -2057,20 +2065,20 @@ n(tikz_fname,"w"); for (SNR=snr0; SNRframe_rx=0; for (i=0; i<4; i++) { - errs[0][i]=0; - errs[1][i]=0; - /*Let see, how it will work, if */ - round_trials[i] = 0; - // round_trials_1[i] = 0; + errs[0][i]=0; //CW_0 + errs[1][i]=0; //CW_1 + + round_trials[0][i] = 0; // CW_0 + round_trials[1][i] = 0; // CW_1 } dci_errors=0; - //avg_ber = 0; - round=0; + round = 0; avg_iter[0] = 0; avg_iter[1] = 0; iter_trials[0]=0; iter_trials[1]=0; + unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}; reset_meas(&PHY_vars_eNB->phy_proc_tx); // total eNB tx reset_meas(&PHY_vars_eNB->dlsch_scrambling_stats); reset_meas(&PHY_vars_UE->dlsch_unscrambling_stats); @@ -2119,7 +2127,8 @@ n(tikz_fname,"w"); for (trials = 0;trialsnb_antennas_tx; i++) { memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } @@ -2129,18 +2138,26 @@ n(tikz_fname,"w"); ret[0] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; ret[1] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; - /*This condition indicates, that the round_trials must go on, while CRC keeps failing at - least for one of the CW and round < num_rounds. This also means that round_trials is a unique - variable for both CW*/ + resend_cw0_cw1=1; + resend_cw1=0; - while (((transmission_mode == 3 || transmission_mode == 4) && ((round < num_rounds) && ((ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) - || (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) || - ((transmission_mode!=4 && transmission_mode != 3)&& ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) { + while (((transmission_mode == 3 || transmission_mode == 4) && + ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) && + (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations))) || + ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && + (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) { //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); - //printf("round_trials %d round %d\n", round_trials[round], round); + + if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) + round_trials[0][round]++; + + if (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) + round_trials[1][round]++; - round_trials[round]++; + + /*printf("Trial %d, round cw0 = %d , round cw1 = %d, ret[0] = %d, ret[1] = %d, round_trials cw0 [%d]= %d, round_trials cw1 [%d]= %d\n",trials, round, round, \ + ret[0], ret[1], round, round_trials[0][round], round, round_trials[1][round]);*/ //printf("round_trials %d round %d\n", round_trials[round], round); @@ -2171,11 +2188,14 @@ n(tikz_fname,"w"); // Simulate HARQ procedures!!! if (common_flag == 0) { + + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + if (transmission_mode == 3 || transmission_mode == 4) + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rvidx = round&3; if (round == 0) { // First round TB0_active = 1; - - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { switch (transmission_mode) { @@ -2377,7 +2397,6 @@ n(tikz_fname,"w"); } } else { - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { switch (transmission_mode) { @@ -2414,13 +2433,13 @@ n(tikz_fname,"w"); ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + } else { // deactivate TB0 ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); break; case 25: @@ -2429,7 +2448,7 @@ n(tikz_fname,"w"); ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + } else { // deactivate TB0 ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; @@ -2444,13 +2463,13 @@ n(tikz_fname,"w"); ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + } else { // deactivate TB0 ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); break; case 100: @@ -2484,7 +2503,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); break; case 25: @@ -2662,7 +2681,6 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - //change tpmi } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); break; @@ -2672,7 +2690,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + } else { // deactivate TB0 ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; @@ -2743,7 +2761,7 @@ n(tikz_fname,"w"); rate[cw] = (double)tbs[cw]/(double)coded_bits_per_codeword[cw]; - if ((SNR==snr0) && (trials==0) && (round==0) && (pmi_feedback==0)) + if ((SNR == snr0) && (trials == 0) && (round == 0) && (pmi_feedback == 0)) printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", k,cw,rate[cw],rate[cw]*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), coded_bits_per_codeword[cw], @@ -2786,23 +2804,7 @@ n(tikz_fname,"w"); &PHY_vars_eNB->dlsch_turbo_encoding_stats, &PHY_vars_eNB->dlsch_interleaving_stats)<0) exit(-1); - - - - /* - if (transmission_mode == 3) { - if (dlsch_encoding(input_buffer1[k], - &PHY_vars_eNB->lte_frame_parms, - num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][1], - 0,subframe, - &PHY_vars_eNB->dlsch_rate_matching_stats, - &PHY_vars_eNB->dlsch_turbo_encoding_stats, - &PHY_vars_eNB->dlsch_interleaving_stats - )<0) - exit(-1); - } - */ + stop_meas(&PHY_vars_eNB->dlsch_encoding_stats); PHY_vars_eNB->dlsch_eNB[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; @@ -2955,7 +2957,7 @@ n(tikz_fname,"w"); // Multipath channel if (awgn_flag == 0) { - multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, + multipath_channel(eNB2UE[round+round],s_re,s_im,r_re,r_im, 2*frame_parms->samples_per_tti,hold_channel); // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); if(abstx==1 && num_rounds>1) @@ -2965,14 +2967,13 @@ n(tikz_fname,"w"); random_channel(eNB2UE[3],0); } if (PHY_vars_UE->perfect_ce==1){ - freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[round+round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); } } - - // freq_channel(eNB2UE[0], NB_RB,12*NB_RB + 1); - if(abstx){ + + if(abstx){ // TODO: check the rounds here!! if (trials==0 && round==0) { // calculate freq domain representation to compute SINR freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1); @@ -3118,9 +3119,9 @@ n(tikz_fname,"w"); for (aarx=0; aarxnb_antennas_rx; aarx++) { for (i=0; iN_RB_DL*12; i++) { ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= - (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + (int16_t)(eNB2UE[round+round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= - (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + (int16_t)(eNB2UE[round+round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); } } } @@ -3219,24 +3220,22 @@ n(tikz_fname,"w"); dlsch_active = 0; if (round==0) { dci_errors++; - round=5; + round=5; // this is meant to stop the "while" loop if DCI is wrong; errs[0][0]++; - //round_trials[0]++; if (n_frames==1) printf("DCI error trial %d errs[0][0] %d\n",trials,errs[0][0]); } - //for (i=1;i<=round;i++) - //round_trials[i]--; - //round=5; } for (i=0;idlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->first_tx=1; - PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->first_tx=1; - } + if (round == 0) { + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx=1; + } + if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) { + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->first_tx=1; + } if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, subframe, @@ -3258,37 +3257,46 @@ n(tikz_fname,"w"); PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, 0, subframe); + if (transmission_mode == 3 || transmission_mode == 4) { + coded_bits_per_codeword[1]= get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl, + PHY_vars_UE->lte_ue_pdcch_vars[1]->num_pdcch_symbols, + 0, + subframe); + } /* rate = (double)dlsch_tbs25[get_I_TBS(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs)][PHY_vars_UE->dlsch_ue[0][0]->nb_rb-1]/(coded_bits_per_codeword); rate*=get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs); */ printf("num_pdcch_symbols %d, G %d, TBS %d\n",PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword [0],PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->TBS); - dlsch_active = 1; + dlsch_active = 1; // what does it indicates??? } else { dlsch_active = 0; if (round==0) { dci_errors++; errs[0][0]++; - //round_trials[0]++; round=5; if (n_frames==1) printf("DCI misdetection trial %d\n",trials); } - // for (i=1;i<=round;i++) - // round_trials[i]--; - // round=5; } } - } else { //dci_flag == 0 + } else { //dci_flag == 0 PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = n_rnti; PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; if (round == 0) { PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx=1; + } + if (round == 0) { PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->first_tx=1; } + switch (transmission_mode) { case 1: case 2: @@ -3447,7 +3455,7 @@ n(tikz_fname,"w"); cw_to_decode_interf=Kmimo; } - for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[cw_non_sic] = get_G(&PHY_vars_eNB->lte_frame_parms, @@ -3512,7 +3520,7 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_decoding_stats); ret[cw_non_sic] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], &PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_ue[0][cw_non_sic], PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid], @@ -3520,10 +3528,14 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid, 1,llr8_flag); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + //printf("retr cw 0 = %d\n", ret[0]); + //printf("current round = %d\n", PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->round); + - if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { //If CRC for the first CW did not fail - if (cw_non_sic==0) { + if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 + + if (cw_non_sic==0) { avg_iter[0] += ret[0]; iter_trials[0]++; } @@ -3650,8 +3662,11 @@ n(tikz_fname,"w"); if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && rx_type==rx_SIC_dual_stream) { - - // for (round = 0 ; round < 1 ; round++) { + // printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round); + + for (round_sic = 0 ; round_sic < (round +1); round_sic++) { + //printf("I enter round_sic loop \n"); + //printf("round_sic= %d\n", round_sic); dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; @@ -3714,9 +3729,9 @@ n(tikz_fname,"w"); case 2: dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], num_pdcch_symbols, dlsch0_eNB_harq->nb_rb, @@ -3729,12 +3744,12 @@ n(tikz_fname,"w"); case 4: dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], @@ -3743,13 +3758,13 @@ n(tikz_fname,"w"); break; case 6: dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], @@ -3757,6 +3772,7 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_ue[eNB_id][0]); break; } + } // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); @@ -3765,18 +3781,18 @@ n(tikz_fname,"w"); coded_bits_per_codeword[cw_sic]= get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0, - subframe); + get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe); PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_sic]; PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); - if (n_frames==2) { + if (n_frames==1) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword[cw_sic], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_sic]); @@ -3788,12 +3804,13 @@ n(tikz_fname,"w"); sprintf(vname,"dlschcw%d_e", cw_sic); write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_sic],1,4); uncoded_ber=0; - printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { - uncoded_ber_bit[i] = 1; - uncoded_ber++; - } else + printf("trials=%d\n", trials); + for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } + else uncoded_ber_bit[i] = 0; uncoded_ber/=coded_bits_per_codeword[cw_sic]; @@ -3806,7 +3823,7 @@ n(tikz_fname,"w"); uncoded_ber_bit = NULL; } - start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, 0, PHY_vars_UE->dlsch_ue[0][cw_sic], @@ -3814,55 +3831,56 @@ n(tikz_fname,"w"); PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], cw_sic, subframe<<1); - stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); ret[1] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw_sic], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], - subframe, - PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, - 1,llr8_flag); + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][cw_sic], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, + 1,llr8_flag); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); - + + // printf("retr cw 1 = %d\n", ret[1]); - if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { //if (ret <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) + if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { - avg_iter[1] += ret[1]; - iter_trials[1]++; + avg_iter[1] += ret[1]; + iter_trials[1]++; - if (n_frames==2) { - printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); - #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + if (n_frames==1) { + printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); + + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); - } - #endif + printf("Decoded_output (Segment %d):\n",s); + + for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + } + #endif } } - - else { errs[cw_sic][round]++; // exit(0); if (cw_sic==1) { - avg_iter[1] += ret[1]-1; - iter_trials[1]++; + avg_iter[1] += ret[1]-1; + iter_trials[1]++; } if (n_frames==2) { @@ -3911,7 +3929,7 @@ n(tikz_fname,"w"); } - if (n_frames==2) { + if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); #ifdef PRINT_BYTES @@ -3935,7 +3953,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->phy_proc_rx); - if (n_frames==2) { + if (n_frames==1) { //rxsig sprintf(fname,"rxsig0_r%d.m",round); @@ -4021,15 +4039,38 @@ n(tikz_fname,"w"); 0,// UE_id subframe); } + + - round++; - } //round + if ((transmission_mode != 3 && transmission_mode !=4 ) && ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + round++; + } + + + if ((transmission_mode == 3 || transmission_mode == 4 ) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) && (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ + resend_both[round]++; + round++; + resend_cw0_cw1=1; //resend both cws + resend_cw1=0; + + } + + if ((transmission_mode == 3 || transmission_mode == 4 ) && (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) && (ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ + resend_one[round]++; + round++; + resend_cw0_cw1=0; + resend_cw1=1; //resend only cw1, alamouti + + } + + } + //} //round if(transmission_mode != 3 && transmission_mode !=4 ){ if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) break; } - + //len = chbch_stats_read(stats_buffer,NULL,0,4096); //printf("%s\n\n",stats_buffer); @@ -4082,6 +4123,8 @@ n(tikz_fname,"w"); } //trials + printf("both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); + printf("one failed round 0 = %d, one failed round 1 = %d, one failed round 2 = %d, one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); // round_trials[0]: number of code word : goodput the protocol double table_tx[time_vector_tx.size]; @@ -4170,7 +4213,15 @@ n(tikz_fname,"w"); double std_phy_proc_rx_demod=0; double std_phy_proc_rx_dec=0; - effective_rate = ((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); + if (transmission_mode != 3 && transmission_mode !=4) { + effective_rate = ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3])); + } + else { + effective_rate = ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3]))+ + ((double)(round_trials[1][0])/((double)round_trials[1][0] + round_trials[1][1] + round_trials[1][2] + round_trials[1][3])); + } + + printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n", SNR, @@ -4182,39 +4233,39 @@ n(tikz_fname,"w"); "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n", errs[0][0], errs[1][0], - round_trials[0], + round_trials[0][0], errs[0][1], errs[1][1], - round_trials[0], + round_trials[0][0], errs[0][2], errs[1][2], - round_trials[0], + round_trials[0][0], errs[0][3], errs[1][3], - round_trials[0], - (double)errs[0][0]/(round_trials[0]), - (double)errs[1][0]/(round_trials[0]), - (double)errs[0][1]/(round_trials[0]), - (double)errs[1][1]/(round_trials[0]), - (double)errs[0][2]/(round_trials[0]), - (double)errs[1][2]/(round_trials[0]), - (double)errs[0][3]/(round_trials[0]), - (double)errs[1][3]/(round_trials[0]), + round_trials[0][0], + (double)errs[0][0]/(round_trials[0][0]), + (double)errs[1][0]/(round_trials[0][0]), + (double)errs[0][1]/(round_trials[0][0]), + (double)errs[1][1]/(round_trials[0][0]), + (double)errs[0][2]/(round_trials[0][0]), + (double)errs[1][2]/(round_trials[0][0]), + (double)errs[0][3]/(round_trials[0][0]), + (double)errs[1][3]/(round_trials[0][0]), dci_errors, - round_trials[0], - (double)dci_errors/(round_trials[0]), + round_trials[0][0], + (double)dci_errors/(round_trials[0][0]), rate[0]*effective_rate, 100*effective_rate, rate[0], rate[0]*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+ - 4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2]) - +4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0]), - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0])), - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0]))+ - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+ + 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) + +4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]), + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])), + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0][1])), + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0]))+ + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0][1])), rate[0], rate[1]); @@ -4330,13 +4381,13 @@ n(tikz_fname,"w"); PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, rate[0], errs[0][0], - round_trials[0], + round_trials[0][0], errs[0][1], - round_trials[1], + round_trials[0][1], errs[0][2], - round_trials[2], + round_trials[0][2], errs[0][3], - round_trials[3], + round_trials[0][3], dci_errors); } else { @@ -4350,34 +4401,34 @@ n(tikz_fname,"w"); rate[1], errs[0][0], errs[1][0], - round_trials[0], + round_trials[0][0], errs[0][1], errs[1][1], - round_trials[1], + round_trials[0][1], errs[0][2], errs[1][2], - round_trials[2], + round_trials[0][2], errs[0][3], errs[1][3], - round_trials[3], - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0])), - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0]))+ - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), + round_trials[0][3], + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])), + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])), + rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0]))+ + rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])), dci_errors); } if(abstx){ //ABSTRACTION if ((transmission_mode != 3)&& (transmission_mode != 4)) { - blerr[0][0] = (double)errs[0][0]/(round_trials[0]); + blerr[0][0] = (double)errs[0][0]/(round_trials[0][0]); if(num_rounds>1){ - blerr[0][1] = (double)errs[0][1]/(round_trials[1]); + blerr[0][1] = (double)errs[0][1]/(round_trials[0][1]); - blerr[0][2] = (double)errs[0][2]/(round_trials[2]); + blerr[0][2] = (double)errs[0][2]/(round_trials[0][2]); - blerr[0][3] = (double)errs[0][3]/(round_trials[3]); + blerr[0][3] = (double)errs[0][3]/(round_trials[0][3]); fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]); } @@ -4386,15 +4437,15 @@ n(tikz_fname,"w"); } } else { - blerr[0][0] = (double)errs[0][0]/(round_trials[0]); - blerr[1][0] = (double)errs[1][0]/(round_trials[0]); + blerr[0][0] = (double)errs[0][0]/(round_trials[0][0]); + blerr[1][0] = (double)errs[1][0]/(round_trials[0][0]); if(num_rounds>1){ - blerr[0][1] = (double)errs[0][1]/(round_trials[1]); - blerr[1][1] = (double)errs[1][1]/(round_trials[1]); - blerr[0][2] = (double)errs[0][2]/(round_trials[2]); - blerr[1][2] = (double)errs[1][2]/(round_trials[2]); - blerr[0][3] = (double)errs[0][3]/(round_trials[3]); - blerr[1][3] = (double)errs[1][3]/(round_trials[3]); + blerr[0][1] = (double)errs[0][1]/(round_trials[0][1]); + blerr[1][1] = (double)errs[1][1]/(round_trials[1][1]); + blerr[0][2] = (double)errs[0][2]/(round_trials[0][2]); + blerr[1][2] = (double)errs[1][2]/(round_trials[1][2]); + blerr[0][3] = (double)errs[0][3]/(round_trials[0][3]); + blerr[1][3] = (double)errs[1][3]/(round_trials[1][3]); fprintf(csv_fd,"%e;%e;%e;%e;%e;%e;%e;%e;\n",blerr[0][0],blerr[1][0],blerr[0][1],blerr[1][1],blerr[0][2],blerr[1][2], blerr[0][3], blerr[1][3]); } else { @@ -4412,13 +4463,13 @@ n(tikz_fname,"w"); PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, rate[0], errs[0][0], - round_trials[0], + round_trials[0][0], errs[0][1], - round_trials[1], + round_trials[0][1], errs[0][2], - round_trials[2], + round_trials[0][2], errs[0][3], - round_trials[3], + round_trials[0][3], dci_errors); //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); @@ -4438,15 +4489,15 @@ n(tikz_fname,"w"); round_trials[2], errs[0][3], round_trials[3], - (double)errs[0][0]/(round_trials[0]), - (double)errs[0][1]/(round_trials[0]), - (double)errs[0][2]/(round_trials[0]), - (double)errs[0][3]/(round_trials[0]), + (double)errs[0][0]/(round_trials[0][0]), + (double)errs[0][1]/(round_trials[0][0]), + (double)errs[0][2]/(round_trials[0][0]), + (double)errs[0][3]/(round_trials[0][0]), dci_errors, round_trials[0], - (double)dci_errors/(round_trials[0]), - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); + (double)dci_errors/(round_trials[0][0]), + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])); } else { fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", @@ -4456,13 +4507,13 @@ n(tikz_fname,"w"); PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, rate[0], errs[0][0], - round_trials[0], + round_trials[0][0], errs[0][1], - round_trials[1], + round_trials[0][1], errs[0][2], - round_trials[2], + round_trials[0][2], errs[0][3], - round_trials[3], + round_trials[0][3], dci_errors); //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); @@ -4476,22 +4527,22 @@ n(tikz_fname,"w"); rate[0], (double)avg_iter[0]/iter_trials[0], errs[0][0], - round_trials[0], + round_trials[0][0], errs[0][1], - round_trials[1], + round_trials[0][1], errs[0][2], - round_trials[2], + round_trials[0][2], errs[0][3], round_trials[3], - (double)errs[0][0]/(round_trials[0]), - (double)errs[0][1]/(round_trials[0]), - (double)errs[0][2]/(round_trials[0]), - (double)errs[0][3]/(round_trials[0]), + (double)errs[0][0]/(round_trials[0][0]), + (double)errs[0][1]/(round_trials[0][0]), + (double)errs[0][2]/(round_trials[0][0]), + (double)errs[0][3]/(round_trials[0][0]), dci_errors, - round_trials[0], - (double)dci_errors/(round_trials[0]), - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); + round_trials[0][0], + (double)dci_errors/(round_trials[0][0]), + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])); } //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", @@ -4567,11 +4618,12 @@ n(tikz_fname,"w"); } if (abstx == 1) { if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { - if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) + if (((double)errs[0][0]/(round_trials[0][0]))<1e-2 && ((double)errs[1][0]/(round_trials[1][0]))<1e-2) + if (((double)errs[0][0]/(round_trials[0][0]))<1e-2 && ((double)errs[1][0]/(round_trials[1][0]))<1e-2) break; } else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-2) + if (((double)errs[0][0]/(round_trials[0][0]))<1e-2) break; } @@ -4579,11 +4631,11 @@ n(tikz_fname,"w"); else { if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { - if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) + if (((double)errs[0][0]/(round_trials[0][0]))<1e-3 && ((double)errs[1][0]/(round_trials[1][0]))<1e-3) break; } else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-3) + if (((double)errs[0][0]/(round_trials[0][0]))<1e-3) break; } From 630e39aea3ff196589edfbd94051252133efa112 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 9 Nov 2016 00:55:57 +0100 Subject: [PATCH 112/571] Intermediate commit. Adding HARQ support for SIC receiver. Changes in dci_tools.c to map TB to CW in a proper way. Enable different options for TB1 retransmissions. Needs further improvements. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 876 +++++++----- openair1/PHY/LTE_TRANSPORT/defs.h | 6 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 1096 +++++++------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 298 ++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 1261 +++++++++-------- 5 files changed, 1935 insertions(+), 1602 deletions(-) mode change 100644 => 100755 openair1/PHY/LTE_TRANSPORT/defs.h diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index e685ca3da6..0da47dbdff 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -404,7 +404,7 @@ uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) } // Convert a DCI Format 1C RIV to a Format 1A RIV -// This extracts the start and length in PRBs from the 1C rballoc and +// This extracts the start and length in PRBs from the 1C rballoc and // recomputes the RIV as if it were the 1A rballoc uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) { @@ -448,7 +448,7 @@ uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) { } // printf("RBpstart %d\n",RBpstart); return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1))); - + } uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { @@ -456,11 +456,11 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { int offset; switch (N_RB_DL) { - + case 6: // N_RB_DL = tildeN_RB_DL = 6 // Ngap = 4 , P=1, Nrow = 2, Nnull = 2 - + switch (vrb) { case 0: // even: 0->0, 1->2, odd: 0->3, 1->5 case 1: @@ -471,13 +471,13 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { return ((3*odd_slot) + 2*(vrb&3) + 5)%6; break; case 4: // even: 4->1, odd: 4->4 - return ((3*odd_slot) + 1)%6; + return ((3*odd_slot) + 1)%6; case 5: // even: 5->4, odd: 5->1 return ((3*odd_slot) + 4)%6; break; } break; - + case 15: if (vrb<12) { if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11 @@ -491,11 +491,11 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { return (10+(7*odd_slot)) % 14; return 14; break; - + case 25: return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); break; - + case 50: // P=3 if (Ngap==0) { // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27 @@ -528,7 +528,7 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { offset=18; else offset=0; - + if (vrb<12) { if ((vrb&3)>=2) return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; @@ -543,19 +543,19 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { case 75: // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0 if (Ngap ==0) { - return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); + return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; case 100: // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0 if (Ngap ==0) { - return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); + return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; default: @@ -563,7 +563,7 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { return 0; } return 0; - + } @@ -878,7 +878,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, uint32_t rballoc = UINT32_MAX; uint32_t RIV_max = 0; uint8_t NPRB,tbswap,tpmi=0; - LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1; + LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; uint8_t frame_type=frame_parms->frame_type; uint8_t vrb_type=0; uint8_t mcs=0,mcs1=0,mcs2=0; @@ -886,6 +886,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, uint8_t rv=0,rv1=0,rv2=0; uint8_t rah=0; uint8_t TPC=0; + uint8_t TB0_active=0,TB1_active=0; LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; // printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu); @@ -926,6 +927,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, } dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + dlsch0_harq->codeword=0; if (vrb_type==LOCALIZED) { dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rballoc]; @@ -964,7 +966,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - + if (vrb_type==LOCALIZED) { dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rballoc]; } @@ -1216,6 +1218,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, } dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + dlsch0_harq->codeword=0; // msg("DCI: Setting subframe_tx for subframe %d\n",subframe); dlsch[0]->subframe_tx[subframe] = 1; @@ -1497,66 +1500,128 @@ int generate_eNB_dlsch_params_from_dci(int frame, // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0 // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated - if (tbswap == 0) { - dlsch0 = dlsch[0]; - dlsch1 = dlsch[1]; - } else { - dlsch0 = dlsch[1]; - dlsch1 = dlsch[0]; + TB0_active = 1; + TB1_active = 1; + + if ((rv1 == 1) && (mcs1 == 0)) { + TB0_active=0; + } + if ((rv2 == 1) && (mcs2 == 0)) { + TB1_active=0; } - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; + if (TB0_active && TB1_active && tbswap==0) { + dlsch0=dlsch[0]; + dlsch1=dlsch[1]; + dlsch0->active = 1; + dlsch1->active = 1; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + dlsch0_harq->mcs = mcs1; + dlsch1_harq->mcs = mcs2; + dlsch0_harq->rvidx = rv1; + dlsch1_harq->rvidx = rv2; + dlsch0_harq->status = ACTIVE; + dlsch1_harq->status = ACTIVE; + dlsch0_harq->codeword=0; + dlsch1_harq->codeword=1; + printf("\n ENB: BOTH ACTIVE\n"); + } + else if (TB0_active && TB1_active && tbswap==1) { + dlsch0=dlsch[0]; + dlsch1=dlsch[1]; + dlsch0->active = 1; + dlsch1->active = 1; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + dlsch0_harq->mcs = mcs1; + dlsch1_harq->mcs = mcs2; + dlsch0_harq->rvidx = rv1; + dlsch1_harq->rvidx = rv2; + dlsch0_harq->status = ACTIVE; + dlsch1_harq->status = ACTIVE; + dlsch0_harq->codeword=1; + dlsch1_harq->codeword=0; + } + else if (TB0_active && (TB1_active==0)) { + dlsch0=dlsch[0]; + dlsch0->active = 1; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch0_harq->mcs = mcs1; + dlsch0_harq->rvidx = rv1; + dlsch0_harq->status = ACTIVE; + dlsch0_harq->codeword = 0; + dlsch1=NULL; + dlsch1_harq = NULL; + } + else if ((TB0_active==0) && TB1_active) { + dlsch1=dlsch[1]; + dlsch1->active = 1; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + dlsch1_harq->mcs = mcs2; + dlsch1_harq->rvidx = rv2; + dlsch1_harq->status = ACTIVE; + dlsch1_harq->codeword = 0; + dlsch0=NULL; + dlsch0_harq = NULL; + printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); + } - dlsch0->subframe_tx[subframe] = 1; + if (dlsch0 != NULL){ + dlsch0->subframe_tx[subframe] = 1; - dlsch0->current_harq_pid = harq_pid; - dlsch1->current_harq_pid = harq_pid; - dlsch0->harq_ids[subframe] = harq_pid; - dlsch1->harq_ids[subframe] = harq_pid; - // printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe); + dlsch0->current_harq_pid = harq_pid; + dlsch0->harq_ids[subframe] = harq_pid; + } + + if (dlsch1_harq != NULL){ + dlsch1->current_harq_pid = harq_pid; + dlsch1->harq_ids[subframe] = harq_pid; + } - conv_rballoc(rah, - rballoc, - frame_parms->N_RB_DL, - dlsch0_harq->rb_alloc); + if (dlsch0 != NULL ){ + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch0_harq->rb_alloc); - dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; - dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL); - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL); - if (dlsch0_harq->nb_rb == 0) - return(-1); + if (dlsch1 != NULL){ + dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + } + } else if ((dlsch0 == NULL ) && (dlsch1 != NULL )){ + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch1_harq->rb_alloc); + + dlsch1_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL); + } + + + /*if (dlsch0_harq->nb_rb == 0) + return(-1);*/ - dlsch0_harq->mcs = mcs1; - dlsch1_harq->mcs = mcs2; - dlsch0_harq->rvidx = rv1; - dlsch1_harq->rvidx = rv2; // assume both TBs are active - dlsch0_harq->Nl = 1; - dlsch1_harq->Nl = 1; - dlsch0->active = 1; - dlsch1->active = 1; + if (dlsch0_harq != NULL) + dlsch0_harq->Nl = 1; + if (dlsch1_harq != NULL) + dlsch1_harq->Nl = 1; // check if either TB is disabled (see 36-213 V11.3 Section ) - if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { - dlsch0->active = 0; - } - - if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { - dlsch1->active = 0; - } if (frame_parms->nb_antennas_tx == 2) { - if (dlsch0->active == 1 && dlsch1->active == 1) { // both TBs are active + if ((dlsch0 != NULL) && (dlsch1 != NULL)) { //two CW active - dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; switch (tpmi) { case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; @@ -1575,13 +1640,12 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; dlsch0_harq->pmi_alloc = DL_pmi_single; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = DL_pmi_single; + dlsch1_harq->pmi_alloc = DL_pmi_single; break; default: break; } - } - else if (dlsch1->active == 0) { // only one is active + } else if ((dlsch0 != NULL) && (dlsch1 == NULL)) { // only CW 0 active dlsch0_harq->dl_power_off = 1; dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; switch (tpmi) { @@ -1613,53 +1677,54 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq->pmi_alloc = DL_pmi_single; break; } - } - else if (dlsch0->active == 0) { // only one is active - dlsch1_harq->dl_power_off = 1; - dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - switch (tpmi) { - case 0 : - dlsch1_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,0); - break; - case 2: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1,0); - break; - case 3: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2,0); - break; - case 4: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3,0); - break; - case 5: - dlsch1_harq->mimo_mode = PUSCH_PRECODING0; - dlsch1_harq->pmi_alloc = DL_pmi_single; - break; - case 6: - dlsch1_harq->mimo_mode = PUSCH_PRECODING1; - dlsch1_harq->pmi_alloc = DL_pmi_single; - break; + } else if ((dlsch0 == NULL) && (dlsch1 != NULL)) { + dlsch1_harq->dl_power_off = 1; + dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; + switch (tpmi) { + case 0 : + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0,0); + break; + case 2: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1,0); + break; + case 3: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2,0); + break; + case 4: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3,0); + break; + case 5: + dlsch1_harq->mimo_mode = PUSCH_PRECODING0; + dlsch1_harq->pmi_alloc = DL_pmi_single; + break; + case 6: + dlsch1_harq->mimo_mode = PUSCH_PRECODING1; + dlsch1_harq->pmi_alloc = DL_pmi_single; + break; + } } - } + } else if (frame_parms->nb_antennas_tx == 4) { // fill in later } // reset HARQ process if this is the first transmission - if (dlsch0_harq->round == 0) + /* if (dlsch0_harq->round == 0) dlsch0_harq->status = ACTIVE; if (dlsch1_harq->round == 0) - dlsch1_harq->status = ACTIVE; - - dlsch0->rnti = rnti; - dlsch1->rnti = rnti; + dlsch1_harq->status = ACTIVE;*/ + if (dlsch0_harq != NULL) + dlsch0->rnti = rnti; + if (dlsch1 != NULL) + dlsch1->rnti = rnti; break; @@ -1869,7 +1934,8 @@ int generate_eNB_dlsch_params_from_dci(int frame, // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0 // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated - if (tbswap == 0) { + // This must be set as in TM4, does not work properly now. + if (tbswap == 0) { dlsch0 = dlsch[0]; dlsch1 = dlsch[1]; } else { @@ -1933,7 +1999,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; if ((dlsch0->active==1) && (dlsch1->active==1)) { - + dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->dl_power_off = 1; @@ -2154,11 +2220,15 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; + dlsch1_harq->codeword=1; + conv_rballoc(rah, rballoc, frame_parms->N_RB_DL, dlsch0_harq->rb_alloc); - + dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0]; dlsch0_harq->nb_rb = conv_nprb(rah, @@ -2315,6 +2385,10 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; + dlsch1_harq->codeword=1; + conv_rballoc(rah, rballoc, frame_parms->N_RB_DL, @@ -2487,6 +2561,10 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; + dlsch1_harq->codeword=1; + conv_rballoc(rah, rballoc, frame_parms->N_RB_DL, @@ -2568,6 +2646,8 @@ int generate_eNB_dlsch_params_from_dci(int frame, //dlsch1->harq_ids[subframe] = harq_pid; // printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe); dlsch0_harq = dlsch0->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL, @@ -2677,7 +2757,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, break; } - + if (dlsch0_harq) { dlsch0_harq->frame = frame; dlsch0_harq->subframe = subframe; @@ -2719,7 +2799,7 @@ int generate_eNB_dlsch_params_from_dci(int frame, #endif - // compute DL power control parameters + // compute DL power control parameters computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off); @@ -3115,37 +3195,37 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]); LOG_D(PHY,"MCS %d\n",((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->mcs); break; - + case 25: LOG_D(PHY,"DCI format1C (5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[conv_1C_RIV(((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,25)]); LOG_D(PHY,"MCS %d\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->mcs); break; - + case 50: LOG_D(PHY,"DCI format1C (10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"Ngap %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->Ngap); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,50)]); LOG_D(PHY,"MCS %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->mcs); break; - + case 100: LOG_D(PHY,"DCI format1C (20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"Ngap %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->Ngap); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,100)]); LOG_D(PHY,"MCS %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->mcs); break; - - + + default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } - + break; - + case format2: if ((frame_parms->frame_type == TDD) && @@ -3859,13 +3939,14 @@ int generate_ue_dlsch_params_from_dci(int frame, uint8_t vrb_type=0; uint8_t mcs=0,mcs1=0,mcs2=0; uint8_t rv=0,rv1=0,rv2=0; + uint8_t TB0_active=0,TB1_active=0; uint8_t ndi=0,ndi1=0,ndi2=0; uint8_t rah=0; uint8_t TPC=0; uint8_t NPRB=0,tbswap=0,tpmi=0; uint8_t Ngap; LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; - LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq; + LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; #ifdef DEBUG_DCI LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, dci_format %d\n",rnti,dci_format); @@ -3915,6 +3996,8 @@ int generate_ue_dlsch_params_from_dci(int frame, } dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + + NPRB = RIV2nb_rb_LUT6[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; @@ -4170,6 +4253,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; dlsch0_harq->dl_power_off = 1; //no power offset + // Needs to be checked + dlsch0_harq->codeword=0; + LOG_D(PHY,"UE (%x/%d): Subframe %d Format1A DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d, round %d\n", dlsch[0]->rnti, harq_pid, @@ -4210,7 +4296,7 @@ int generate_ue_dlsch_params_from_dci(int frame, harq_pid = 0; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - + switch (frame_parms->N_RB_DL) { case 6: mcs = ((DCI1C_1_5MHz_t *)dci_pdu)->mcs; @@ -4230,7 +4316,7 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; RIV_max = RIV_max25; - // printf("Format1C : %x : mcs %d, rballoc %d=>%d=>%x\n",((uint32_t*)dci_pdu)[0], + // printf("Format1C : %x : mcs %d, rballoc %d=>%d=>%x\n",((uint32_t*)dci_pdu)[0], // mcs,((DCI1C_5MHz_t *)dci_pdu)->rballoc,rballoc,dlsch0_harq->rb_alloc_even[0]); break; @@ -4240,16 +4326,16 @@ int generate_ue_dlsch_params_from_dci(int frame, Ngap = ((DCI1C_10MHz_t *)dci_pdu)->Ngap; dlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc]; if (Ngap == 0) { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; } else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; } RIV_max = RIV_max50; @@ -4261,28 +4347,28 @@ int generate_ue_dlsch_params_from_dci(int frame, Ngap = ((DCI1C_20MHz_t *)dci_pdu)->Ngap; dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc]; if (Ngap==0) { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; } else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; } RIV_max = RIV_max100; /* - printf("Format1C : %x : mcs %d, rballoc %d=>%d=>(%08x.%08x.%08x.%08x), Ngap %d\n",((uint32_t*)dci_pdu)[0], + printf("Format1C : %x : mcs %d, rballoc %d=>%d=>(%08x.%08x.%08x.%08x), Ngap %d\n",((uint32_t*)dci_pdu)[0], mcs,((DCI1C_20MHz_t *)dci_pdu)->rballoc,rballoc, dlsch0_harq->rb_alloc_even[0], dlsch0_harq->rb_alloc_even[1], @@ -4291,8 +4377,8 @@ int generate_ue_dlsch_params_from_dci(int frame, Ngap ); */ - break; - + break; + default: LOG_E(PHY,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL); return(-1); @@ -4309,9 +4395,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch[0]->current_harq_pid = harq_pid; if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321 - if (((frame&1) == 0) && (subframe == 5)) + if (((frame&1) == 0) && (subframe == 5)) dlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 - else + else dlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs } else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3 @@ -4323,6 +4409,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; dlsch0_harq->dl_power_off = 1; //no power offset + // Needs to be checked + dlsch0_harq->codeword=0; + LOG_D(PHY,"UE (%x/%d): Subframe %d Format1C DCI: harq_status %d, round %d\n", dlsch[0]->rnti, harq_pid, @@ -4472,6 +4561,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->dl_power_off = 1; //no power offset + // Needs to be checked + dlsch0_harq->codeword=0; + LOG_D(PHY,"UE (%x/%d): Subframe %d Format1 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, dlsch0_harq->first_tx,dlsch0_harq->status); @@ -4777,210 +4869,269 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); } - /*if (frame_type == TDD) - tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - else - tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;*/ + // check if either TB is disabled (see 36-213 V8.6 p. 26) + TB0_active = 1; + TB1_active = 1; - - if (tbswap == 0) { - dlsch0 = dlsch[0]; - dlsch1 = dlsch[1]; - } else { - dlsch0 = dlsch[1]; - dlsch1 = dlsch[0]; + if ((rv1 == 1) && (mcs1 == 0)) { + TB0_active=0; + } + if ((rv2 == 1) && (mcs2 == 0)) { + TB1_active=0; } - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - dlsch0->current_harq_pid = harq_pid; - dlsch1->current_harq_pid = harq_pid; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch1->harq_ack[subframe].harq_id = harq_pid; + //printf("RV TB0 = %d\n", rv1); - conv_rballoc(rah, - rballoc, - frame_parms->N_RB_DL, - dlsch0_harq->rb_alloc_even); - dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; + if (TB0_active && TB1_active && tbswap==0) { //dlsch0, dlsch0_harq are at the TB level + dlsch0=dlsch[0]; + dlsch1=dlsch[1]; + dlsch0->active = 1; + dlsch1->active = 1; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + dlsch0_harq->mcs = mcs1; + dlsch1_harq->mcs = mcs2; + dlsch0_harq->rvidx = rv1; + dlsch1_harq->rvidx = rv2; + dlsch0_harq->status = ACTIVE; + dlsch1_harq->status = ACTIVE; + dlsch0_harq->codeword=0; + dlsch1_harq->codeword=1; + //printf("\n UE: BOTH ACTIVE\n"); + } + else if (TB0_active && TB1_active && tbswap==1) { + dlsch0=dlsch[0]; + dlsch1=dlsch[1]; + dlsch0->active = 1; + dlsch1->active = 1; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + dlsch0_harq->mcs = mcs1; + dlsch1_harq->mcs = mcs2; + dlsch0_harq->rvidx = rv1; + dlsch1_harq->rvidx = rv2; + dlsch0_harq->status = ACTIVE; + dlsch1_harq->status = ACTIVE; + dlsch0_harq->codeword=1; + dlsch1_harq->codeword=0; + } + else if (TB0_active && (TB1_active==0)) { + dlsch0=dlsch[0]; + dlsch0->active = 1; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch0_harq->mcs = mcs1; + dlsch0_harq->rvidx = rv1; + dlsch0_harq->status = ACTIVE; + dlsch0_harq->codeword = 0; + dlsch1=NULL; + dlsch1_harq = NULL; + } + else if ((TB0_active==0) && TB1_active) { + dlsch1=dlsch[1]; + dlsch1->active = 1; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + dlsch1_harq->mcs = mcs2; + dlsch1_harq->rvidx = rv2; + dlsch1_harq->status = ACTIVE; + dlsch1_harq->codeword = 0; + dlsch0=NULL; + dlsch0_harq = NULL; + //printf("\n UE: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); + } - dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; - dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0]; - dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1]; - dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; - dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; - dlsch0_harq->nb_rb = conv_nprb(rah, + if (dlsch0 != NULL){ + dlsch0->current_harq_pid = harq_pid; + dlsch0->harq_ack[subframe].harq_id = harq_pid; + } + + if (dlsch1 != NULL){ + dlsch1->current_harq_pid = harq_pid; + dlsch1->harq_ack[subframe].harq_id = harq_pid; + } + + if (dlsch0_harq != NULL){ + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch0_harq->rb_alloc_even); + + dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; + dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; + dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; + dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; + + if (dlsch1_harq != NULL){ + dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; + dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0]; + dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1]; + dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; + dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; + + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + } + + dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL); - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; - dlsch0_harq->mcs = mcs1; - dlsch1_harq->mcs = mcs2; + } else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; - dlsch[1]->g_pucch += delta_PUCCH_lut[TPC&3]; - /* - if (dlsch0_harq->mcs>20) { - msg("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs); - return(-1); + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch1_harq->rb_alloc_even); + + dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3]; + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; } - */ - dlsch0_harq->rvidx = rv1; - dlsch1_harq->rvidx = rv2; - - // assume both TBs are active - dlsch0_harq->Nl = 1; - dlsch1_harq->Nl = 1; - dlsch0->active = 1; - dlsch1->active = 1; - - - // check if either TB is disabled (see 36-213 V8.6 p. 26) - - if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { - - dlsch0_harq->status = DISABLED; - dlsch0->active = 0; + if (dlsch0_harq != NULL) { + dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch0->g_pucch += delta_PUCCH_lut[TPC&3]; } - if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { - dlsch1_harq->status = DISABLED; - dlsch1->active = 0; + if (dlsch1_harq != NULL) { + dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch1->g_pucch += delta_PUCCH_lut[TPC&3]; } - dlsch0_harq->Nl = 1; - dlsch1_harq->Nl = 1; + // assume one layer per codeword (2 antenna port case) + if (dlsch0_harq != NULL) + dlsch0_harq->Nl = 1; - // dlsch0->layer_index = tbswap; - // dlsch1->layer_index = 1-tbswap; + if (dlsch1_harq != NULL) + dlsch1_harq->Nl = 1; - if (dlsch0->active==1 && dlsch1->active==1) { //two TB + + if ((dlsch0 != NULL) && (dlsch1 != NULL)){ //two CW active dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; - switch (tpmi) { - case 0: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - break; - case 1: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1,1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); - break; - case 2: // PUSCH precoding - dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; - break; - default: - break; - } - } else if (dlsch1_harq->status == DISABLED) { - dlsch0_harq->dl_power_off = 1; - switch (tpmi) { - case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); - break; - case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; - case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; - case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; - case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; - case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - LOG_E(PHY,"Unsupported TPMI\n"); - return(-1); - break; - } - } else if (dlsch0_harq->status == DISABLED) { dlsch1_harq->dl_power_off = 1; switch (tpmi) { - case 0 : - dlsch1_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); - break; - case 2: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; - case 3: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; - case 4: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; - case 5: - dlsch1_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; - case 6: - dlsch1_harq->mimo_mode = PUSCH_PRECODING1; - LOG_E(PHY,"Unsupported TPMI\n"); - return(-1); - break; + case 0: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + break; + case 1: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + break; + case 2: // PUSCH precoding + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + if (tbswap==0){ + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; + } else { + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; + } + break; + default: + break; } + } else if ((dlsch0 != NULL) && (dlsch1 == NULL)) { // only CW 0 active + dlsch0_harq->dl_power_off = 1; + switch (tpmi) { + case 0 : + dlsch0_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); + break; + case 2: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; + case 3: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + break; + case 4: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; + case 5: + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + // we need to extract the first column of precoding matrix (which was computed assuming rank==2) + dlsch0_harq->pmi_alloc = 0;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; + case 6: + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + // we need to extract the second column of precoding matrix (which was computed assuming rank==2) + dlsch0_harq->pmi_alloc = 0;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); + break; + } + } else { + dlsch1_harq->dl_power_off = 1; + switch (tpmi) { + case 0 : + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); + break; + case 2: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; + case 3: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + break; + case 4: + dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; + case 5: + dlsch1_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; + case 6: + dlsch1_harq->mimo_mode = PUSCH_PRECODING1; + dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; + return(-1); + break; + } } - if (frame_parms->mode1_flag == 1) + if ((frame_parms->mode1_flag == 1) && (dlsch0_harq != NULL)) dlsch0_harq->mimo_mode = SISO; - if (dlsch0->active == 1) { + if (dlsch0 != NULL) { if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { dlsch0_harq->round = 0; dlsch0_harq->status = ACTIVE; dlsch0_harq->DCINdi = ndi1; - if (dlsch0_harq->first_tx==1) { + if ( dlsch0_harq->first_tx==1) { LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); dlsch0_harq->first_tx = 0; } - } - else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, + } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received - + dlsch0->harq_ack[subframe].ack = 1; dlsch0->harq_ack[subframe].harq_id = harq_pid; dlsch0->harq_ack[subframe].send_harq_status = 1; @@ -4988,7 +5139,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } } - if (dlsch1->active == 1) { + if ((dlsch1 != NULL) && (dlsch1->active == 1 )) { if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { dlsch1_harq->round = 0; dlsch1_harq->status = ACTIVE; @@ -4998,10 +5149,10 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->first_tx = 0; } } - else if (dlsch1_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, + else if ((dlsch1 != NULL) && (dlsch1_harq->status == SCH_IDLE)) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received - + dlsch1->harq_ack[subframe].ack = 1; dlsch1->harq_ack[subframe].harq_id = harq_pid; dlsch1->harq_ack[subframe].send_harq_status = 1; @@ -5009,47 +5160,42 @@ int generate_ue_dlsch_params_from_dci(int frame, } } - // dlsch0_harq->mcs = mcs1; + if (dlsch0 != NULL){ + if (dlsch0_harq->nb_rb>1) { + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + if (mcs1 <= 28) + dlsch0_harq->Qm = get_Qm(mcs1); + else if (mcs1<=31) + dlsch0_harq->Qm = (mcs1-28)<<1; + else + LOG_E(PHY,"invalid mcs1 %d\n",mcs1); + } else + dlsch0_harq->TBS =0; - if (dlsch0_harq->nb_rb>1) { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - if (mcs1 <= 28) - dlsch0_harq->Qm = get_Qm(mcs1); - else if (mcs1<=31) - dlsch0_harq->Qm = (mcs1-28)<<1; - else - LOG_E(PHY,"invalid mcs1 %d\n",mcs1); - } else - dlsch0_harq->TBS =0; - - - /* - if (dlsch0_harq->mcs > 18) - printf("mcs %d, TBS %d\n",dlsch0_harq->mcs,dlsch0_harq->TBS); - */ - - if (dlsch1_harq->DCINdi != ndi2) { - dlsch1_harq->round=0; - dlsch1_harq->status = ACTIVE; + dlsch0->rnti = rnti; } - dlsch1_harq->DCINdi = ndi2; - // dlsch1_harq->mcs = mcs2; + if (dlsch1 != NULL) { + if (dlsch1_harq->DCINdi != ndi2) { + dlsch1_harq->round=0; + dlsch1_harq->status = ACTIVE; + } - if (dlsch1_harq->nb_rb>1) { - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - if (mcs2 <= 28) - dlsch1_harq->Qm = get_Qm(mcs2); - else if (mcs1<=31) - dlsch1_harq->Qm = (mcs2-28)<<1; - else - LOG_E(PHY,"invalid mcs2 %d\n",mcs2); - } else - dlsch1_harq->TBS = 0; + dlsch1_harq->DCINdi = ndi2; + if (dlsch1_harq->nb_rb>1) { + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; + if (mcs2 <= 28) + dlsch1_harq->Qm = get_Qm(mcs2); + else if (mcs1<=31) + dlsch1_harq->Qm = (mcs2-28)<<1; + else + LOG_E(PHY,"invalid mcs2 %d\n",mcs2); + } else + dlsch1_harq->TBS = 0; - dlsch0->rnti = rnti; - dlsch1->rnti = rnti; + dlsch1->rnti = rnti; + } break; @@ -5292,6 +5438,7 @@ int generate_ue_dlsch_params_from_dci(int frame, // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0 // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated + //Needs to be done in the same manner as TM$. if (tbswap == 0) { dlsch0 = dlsch[0]; dlsch1 = dlsch[1]; @@ -5302,6 +5449,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; dlsch1_harq = dlsch[1]->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; + dlsch1_harq->codeword=1; dlsch0->current_harq_pid = harq_pid; dlsch1->current_harq_pid = harq_pid; dlsch0->harq_ack[subframe].harq_id = harq_pid; @@ -5425,7 +5575,7 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; - + if ((dlsch0->active==1) && (dlsch1->active==1)) { dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; @@ -5518,14 +5668,14 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->Qm = (mcs1-28)<<1; else LOG_E(PHY,"invalid mcs1 %d\n",mcs1); - + if (mcs2 <= 28) dlsch1_harq->Qm = get_Qm(mcs2); else if (mcs2<=31) dlsch1_harq->Qm = (mcs2-28)<<1; else LOG_E(PHY,"invalid mcs2 %d\n",mcs2); - + // printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active); //printf("UE (%x/%d): Subframe %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, // dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status); @@ -5560,10 +5710,12 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0 = dlsch[0]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL, dlsch0_harq->rb_alloc_even); - + dlsch0_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_even[0]; dlsch0_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_even[1]; dlsch0_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_even[2]; @@ -5719,7 +5871,7 @@ int generate_ue_dlsch_params_from_dci(int frame, #endif dlsch[0]->active=1; - // compute DL power control parameters + // compute DL power control parameters computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off); @@ -5883,8 +6035,8 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) uint8_t rank = meas->rank[eNB_id]; int pmi_re,pmi_im; int nb_subbands=0; - - + + switch (nb_rb) { case 6: nb_subbands = 6; @@ -5900,7 +6052,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) nb_subbands = 13; break; } - + for (i=0; inb_antennas_rx; aarx++) { pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; @@ -5940,20 +6092,20 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) // this is orthogonal //if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im))) pmiq = PMI_2A_R1_11; - else + else pmiq = PMI_2A_R1_1j; - + // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); // printf("subband %d, pmi%d \n",i,pmiq); //According to Section 7.2.4 of 36.213 - - pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit + + pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit } else { LOG_E(PHY,"PMI feedback for rank>1 not supported!\n"); pmivect = 0; - } - + } + } // printf( "pmivect %d \n", pmivect); @@ -7322,7 +7474,7 @@ int generate_eNB_ulsch_params_from_dci(void *dci_pdu, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe), pdcch_alloc2ul_subframe(frame_parms,subframe)); - + // printf("eNB: sched_subframe %d, subframe %d, frame_tx %d\n",sched_subframe,subframe,phy_vars_eNB->proc[sched_subframe].frame_tx); switch (frame_parms->N_RB_DL) { diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h old mode 100644 new mode 100755 index a7a3143f1d..3f20cacf63 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -94,7 +94,7 @@ #define PMI_2A_1j 2 #define PMI_2A_1mj 3 //2 layers -#define PMI_2A_R1_10 0 +#define PMI_2A_R1_10 0 #define PMI_2A_R1_11 1 #define PMI_2A_R1_1j 2 @@ -172,6 +172,8 @@ typedef struct { uint8_t Nlayers; /// First layer for this PSCH transmission uint8_t first_layer; + /// codeword this transport block is mapped to + uint8_t codeword; } LTE_DL_eNB_HARQ_t; typedef struct { @@ -575,6 +577,8 @@ typedef struct { uint32_t trials[8]; /// error statistics per round uint32_t errors[8]; + /// codeword this transport block is mapped to + uint8_t codeword; } LTE_DL_UE_HARQ_t; typedef struct { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index b3bbbda114..59e988861b 100755 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -57,7 +57,7 @@ //#define DEBUG_PHY 1 //#define DEBUG_DLSCH_DEMOD 1 -int avg[4]; +int avg[4]; int avg_0[2]; int avg_1[2]; @@ -67,9 +67,9 @@ uint8_t interf_unaw_shift0=0; uint8_t interf_unaw_shift1=0; uint8_t interf_unaw_shift=0; //inferference-free case -unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, +unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; -unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1, +unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1, 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous /* @@ -111,18 +111,20 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LTE_UE_DLSCH_t **dlsch_ue; - unsigned char aatx,aarx; + unsigned char aatx,aarx; unsigned short nb_rb, round; - int avgs, rb; + int avgs, rb; LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0; uint32_t *rballoc; int32_t **rxdataF_comp_ptr; int32_t **dl_ch_mag_ptr; + int32_t codeword_TB0; + int32_t codeword_TB1; + + - - switch (type) { case SI_PDSCH: lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]; @@ -139,8 +141,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, case PDSCH: lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars[eNB_id]; dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id]; - dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid]; - dlsch1_harq = dlsch_ue[1]->harq_processes[harq_pid]; + codeword_TB0 = dlsch_ue[0]->harq_processes[harq_pid]->codeword; + codeword_TB1 = dlsch_ue[1]->harq_processes[harq_pid]->codeword; + dlsch0_harq = dlsch_ue[codeword_TB0]->harq_processes[harq_pid]; + dlsch1_harq = dlsch_ue[codeword_TB1]->harq_processes[harq_pid]; break; default: @@ -176,7 +180,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_W(PHY,"dlsch_demodulation.c: Null lte_frame_parms\n"); return(-1); } - + if (((frame_parms->Ncp == NORMAL) && (symbol>=7)) || ((frame_parms->Ncp == EXTENDED) && (symbol>=6))) rballoc = dlsch0_harq->rb_alloc_odd; @@ -187,9 +191,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_E(PHY,"This transmission mode is not yet supported!\n"); return(-1); } - - - + + + if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING))) { DevAssert(dlsch1_harq); if (eNB_id!=eNB_id_i) { @@ -234,7 +238,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, phy_vars_ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); - else + else nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, @@ -266,7 +270,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id_i], lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, rballoc, @@ -275,11 +279,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, phy_vars_ue->high_speed_flag, frame_parms); - else + else nb_rb = dlsch_extract_rbs_single(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, lte_ue_pdsch_vars[eNB_id_i]->pmi_ext, rballoc, @@ -306,13 +310,13 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, aarx = frame_parms->nb_antennas_rx; if (dlsch0_harq->mimo_modedl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, nb_rb); - + if (first_symbol_flag==1) { dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, @@ -333,8 +337,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1; //+ interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; // printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh); } - - + + dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, @@ -348,13 +352,13 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, nb_rb, lte_ue_pdsch_vars[eNB_id]->log2_maxh, phy_measurements); // log2_maxh+I0_shift - + /*if (symbol == 5) { write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } */ - if ((rx_type==rx_IC_single_stream) && + if ((rx_type==rx_IC_single_stream) && (eNB_id_in_connected_eNB)) { - + dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, @@ -373,9 +377,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (symbol == 5) { write_output("rxF_comp_d.m","rxF_c_d",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - write_output("rxF_comp_i.m","rxF_c_i",<e_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + write_output("rxF_comp_i.m","rxF_c_i",<e_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } -#endif +#endif // compute correlation between signal and interference channels dlsch_dual_stream_correlation(frame_parms, symbol, @@ -385,27 +389,27 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh); } - + } - else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || - ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || + ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 // LOG_I(PHY,"Running PDSCH RX for TM3\n"); - + if (frame_parms->nb_antennas_tx_eNB == 2) { - - + + // scaling interfering channel (following for TM56) dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, nb_rb); - - + + if (first_symbol_flag==1) { // effective channel of desired user is always stronger than interfering eff. channel - dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg_0, @@ -413,12 +417,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, symbol, nb_rb, dlsch0_harq->mimo_mode); - - + + // write_output("dlsch0_r0_aver_chan_1.m","dl_aver_ch1_r0_0",&avg_1[0],1,1,2); - - + + if (rx_type>rx_standard) { // Shifts are needed to avoid tails in SNR/BLER curves. // LUT will be introduced with mcs-dependent shift @@ -426,10 +430,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - + //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - + } else { // Shifts are needed to avoid tails in SNR/BLER curves. @@ -443,40 +447,40 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } } - dlsch_channel_compensation_TM34(frame_parms, + dlsch_channel_compensation_TM34(frame_parms, lte_ue_pdsch_vars[eNB_id], - phy_measurements, - eNB_id, - symbol, - dlsch0_harq->Qm, + phy_measurements, + eNB_id, + symbol, + dlsch0_harq->Qm, dlsch1_harq->Qm, harq_pid, dlsch0_harq->round, dlsch0_harq->mimo_mode, - nb_rb, + nb_rb, lte_ue_pdsch_vars[eNB_id]->log2_maxh0, - lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + /* if (symbol == 5) { - + write_output("rxF_comp_d00.m","rxF_c_d00",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rxF_comp_d01.m","rxF_c_d01",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 write_output("rxF_comp_d10.m","rxF_c_d10",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 write_output("rxF_comp_d11.m","rxF_c_d11",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - + } */ // compute correlation between signal and interference channels (rho12 and rho21) - + dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22 symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - + //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); //to be optimized (just take complex conjugate) @@ -490,15 +494,15 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); - + /* if (symbol == 5) { - + write_output("rho0_0.m","rho0_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rho2_0.m","rho2_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 write_output("rho0_1.m.m","rho0_1",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 write_output("rho2_1.m","rho2_1",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - + } */ } @@ -512,7 +516,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if ((rx_type==rx_IC_single_stream) && (eNB_id_i==phy_vars_ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) { // TM5 two-user // Scale the channel estimates for interfering stream - + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, @@ -542,7 +546,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); //printf("log1_maxh =%d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); } - + dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, @@ -582,8 +586,8 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // printf("pmi %d, pmi_i %d\n",lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb],lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[rb]); } - - + + dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, @@ -607,23 +611,23 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, write_output("rxF_comp_i.m","rxF_c_i",<e_ue_pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } #endif - dlsch_dual_stream_correlation(frame_parms, - symbol, - nb_rb, - lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + dlsch_dual_stream_correlation(frame_parms, + symbol, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], lte_ue_pdsch_vars[eNB_id]->log2_maxh); - } + } else if (dlsch0_harq->dl_power_off==1) { - + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch_ue, symbol, nb_rb); - + if (first_symbol_flag==1) { dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, @@ -642,11 +646,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; - + } - - - + + + dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, @@ -668,26 +672,26 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // printf("MRC\n"); if (frame_parms->nb_antennas_rx > 1) { if ((dlsch0_harq->mimo_mode == LARGE_CDD) || - ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 if (frame_parms->nb_antennas_tx_eNB == 2) { - dlsch_detection_mrc_TM34(frame_parms, + dlsch_detection_mrc_TM34(frame_parms, lte_ue_pdsch_vars[eNB_id], harq_pid, dlsch0_harq->round, symbol, nb_rb, 1); - - + + /* if (symbol == 5) { - + write_output("rho0_mrc.m","rho0_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rho2_mrc.m","rho2_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 } */ - - + + } } else { @@ -702,7 +706,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, symbol, nb_rb, - rx_type==rx_IC_single_stream); + rx_type==rx_IC_single_stream); } } @@ -726,12 +730,12 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, symbol, nb_rb); - - } - + + } + // printf("LLR"); - if ((dlsch0_harq->mimo_mode == LARGE_CDD) || - ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + if ((dlsch0_harq->mimo_mode == LARGE_CDD) || + ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { rxdataF_comp_ptr = lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; dl_ch_mag_ptr = lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round]; @@ -743,7 +747,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } switch (dlsch0_harq->Qm) { - case 2 : + case 2 : if (rx_type==rx_standard) { dlsch_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, @@ -773,7 +777,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); } } - else if (dlsch1_harq->Qm == 4) { + else if (dlsch1_harq->Qm == 4) { dlsch_qpsk_16qam_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i @@ -816,7 +820,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); } - } + } } break; case 4 : @@ -914,7 +918,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->llr128); } else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { + if (dlsch1_harq->Qm == 2) { dlsch_64qam_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i @@ -960,7 +964,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); } } - else { + else { dlsch_64qam_64qam_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i @@ -996,7 +1000,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (dlsch1_harq) { switch (get_Qm(dlsch1_harq->mcs)) { - case 2 : + case 2 : if (rx_type==rx_standard) { dlsch_qpsk_llr(frame_parms, rxdataF_comp_ptr, @@ -1037,7 +1041,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); return(-1); break; - } + } } return(0); @@ -1070,23 +1074,23 @@ void dlsch_channel_compensation(int **rxdataF_ext, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - - if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size + + if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size nb_rb=1+(5*nb_rb/6); - else - pilots=1; + else + pilots=1; } for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) { if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) QAM_amp128b = _mm_setzero_si128(); - } + } else if (mod_order == 6) { - QAM_amp128 = _mm_set1_epi16(QAM64_n1); + QAM_amp128 = _mm_set1_epi16(QAM64_n1); QAM_amp128b = _mm_set1_epi16(QAM64_n2); } - + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); for (aarx=0;aarxnb_antennas_rx;aarx++) { @@ -1099,58 +1103,58 @@ void dlsch_channel_compensation(int **rxdataF_ext, for (rb=0;rb2) { + if (mod_order>2) { // get channel amplitude if not QPSK - + mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - + mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - + // store channel magnitude here in a new field of dlsch - + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - + dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[1] = dl_ch_mag128[1]; dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - + if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - + dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag128b[2] = dl_ch_mag128[2]; - + dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); + dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); } - + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - - + + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - + if (pilots==0) { dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); } } - + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); // print_ints("re",&mmtmpD0); - + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); @@ -1170,7 +1174,7 @@ void dlsch_channel_compensation(int **rxdataF_ext, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch128); // print_shorts("pack:",rxdataF_comp128); - + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -1183,12 +1187,12 @@ void dlsch_channel_compensation(int **rxdataF_ext, mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - + rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+1); // print_shorts("ch:",dl_ch128+1); - // print_shorts("pack:",rxdataF_comp128+1); - + // print_shorts("pack:",rxdataF_comp128+1); + if (pilots==0) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); @@ -1202,12 +1206,12 @@ void dlsch_channel_compensation(int **rxdataF_ext, mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+2); // print_shorts("ch:",dl_ch128+2); // print_shorts("pack:",rxdataF_comp128+2); - + dl_ch128+=3; dl_ch_mag128+=3; dl_ch_mag128b+=3; @@ -1221,24 +1225,24 @@ void dlsch_channel_compensation(int **rxdataF_ext, rxdataF128+=2; rxdataF_comp128+=2; } - + } } } - + if (rho) { - - + + for (aarx=0;aarxnb_antennas_rx;aarx++) { rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - + for (rb=0;rbrx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12); - } - } + } + } } _mm_empty(); _m_empty(); -} +} @@ -1361,16 +1365,16 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) } #elif defined(__arm__) void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { - + __m128i amp; amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); switch (pmi) { - + case 0 : // +1 +1 // print_shorts("phase 0 :ch0",ch0); // print_shorts("phase 0 :ch1",ch1); - ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); + ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); break; case 1 : // +1 -1 // print_shorts("phase 1 :ch0",ch0); @@ -1383,7 +1387,7 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); - + break; // +1 -j case 3 : ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); @@ -1395,7 +1399,7 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_mulhi_epi16(ch0[0],amp); ch0[0] = _mm_slli_epi16(ch0[0],1); - + _mm_empty(); _m_empty(); } @@ -1407,11 +1411,11 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { short TM3_prec[8]__attribute__((aligned(16))) = {1,1,-1,-1,1,1,-1,-1} ; void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { - + // __m128i amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); - + __m128i tmp0,tmp1; - + // print_shorts("prec2A_TM3 ch0 (before):",ch0); // print_shorts("prec2A_TM3 ch1 (before):",ch1); @@ -1433,7 +1437,7 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { // print_shorts("prec2A_TM3 ch0 (after):",ch0); // print_shorts("prec2A_TM3 ch1 (after):",ch1); - + _mm_empty(); _m_empty(); } @@ -1442,12 +1446,12 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { // pmi = 1 => stream 0 (1,j), stream 2 (1,-j) void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { - + // printf ("demod pmi=%d\n", pmi); // __m128i amp; // amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); __m128i tmp0,tmp1; - + // print_shorts("prec2A_TM4 ch0 (before):",ch0); // print_shorts("prec2A_TM4 ch1 (before):",ch1); @@ -1474,7 +1478,7 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { //ch1[0] = _mm_mulhi_epi16(ch1[0],amp); //ch1[0] = _mm_slli_epi16(ch1[0],1); - + ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 //print_shorts("prec2A_TM4 ch0 (end):",ch0); @@ -1547,26 +1551,26 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, if (pilots==0) { - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); + prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); } - if (mod_order>2) { + if (mod_order>2) { // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); + + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - + mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - + dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - + //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]); //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]); @@ -1575,31 +1579,31 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, dl_ch_mag128b[1] = dl_ch_mag128[1]; dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - + if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - + dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag128b[2] = dl_ch_mag128[2]; - + dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); + dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); } - + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - + //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]); - + dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - + if (pilots==0) { dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); } } @@ -1628,7 +1632,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch128); // print_shorts("pack:",rxdataF_comp128); - + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -1697,42 +1701,42 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, uint32_t rb,Nre; uint32_t aarx,symbol_mod,pilots=0; - + int16x4_t *dl_ch0_128,*dl_ch1_128,*rxdataF128; int16x8_t *dl_ch0_128b,*dl_ch1_128b; int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; int16x8_t *dl_ch_mag128,*dl_ch_mag128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp128; int16x8_t QAM_amp128,QAM_amp128b; - + int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); int32_t precoded_signal_strength=0; - - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size { nb_rb=1+(5*nb_rb/6); } - + else { pilots=1; } } - - + + if (mod_order == 4) { QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) QAM_amp128b = vmovq_n_s16(0); - + } else if (mod_order == 6) { QAM_amp128 = vmovq_n_s16(QAM64_n1); // QAM_amp128b = vmovq_n_s16(QAM64_n2); } - + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); - + for (aarx=0; aarxnb_antennas_rx; aarx++) { - - - + + + dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; @@ -1741,18 +1745,18 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, dl_ch_mag128b = (int16x8_t*)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128 = (int16x8_t*)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12]; - + for (rb=0; rb%d\n",rb,pmi_ext[rb]); #endif prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[0],&dl_ch1_128b[0]); prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[1],&dl_ch1_128b[1]); - + if (pilots==0) { prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[2],&dl_ch1_128b[2]); } - + if (mod_order>2) { // get channel amplitude if not QPSK mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); @@ -1762,7 +1766,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); @@ -1774,29 +1778,29 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - + + } - + dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); - - + + if (pilots==0) { dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); } } mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]); - //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] + //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]); - //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] + //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] - + //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); @@ -1804,49 +1808,49 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + if (pilots==0) { mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - + + dl_ch0_128+=6; dl_ch1_128+=6; dl_ch_mag128+=3; dl_ch_mag128b+=3; rxdataF128+=6; rxdataF_comp128+=3; - + } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less dl_ch0_128+=4; dl_ch1_128+=4; @@ -1856,23 +1860,23 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, rxdataF_comp128+=2; } } - + Nre = (pilots==0) ? 12 : 8; - + precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], (nb_rb*Nre))) - (phy_measurements->n0_power[aarx])); // rx_antennas } phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,phy_measurements->n0_power_tot); - + //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, // phy_measurements->precoded_cqi_dB[eNB_id][0]); - -#endif + +#endif _mm_empty(); - _m_empty(); -} + _m_empty(); +} void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_PDSCH *lte_ue_pdsch_vars, @@ -1906,15 +1910,15 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; unsigned char *pmi_ext = lte_ue_pdsch_vars->pmi_ext; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; - + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) pilots=1; rx_power_correction = 1; - + // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); if (mod_order0 == 4) { @@ -1932,23 +1936,23 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, QAM_amp1_128 = _mm_set1_epi16(QAM64_n1); QAM_amp1_128b = _mm_set1_epi16(QAM64_n2); } - + for (aarx=0;aarxnb_antennas_rx;aarx++) { - + /* if (aarx==0) { - output_shift=output_shift0; + output_shift=output_shift0; } else { output_shift=output_shift1; } */ - - // printf("antenna %d\n", aarx); + + // printf("antenna %d\n", aarx); // printf("symbol %d, rx antenna %d\n", symbol, aarx); dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 - - + + dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 dl_ch_mag0_128b = (__m128i *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12];//responsible for x1 dl_ch_mag1_128 = (__m128i *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x2. always coming from tx2 @@ -1958,156 +1962,156 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp1_128 = (__m128i *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; //result of multipl with MF x2 on antenna of interest for (rb=0; rb2) { + + if (mod_order0>2) { // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); + + mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - + mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - + dl_ch_mag0_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag0_128b[0] = dl_ch_mag0_128[0]; dl_ch_mag0_128[0] = _mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128); dl_ch_mag0_128[0] = _mm_slli_epi16(dl_ch_mag0_128[0],1); - + // print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]); - + dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag0_128b[1] = dl_ch_mag0_128[1]; dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128); dl_ch_mag0_128[1] = _mm_slli_epi16(dl_ch_mag0_128[1],1); - + if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - + dl_ch_mag0_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag0_128b[2] = dl_ch_mag0_128[2]; - + dl_ch_mag0_128[2] = _mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128); - dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1); + dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1); } - + dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b); dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1); - + // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]); - + dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b); dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1); - + if (pilots==0) { dl_ch_mag0_128b[2] = _mm_mulhi_epi16(dl_ch_mag0_128b[2],QAM_amp0_128b); - dl_ch_mag0_128b[2] = _mm_slli_epi16(dl_ch_mag0_128b[2],1); + dl_ch_mag0_128b[2] = _mm_slli_epi16(dl_ch_mag0_128b[2],1); } } - if (mod_order1>2) { + if (mod_order1>2) { // get channel amplitude if not QPSK - - mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); + + mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - + mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - + dl_ch_mag1_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag1_128b[0] = dl_ch_mag1_128[0]; dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128); dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1); - + // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]); dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag1_128b[1] = dl_ch_mag1_128[1]; dl_ch_mag1_128[1] = _mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128); dl_ch_mag1_128[1] = _mm_slli_epi16(dl_ch_mag1_128[1],1); - + if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - + dl_ch_mag1_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag1_128b[2] = dl_ch_mag1_128[2]; - + dl_ch_mag1_128[2] = _mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128); - dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1); + dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1); } - + dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b); dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1); - + // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]); - + dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b); dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1); - + if (pilots==0) { dl_ch_mag1_128b[2] = _mm_mulhi_epi16(dl_ch_mag1_128b[2],QAM_amp1_128b); - dl_ch_mag1_128b[2] = _mm_slli_epi16(dl_ch_mag1_128b[2],1); + dl_ch_mag1_128b[2] = _mm_slli_epi16(dl_ch_mag1_128b[2],1); } } - // layer 0 + // layer 0 // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - + // print_ints("re",&mmtmpD0); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); @@ -2129,7 +2133,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch0_128); // print_shorts("pack:",rxdataF_comp0_128); - + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -2146,8 +2150,8 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp0_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+1); // print_shorts("ch:",dl_ch0_128+1); - // print_shorts("pack:",rxdataF_comp0_128+1); - + // print_shorts("pack:",rxdataF_comp0_128+1); + if (pilots==0) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],rxdataF128[2]); @@ -2161,20 +2165,20 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - + rxdataF_comp0_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+2); // print_shorts("ch:",dl_ch0_128+2); // print_shorts("pack:",rxdataF_comp0_128+2); - + } - - + + // layer 1 // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],rxdataF128[0]); // print_ints("re",&mmtmpD0); - + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); @@ -2194,7 +2198,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch1_128); // print_shorts("pack:",rxdataF_comp1_128); - + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch1_128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -2211,7 +2215,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp1_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+1); // print_shorts("ch:",dl_ch1_128+1); - // print_shorts("pack:",rxdataF_comp1_128+1); + // print_shorts("pack:",rxdataF_comp1_128+1); if (pilots==0) { // multiply by conjugated channel @@ -2226,12 +2230,12 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - + rxdataF_comp1_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+2); // print_shorts("ch:",dl_ch1_128+2); // print_shorts("pack:",rxdataF_comp1_128+2); - + dl_ch0_128+=3; dl_ch1_128+=3; dl_ch_mag0_128+=3; @@ -2253,40 +2257,40 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp0_128+=2; rxdataF_comp1_128+=2; } - + } // rb loop Nre = (pilots==0) ? 12 : 8; - + precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); - + precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); } // rx_antennas - + phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,phy_measurements->n0_power_tot); phy_measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,phy_measurements->n0_power_tot); - + // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, // phy_measurements->precoded_cqi_dB[eNB_id][0]); - + _mm_empty(); _m_empty(); - + #elif defined(__arm__) unsigned short rb,Nre; unsigned char aarx,symbol_mod,pilots=0; - int precoded_signal_strength0=0,precoded_signal_strength1=0, rx_power_correction; + int precoded_signal_strength0=0,precoded_signal_strength1=0, rx_power_correction; int16x4_t *dl_ch0_128,*rxdataF128; int16x4_t *dl_ch1_128; int16x8_t *dl_ch0_128b,*dl_ch1_128b; - + int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; int16x8_t *dl_ch_mag0_128,*dl_ch_mag0_128b,*dl_ch_mag1_128,*dl_ch_mag1_128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp0_128,*rxdataF_comp1_128; int16x8_t QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); - + int **rxdataF_ext = lte_ue_pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = lte_ue_pdsch_vars->dl_ch_estimates_ext; int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; @@ -2295,45 +2299,45 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1[harq_pid][round]; int **rxdataF_comp0 = lte_ue_pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; - + int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; - + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { if (frame_parms->mode1_flag==1) // 10 out of 12 so don't reduce size { nb_rb=1+(5*nb_rb/6); } - + else { pilots=1; } } - + rx_power_correction=1; - + if (mod_order0 == 4) { QAM_amp0_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) QAM_amp0_128b = vmovq_n_s16(0); - + } else if (mod_order0 == 6) { QAM_amp0_128 = vmovq_n_s16(QAM64_n1); // QAM_amp0_128b = vmovq_n_s16(QAM64_n2); } - + if (mod_order1 == 4) { QAM_amp1_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) QAM_amp1_128b = vmovq_n_s16(0); - + } else if (mod_order1 == 6) { QAM_amp1_128 = vmovq_n_s16(QAM64_n1); // QAM_amp1_128b = vmovq_n_s16(QAM64_n2); } - + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); - + for (aarx=0; aarxnb_antennas_rx; aarx++) { - - - + + + dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; @@ -2345,32 +2349,32 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp0_128 = (int16x8_t*)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp1_128 = (int16x8_t*)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; - + for (rb=0; rb2) { // get channel amplitude if not QPSK mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); @@ -2388,29 +2392,29 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + if (pilots==0) { mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - + + } - + dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b); dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b); dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128); dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128); - - + + if (pilots==0) { dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b); dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128); @@ -2426,43 +2430,43 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]); mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + if (pilots==0) { mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]); mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - + + } - + dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b); dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b); dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128); dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128); - - + + if (pilots==0) { dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b); dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128); } } - + mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]); - //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] + //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]); - //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] + //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] - + //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); @@ -2470,68 +2474,68 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp0_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp0_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + // second stream mmtmpD0 = vmull_s16(dl_ch1_128[0], rxdataF128[0]); mmtmpD1 = vmull_s16(dl_ch1_128[1], rxdataF128[1]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); - + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp1_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + mmtmpD0 = vmull_s16(dl_ch1_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch1_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp1_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - + if (pilots==0) { mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); @@ -2539,21 +2543,21 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - + + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); } } - - - + + + Nre = (pilots==0) ? 12 : 8; // rx_antennas @@ -2564,7 +2568,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); - + precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], (nb_rb*Nre))*rx_power_correction) - (phy_measurements->n0_power[aarx])); @@ -2601,9 +2605,9 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); for (aarx=0; aarxnb_antennas_rx; aarx++) { - - - + + + //printf ("antenna %d", aarx); dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; @@ -2650,8 +2654,8 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); - - if (pilots==0) { + + if (pilots==0) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); @@ -2666,7 +2670,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - + dl_ch128+=3; dl_ch128i+=3; dl_ch_rho128+=3; @@ -2676,10 +2680,10 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, dl_ch128i+=2; dl_ch_rho128+=2; } - } + } } - + _mm_empty(); _m_empty(); @@ -2717,14 +2721,14 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); for (aarx=0; aarxnb_antennas_rx; aarx++) { - + if (aarx==0) { - output_shift=output_shift0; + output_shift=output_shift0; } else { output_shift=output_shift1; } - + //printf ("antenna %d", aarx); dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; @@ -2771,8 +2775,8 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); - - if (pilots==0) { + + if (pilots==0) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); @@ -2787,7 +2791,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - + dl_ch128+=3; dl_ch128i+=3; dl_ch_rho128+=3; @@ -2797,10 +2801,10 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, dl_ch128i+=2; dl_ch_rho128+=2; } - } + } } - + _mm_empty(); _m_empty(); @@ -2851,7 +2855,7 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, // print_shorts("mrc mag0:",&dl_ch_mag128_0[i]); // print_shorts("mrc mag0b:",&dl_ch_mag128_0b[i]); // print_shorts("mrc rho1:",&rho128_1[i]); - + } } @@ -2952,13 +2956,13 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *lte_ue_pdsch_vars, + LTE_UE_PDSCH *lte_ue_pdsch_vars, int harq_pid, int round, unsigned char symbol, unsigned short nb_rb, unsigned char dual_stream_UE) { - + unsigned char aatx; int i; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; @@ -2971,23 +2975,23 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1[harq_pid][round]; int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1[harq_pid][round]; - - + + if (frame_parms->nb_antennas_rx>1) { - - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[1][symbol*frame_parms->N_RB_DL*12]; + + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1 = (__m128i *)&dl_ch_mag0[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_0b = (__m128i *)&dl_ch_magb0[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_1b = (__m128i *)&dl_ch_magb0[1][symbol*frame_parms->N_RB_DL*12]; // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) for (i=0;iN_RB_DL*12]; rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i1 = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i0b = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i1 = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i0b = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i1b = (__m128i *)&dl_ch_magb1[1][symbol*frame_parms->N_RB_DL*12]; for (i=0;isqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); @@ -3068,7 +3072,7 @@ ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); for (aarx=0;aarxnb_antennas_rx;aarx++) { dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - + for (rb=0;rbsqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3); dl_ch128+=3; - } - } + } + } } } @@ -3125,11 +3129,11 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],dl_ch128[0])); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) { - dl_ch128+=2; + dl_ch128+=2; } else { avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); - dl_ch128+=3; + dl_ch128+=3; } /* if (rb==0) { @@ -3147,9 +3151,9 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, else nre=12; - avg[(aatx<<1)+aarx] = (((int*)&avg128D)[0] + - ((int*)&avg128D)[1] + - ((int*)&avg128D)[2] + + avg[(aatx<<1)+aarx] = (((int*)&avg128D)[0] + + ((int*)&avg128D)[1] + + ((int*)&avg128D)[2] + ((int*)&avg128D)[3])/(nb_rb*nre); // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); @@ -3259,7 +3263,7 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, for (aarx=0; aarxnb_antennas_rx; aarx++) { dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - + avg_0_128D = _mm_setzero_si128(); avg_1_128D = _mm_setzero_si128(); for (rb=0; rbNcp-1)))&&(frame_parms->mode1_flag==0)) { - dl_ch0_128+=2; + dl_ch0_128+=2; dl_ch1_128+=2; } else { dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); + dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - if (mimo_mode==LARGE_CDD) + if (mimo_mode==LARGE_CDD) prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); @@ -3317,27 +3321,27 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); - + avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - - dl_ch0_128+=3; + + dl_ch0_128+=3; dl_ch1_128+=3; - } + } } - - + + avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) + (((int*)&avg_0_128D)[1])/(nb_rb*nre) + (((int*)&avg_0_128D)[2])/(nb_rb*nre) + (((int*)&avg_0_128D)[3])/(nb_rb*nre); // printf("From Chan_level aver stream 0 %d =%d\n", aarx, avg_0[aarx]); - + avg_1[aarx] = (((int*)&avg_1_128D)[0])/(nb_rb*nre) + (((int*)&avg_1_128D)[1])/(nb_rb*nre) + (((int*)&avg_1_128D)[2])/(nb_rb*nre) + - (((int*)&avg_1_128D)[3])/(nb_rb*nre); + (((int*)&avg_1_128D)[3])/(nb_rb*nre); // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); } //avg_0[0] = max(avg_0[0],avg_0[1]); @@ -3399,38 +3403,38 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]); - if (mimo_mode==LARGE_CDD) + if (mimo_mode==LARGE_CDD) prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - // mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + // mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]); - if (mimo_mode==LARGE_CDD) + if (mimo_mode==LARGE_CDD) prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) prec2A_TM4_128(1,&dl_ch0_128_tmp,&dl_ch1_128_tmp); - // mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + // mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) { - dl_ch0_128+=2; + dl_ch0_128+=2; dl_ch1_128+=2; } else { dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); + dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - if (mimo_mode==LARGE_CDD) + if (mimo_mode==LARGE_CDD) prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) prec2A_TM4_128(0,&dl_ch0_128_tmp,&dl_ch1_128_tmp); @@ -3440,9 +3444,9 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - dl_ch0_128+=3; + dl_ch0_128+=3; dl_ch1_128+=3; - } + } } avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + @@ -3513,20 +3517,20 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) { - dl_ch0_128+=2; + dl_ch0_128+=2; dl_ch1_128+=2; } else { dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); - dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); + dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - dl_ch0_128+=3; + dl_ch0_128+=3; dl_ch1_128+=3; - } + } } avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + @@ -3575,7 +3579,7 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, ch_mag1 = (__m128i *)&dl_ch_mag[2][jj]; ch_mag0b = (__m128i *)&dl_ch_magb[0][jj]; ch_mag1b = (__m128i *)&dl_ch_magb[2][jj]; - + for (rb=0; rbfirst_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs - + for (rb=0;rbN_RB_DL;rb++) { - + if (rb < 32) rb_alloc_ind = (rb_alloc[0]>>rb) & 1; else if (rb < 64) @@ -3826,31 +3830,31 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, skip_half=1; else if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) skip_half=2; - + //SSS - if (((subframe==0)||(subframe==5)) && - (rb>((frame_parms->N_RB_DL>>1)-3)) && - (rb<((frame_parms->N_RB_DL>>1)+3)) && + if (((subframe==0)||(subframe==5)) && + (rb>((frame_parms->N_RB_DL>>1)-3)) && + (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { rb_alloc_ind = 0; } - //SSS - if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)-3)) && + //SSS + if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb)) skip_half=1; - else if (((subframe==0)||(subframe==5)) && - (rb==((frame_parms->N_RB_DL>>1)+3)) && + else if (((subframe==0)||(subframe==5)) && + (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb)) skip_half=2; //PSS in subframe 0/5 if FDD if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && - (rb>((frame_parms->N_RB_DL>>1)-3)) && - (rb<((frame_parms->N_RB_DL>>1)+3)) && + if (((subframe==0)||(subframe==5)) && + (rb>((frame_parms->N_RB_DL>>1)-3)) && + (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { rb_alloc_ind = 0; } @@ -3860,7 +3864,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) skip_half=2; } - + if ((frame_parms->frame_type == TDD) && (subframe==6)){ //TDD Subframe 6 if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { @@ -3984,8 +3988,8 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, // PBCH - if ((subframe==0) && - (l>=(nsymb>>1)) && + if ((subframe==0) && + (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { rb_alloc_ind = 0; } @@ -4008,7 +4012,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, (l==pss_symb) ) { rb_alloc_ind = 0; } - + // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); // printf("DC rb %d (%p)\n",rb,rxF); @@ -4052,7 +4056,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, rxF_ext[j++]=rxF[(1+i-6)]; #ifdef DEBUG_DLSCH_DEMOD printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); -#endif +#endif } } @@ -4067,9 +4071,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, dl_ch0+=12; rxF+=7; rb++; - + for (;rbN_RB_DL;rb++) { - // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); + // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); // printf("rb %d (%p)\n",rb,rxF); skip_half=0; @@ -4134,7 +4138,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, } if (rb_alloc_ind==1) { -#ifdef DEBUG_DLSCH_DEMOD +#ifdef DEBUG_DLSCH_DEMOD printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif /* @@ -4150,7 +4154,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[i]; -#ifdef DEBUG_DLSCH_DEMOD +#ifdef DEBUG_DLSCH_DEMOD printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif } @@ -4233,7 +4237,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, } } } - + return(nb_rb/frame_parms->nb_antennas_rx); } @@ -4250,7 +4254,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode) { - + int prb,nb_rb=0; int prb_off,prb_off2; int rb_alloc_ind,skip_half=0,sss_symb,pss_symb=0,nsymb,l; @@ -4258,7 +4262,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, int32_t *dl_ch0,*dl_ch0p,*dl_ch0_ext,*dl_ch1,*dl_ch1p,*dl_ch1_ext,*rxF,*rxF_ext; int symbol_mod,pilots=0,j=0; unsigned char *pmi_loc; - + symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; // printf("extract_rbs: symbol_mod %d\n",symbol_mod); @@ -4287,7 +4291,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } pmi_loc = pmi_ext; - + // pointers to extracted RX signals and channel estimates rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; @@ -4295,7 +4299,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, for (prb=0; prbN_RB_DL; prb++) { skip_half=0; - + if (prb < 32) rb_alloc_ind = (rb_alloc[0]>>prb) & 1; else if (prb < 64) @@ -4309,22 +4313,22 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, if (rb_alloc_ind == 1) nb_rb++; - + if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs // PBCH - if ((subframe==0) && - (prb>=((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l>=(nsymb>>1)) && + if ((subframe==0) && + (prb>=((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { rb_alloc_ind = 0; // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb); } - + //SSS - + if (((subframe==0)||(subframe==5)) && (prb>=((frame_parms->N_RB_DL>>1)-3)) && (prb<((frame_parms->N_RB_DL>>1)+3)) && @@ -4332,59 +4336,59 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rb_alloc_ind = 0; // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); } - - - + + + //PSS in subframe 0/5 if FDD if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && - (prb>=((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && + if (((subframe==0)||(subframe==5)) && + (prb>=((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { rb_alloc_ind = 0; // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb); } } - + if ((frame_parms->frame_type == TDD) && (subframe==6)) { //TDD Subframe 6 - if ((prb>=((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && + if ((prb>=((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { rb_alloc_ind = 0; } } - + if (rb_alloc_ind==1) { // PRB is allocated - + prb_off = 12*prb; prb_off2 = 1+(12*(prb-(frame_parms->N_RB_DL>>1))); dl_ch0p = dl_ch0+(12*prb); dl_ch1p = dl_ch1+(12*prb); if (prb<(frame_parms->N_RB_DL>>1)){ rxF = &rxdataF[aarx][prb_off+ - frame_parms->first_carrier_offset + + frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size))]; } else { rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } - + /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; else *pmi_loc=(pmi>>prb)&1;*/ - + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; - - + + if (pilots == 0) { - + memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int)); memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int)); memcpy(rxF_ext,rxF,12*sizeof(int)); @@ -4414,17 +4418,17 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, // PBCH - if ((subframe==0) && - (prb>((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l>=(nsymb>>1)) && + if ((subframe==0) && + (prb>((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { rb_alloc_ind = 0; // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb); } - + //SSS - + if (((subframe==0)||(subframe==5)) && (prb>((frame_parms->N_RB_DL>>1)-3)) && (prb<((frame_parms->N_RB_DL>>1)+3)) && @@ -4432,24 +4436,24 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rb_alloc_ind = 0; // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); } - - - + + + //PSS in subframe 0/5 if FDD if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && - (prb>((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && + if (((subframe==0)||(subframe==5)) && + (prb>((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { rb_alloc_ind = 0; // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb); } } - + if ((frame_parms->frame_type == TDD) && ((subframe==1) || (subframe==6))) { //TDD Subframe 1-6 - if ((prb>((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && + if ((prb>((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { rb_alloc_ind = 0; } @@ -4457,23 +4461,23 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, if (rb_alloc_ind == 1) { skip_half=0; - + //Check if we have to drop half a PRB due to PSS/SSS/PBCH // skip_half == 0 means full PRB // skip_half == 1 means first half is used (leftmost half-PRB from PSS/SSS/PBCH) // skip_half == 2 means second half is used (rightmost half-PRB from PSS/SSS/PBCH) //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 - if ((subframe==0) && - (prb==((frame_parms->N_RB_DL>>1)-3)) && - (l>=(nsymb>>1)) && + if ((subframe==0) && + (prb==((frame_parms->N_RB_DL>>1)-3)) && + (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) skip_half=1; - else if ((subframe==0) && - (prb==((frame_parms->N_RB_DL>>1)+3)) && - (l>=(nsymb>>1)) && + else if ((subframe==0) && + (prb==((frame_parms->N_RB_DL>>1)+3)) && + (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) skip_half=2; - + //SSS if (((subframe==0)||(subframe==5)) && (prb==((frame_parms->N_RB_DL>>1)-3)) && @@ -4483,34 +4487,34 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, (prb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb)) skip_half=2; - + //PSS Subframe 0,5 if (((frame_parms->frame_type == FDD) && (((subframe==0)||(subframe==5)))) || //FDD Subframes 0,5 ((frame_parms->frame_type == TDD) && (((subframe==1) || (subframe==6))))) { //TDD Subframes 1,6 - - if ((prb==((frame_parms->N_RB_DL>>1)-3)) && + + if ((prb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) skip_half=1; - else if ((prb==((frame_parms->N_RB_DL>>1)+3)) && + else if ((prb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) skip_half=2; } - - + + prb_off = 12*prb; prb_off2 = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1)); dl_ch0p = dl_ch0+(12*prb); dl_ch1p = dl_ch1+(12*prb); - + if (prb<=(frame_parms->N_RB_DL>>1)){ rxF = &rxdataF[aarx][prb_off+ - frame_parms->first_carrier_offset + + frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size))]; } else { - rxF = &rxdataF[aarx][prb_off2+ + rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } #ifdef DEBUG_DLSCH_DEMOD @@ -4563,7 +4567,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } } else { // pilots=1 j=0; - + if (skip_half==1) { for (i=0; i<6; i++) { if ((i!=frame_parms->nushift) && @@ -4615,7 +4619,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } //skip_half==0 } //pilots==1 } else { // Do middle RB (around DC) - + if (pilots==0) { memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); @@ -4630,12 +4634,12 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch1_ext+=6; dl_ch0p+=6; dl_ch1p+=6; - + rxF = &rxdataF[aarx][1+((symbol*(frame_parms->ofdm_symbol_size)))]; memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); - memcpy(rxF_ext,rxF,6*sizeof(int32_t)); + memcpy(rxF_ext,rxF,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD for (i=0; i<6; i++) { printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); @@ -4646,7 +4650,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch1_ext+=6; } else { // pilots==1 j=0; - + for (i=0; i<6; i++) { if ((i!=frame_parms->nushift) && (i!=((frame_parms->nushift+3)%6))) { @@ -4659,27 +4663,27 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } } rxF = &rxdataF[aarx][1+symbol*(frame_parms->ofdm_symbol_size)]; - + for (; i<12; i++) { if ((i!=((frame_parms->nushift+6)%12)) && (i!=((frame_parms->nushift+9)%12))) { dl_ch0_ext[j]=dl_ch0p[i]; dl_ch1_ext[j]=dl_ch1p[i]; - rxF_ext[j++]=rxF[i-6]; + rxF_ext[j++]=rxF[i-6]; #ifdef DEBUG_DLSCH_DEMOD printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short*)&rxF[1+i-6])); #endif } } - + dl_ch0_ext+=8; dl_ch1_ext+=8; rxF_ext+=8; } //pilots==1 } // if Middle PRB - } // if odd PRB + } // if odd PRB } // if rballoc==1 - } // for prb + } // for prb } // for aarx return(nb_rb/frame_parms->nb_antennas_rx); } @@ -4741,12 +4745,12 @@ void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round); sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round); write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); - - + + // sprintf(fname,"dlsch%d_r%d_aver_chan_1.m",eNB_id,round); // sprintf(vname,"dl_aver_ch1_r%d_%d",eNB_id,round); // write_output(fname,vname,&avg_1[0],1,1,1); - + sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round); write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 781add5d95..4c70f08230 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -155,13 +155,13 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, { - uint8_t *x0 = dlsch0_harq->e; - MIMO_mode_t mimo_mode = dlsch0_harq->mimo_mode; + uint8_t *x0 = NULL; //dlsch0_harq->e; + MIMO_mode_t mimo_mode = dlsch0_harq->mimo_mode; - int first_layer0 = dlsch0_harq->first_layer; - int Nlayers0 = dlsch0_harq->Nlayers; - uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs); - uint8_t mod_order1=2; + int first_layer0; //= dlsch0_harq->first_layer; + int Nlayers0; // = dlsch0_harq->Nlayers; + uint8_t mod_order0; // = get_Qm(dlsch0_harq->mcs); + uint8_t mod_order1; //=2; uint8_t precoder_index0,precoder_index1; uint8_t *x1=NULL; @@ -199,15 +199,40 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); // if (mimo_mode == LARGE_CDD) gain_lin_QPSK>>=1; - if (dlsch1_harq) { + + + if ((dlsch0_harq != NULL) && (dlsch1_harq != NULL)) { //this is for TM3, TM4 + + x0 = dlsch0_harq->e; + mimo_mode = dlsch0_harq->mimo_mode; + first_layer0 = dlsch0_harq->first_layer; + Nlayers0 = dlsch0_harq->Nlayers; + mod_order0 = get_Qm(dlsch0_harq->mcs); x1 = dlsch1_harq->e; // Fill these in later for TM8-10 // Nlayers1 = dlsch1_harq->Nlayers; // first_layer1 = dlsch1_harq->first_layer; mod_order1 = get_Qm(dlsch1_harq->mcs); + } else if ((dlsch0_harq != NULL) && (dlsch1_harq == NULL)){ //This is for SIS0 TM1, TM6, etc + + x0 = dlsch0_harq->e; + mimo_mode = dlsch0_harq->mimo_mode; + first_layer0 = dlsch0_harq->first_layer; + Nlayers0 = dlsch0_harq->Nlayers; + mod_order0 = get_Qm(dlsch0_harq->mcs); + + } else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ // This is for TM4 retransmission + + x0 = dlsch1_harq->e; + mimo_mode = dlsch1_harq->mimo_mode; + first_layer0 = dlsch1_harq->first_layer; + Nlayers0 = dlsch1_harq->Nlayers; + mod_order0 = get_Qm(dlsch1_harq->mcs); + } + /* switch (mod_order) { case 2: @@ -229,9 +254,16 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } */ -#ifdef DEBUG_DLSCH_MODULATION - printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); -#endif + if (dlsch0_harq != NULL){ + #ifdef DEBUG_DLSCH_MODULATION + printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); + #endif + } else{ + #ifdef DEBUG_DLSCH_MODULATION + printf("allocate_re (mod %d): symbol_offset %d re_offset %d (%d,%d), jj %d -> %d,%d\n",mod_order0,symbol_offset,re_offset,skip_dc,skip_half,*jj, x0[*jj], x0[1+*jj]); + #endif + } + first_re=0; last_re=12; @@ -360,7 +392,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, else if (mimo_mode == ALAMOUTI) { *re_allocated = *re_allocated + 1; - + amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); @@ -386,23 +418,23 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); - + break; - + case 4: //16QAM - - // Antenna 0 position n + + // Antenna 0 position n qam16_table_offset_re = 0; qam16_table_offset_im = 0; - + if (x0[*jj] == 1) qam16_table_offset_re+=2; *jj=*jj+1; if (x0[*jj] == 1) qam16_table_offset_im+=2; *jj=*jj+1; - - + + if (x0[*jj] == 1) qam16_table_offset_re+=1; *jj=*jj+1; @@ -412,12 +444,12 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - + //((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15; - //((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; + //((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; // Antenna 1 position n Real part -> -x1* - + qam16_table_offset_re = 0; qam16_table_offset_im = 0; @@ -427,8 +459,8 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x0[*jj] == 1) qam16_table_offset_im+=2; *jj=*jj+1; - - + + if (x0[*jj] == 1) qam16_table_offset_re+=1; *jj=*jj+1; @@ -439,13 +471,13 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - //((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re]; - //((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; + //((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re]; + //((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; break; case 6: // 64-QAM - + // Antenna 0 qam64_table_offset_re = 0; qam64_table_offset_im = 0; @@ -468,11 +500,11 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x0[*jj] == 1) qam64_table_offset_im+=1; *jj=*jj+1; - + //((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15; - ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; + ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15; + ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; // Antenna 1 => -x1* qam64_table_offset_re = 0; @@ -498,12 +530,12 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, //((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - ((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im]; - + ((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam64_table_offset_re]; + ((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im]; + break; } - // fill in the rest of the ALAMOUTI precoding + // fill in the rest of the ALAMOUTI precoding if (is_not_pilot(pilots,re + 1,frame_parms->nushift,use2ndpilots)==1) { ((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1 ((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1]; @@ -537,9 +569,9 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, *jj = *jj + 1; //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; - + case 4: //16QAM - + qam16_table_offset_re0 = 0; qam16_table_offset_im0 = 0; if (x0[*jj] == 1) @@ -548,25 +580,25 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x0[*jj] == 1) qam16_table_offset_im0+=2; *jj=*jj+1; - + if (x0[*jj] == 1) qam16_table_offset_re0+=1; *jj=*jj+1; if (x0[*jj] == 1) qam16_table_offset_im0+=1; *jj=*jj+1; - + xx0_re = qam_table_s0[qam16_table_offset_re0]; xx0_im = qam_table_s0[qam16_table_offset_im0]; break; - + case 6: //64QAM - - + + qam64_table_offset_re0 = 0; qam64_table_offset_im0 = 0; - + if (x0[*jj] == 1) qam64_table_offset_re0+=4; *jj=*jj+1; @@ -590,7 +622,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, xx0_im = qam_table_s0[qam64_table_offset_im0]; break; - + } switch (mod_order1) { @@ -602,15 +634,15 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, case 2: //QPSK //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + xx1_re = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; - xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; + xx1_im = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj2 = *jj2 + 1; //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); break; - + case 4: //16QAM - + qam16_table_offset_re1 = 0; qam16_table_offset_im1 = 0; if (x1[*jj2] == 1) @@ -630,12 +662,12 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, xx1_im = qam_table_s1[qam16_table_offset_im1]; break; - + case 6: //64QAM - + qam64_table_offset_re1 = 0; qam64_table_offset_im1 = 0; - + if (x1[*jj2] == 1) qam64_table_offset_re1+=4; *jj2 = *jj2 + 1; @@ -659,14 +691,14 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, xx1_im = qam_table_s1[qam64_table_offset_im1]; break; - + } // This implements the Large CDD precoding for 2 TX antennas // - - - - - - - - - - - - //| y0 | | 1 0 || 1 0 || 1 1 || x0 | | x0 + x1 | //| y1 | = .5 | 0 1 || 0 (-1)^i || 1 -1 || x1 | = .5| (-1)^i(x0 - x1)| - // - - - - - - - - - - - + // - - - - - - - - - - - // Note: Factor .5 is accounted for in amplitude when calling this function ((int16_t *)&txdataF[0][tti_offset])[0]+=((xx0_re+xx1_re)>>1); ((int16_t *)&txdataF[1][tti_offset])[0]+=(s*((xx0_re-xx1_re)>>1)); @@ -681,9 +713,9 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, s = -s; } } - else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) { + else if ((mimo_mode >= UNIFORM_PRECODING11)&&(mimo_mode <= PUSCH_PRECODING1)) { // this is for transmission modes 5-6 (1 layer) - *re_allocated = *re_allocated + 1; + *re_allocated = *re_allocated + 1; amp = (int16_t)(((int32_t)tmp_amp*ONE_OVER_SQRT2_Q15)>>15); switch (mod_order0) { @@ -705,9 +737,9 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } break; - + case 4: - + qam16_table_offset_re = 0; qam16_table_offset_im = 0; @@ -717,22 +749,22 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x0[*jj] == 1) qam16_table_offset_im+=2; *jj=*jj+1; - - + + if (x0[*jj] == 1) qam16_table_offset_re+=1; *jj=*jj+1; if (x0[*jj] == 1) qam16_table_offset_im+=1; *jj=*jj+1; - - + + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); @@ -740,7 +772,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } break; - + case 6: qam64_table_offset_re = 0; @@ -763,25 +795,25 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x0[*jj] == 1) qam64_table_offset_im+=1; *jj=*jj+1; - + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } - + break; } } else if ((mimo_mode >= DUALSTREAM_UNIFORM_PRECODING1)&&(mimo_mode <= DUALSTREAM_PUSCH_PRECODING)) { // this is for transmission mode 4 (1 layer) - *re_allocated = *re_allocated + 1; + *re_allocated = *re_allocated + 1; if (precoder_index==0) { precoder_index0 = 0; //[1 1] @@ -809,7 +841,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); @@ -817,9 +849,9 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } break; - + case 4: - + qam16_table_offset_re = 0; qam16_table_offset_im = 0; @@ -829,19 +861,19 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x0[*jj] == 1) qam16_table_offset_im+=2; *jj=*jj+1; - + if (x0[*jj] == 1) qam16_table_offset_re+=1; *jj=*jj+1; if (x0[*jj] == 1) qam16_table_offset_im+=1; *jj=*jj+1; - + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); @@ -849,9 +881,9 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } break; - + case 6: - + qam64_table_offset_re = 0; qam64_table_offset_im = 0; @@ -873,25 +905,25 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x0[*jj] == 1) qam64_table_offset_im+=1; *jj=*jj+1; - + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } - + break; - + } - + if (dlsch1_harq) { switch (mod_order1) { - + case 2: ((int16_t*)&tmp_sample1)[0] = (x1[*jj2]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; @@ -910,9 +942,9 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } break; - + case 4: - + qam16_table_offset_re = 0; qam16_table_offset_im = 0; @@ -922,20 +954,20 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x1[*jj2] == 1) qam16_table_offset_im+=2; *jj2=*jj2+1; - - + + if (x1[*jj2] == 1) qam16_table_offset_re+=1; *jj2=*jj2+1; if (x1[*jj2] == 1) qam16_table_offset_im+=1; *jj2=*jj2+1; - + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); @@ -943,9 +975,9 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, } break; - + case 6: - + qam64_table_offset_re = 0; qam64_table_offset_im = 0; if (x1[*jj2] == 1) @@ -966,20 +998,20 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, if (x1[*jj2] == 1) qam64_table_offset_im+=1; *jj2=*jj2+1; - + ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im])); ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); - + if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); } - + break; - + } } } @@ -1097,7 +1129,6 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, return(0); } - int allocate_REs_in_RB_MCH(int32_t **txdataF, uint32_t *jj, uint16_t re_offset, @@ -1305,32 +1336,75 @@ int dlsch_modulation(int32_t **txdataF, { uint8_t nsymb; - uint8_t harq_pid = dlsch0->current_harq_pid; - LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid]; + uint8_t harq_pid; //= dlsch0->current_harq_pid; + LTE_DL_eNB_HARQ_t *dlsch0_harq; LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid]; uint32_t i,jj,jj2,re_allocated,symbol_offset; uint16_t l,rb,re_offset; uint32_t rb_alloc_ind; - uint32_t *rb_alloc = dlsch0_harq->rb_alloc; + uint32_t *rb_alloc; //=dlsch0_harq->rb_alloc; + uint8_t pilots=0; uint8_t skip_dc,skip_half; - uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs); + uint8_t mod_order0 = 0; uint8_t mod_order1 = 0; int16_t amp_rho_a, amp_rho_b; int16_t qam16_table_a0[4],qam64_table_a0[8],qam16_table_b0[4],qam64_table_b0[8]; int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8]; int16_t *qam_table_s0,*qam_table_s1; + uint8_t get_pmi_temp; #ifdef DEBUG_DLSCH_MODULATION - uint8_t Nl0 = dlsch0_harq->Nl; + uint8_t Nl0; //= dlsch0_harq->Nl; uint8_t Nl1; #endif - if (dlsch1) { + if ((dlsch0 != NULL) && (dlsch1 != NULL)){ + harq_pid = dlsch0->current_harq_pid; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + mod_order0 = get_Qm(dlsch0_harq->mcs); + rb_alloc = dlsch0_harq->rb_alloc; +#ifdef DEBUG_DLSCH_MODULATION + Nl0 = dlsch0_harq->Nl; +#endif + dlsch1_harq = dlsch1->harq_processes[harq_pid]; mod_order1 = get_Qm(dlsch1_harq->mcs); #ifdef DEBUG_DLSCH_MODULATION Nl1 = dlsch1_harq->Nl; #endif + + }else if ((dlsch0 != NULL) && (dlsch1 == NULL)){ + + harq_pid = dlsch0->current_harq_pid; + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + mod_order0 = get_Qm(dlsch0_harq->mcs); + rb_alloc = dlsch0_harq->rb_alloc; +#ifdef DEBUG_DLSCH_MODULATION + Nl0 = dlsch0_harq->Nl; +#endif + + dlsch1_harq = NULL; + mod_order1 = 0; +#ifdef DEBUG_DLSCH_MODULATION + Nl1 = 0; +#endif + + }else if ((dlsch0 == NULL) && (dlsch1 != NULL)){ + + harq_pid = dlsch1->current_harq_pid; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + mod_order0 = get_Qm(dlsch1_harq->mcs); + rb_alloc = dlsch1_harq->rb_alloc; +#ifdef DEBUG_DLSCH_MODULATION + Nl0 = dlsch1_harq->Nl; +#endif + + dlsch0_harq = NULL; + mod_order1 = 0; +#ifdef DEBUG_DLSCH_MODULATION + Nl1 = NULL; +#endif + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN); @@ -1565,7 +1639,7 @@ int dlsch_modulation(int32_t **txdataF, if (rb_alloc_ind > 0) { // printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj); - + allocate_REs_in_RB(frame_parms, txdataF, &jj, @@ -1640,29 +1714,29 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, amp=1; //we do full scale here for SIC gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15)); //printf("gain=%d\n", gain_lin_QPSK); - + jj = 0; i = 0; while (jj <= G-1) { - + re_allocated = re_allocated + 1; switch (mod_order0) { case 2: //QPSK /* TODO: handle more than 1 antenna */ //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); - + ((int16_t*)&sic_buffer[0][i])[0] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i - + jj = jj + 1; - + ((int16_t*)&sic_buffer[0][i])[1] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1} - + jj = jj + 1; - + //printf("recon %d,%d\n",((int16_t*)&sic_buffer[0][i])[0],((int16_t*)&sic_buffer[0][i])[1]); i++; - + break; case 4: //16QAM @@ -1694,8 +1768,8 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, ((int16_t *)&sic_buffer[0][i])[0]+=qam16_table[qam16_table_offset_re]; ((int16_t *)&sic_buffer[0][i])[1]+=qam16_table[qam16_table_offset_im]; - - i++; + + i++; break; @@ -1737,12 +1811,12 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, ((int16_t *)&sic_buffer[0][i])[0]+=(qam64_table[qam64_table_offset_re])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); ((int16_t *)&sic_buffer[0][i])[1]+=(qam64_table[qam64_table_offset_im])>>1;//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - + i++; - + break; } - + } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 335002a5ea..0b39a3580a 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -161,6 +161,7 @@ int main(int argc, char **argv) uint16_t tdd_config=3; uint16_t n_rnti=0x1234; int n_users = 1; + int TB=0; RX_type_t rx_type=rx_standard; @@ -170,10 +171,10 @@ int main(int argc, char **argv) unsigned char *input_buffer0[2],*input_buffer1[2]; unsigned short input_buffer_length0,input_buffer_length1; - /* A variable "ret" is a nuumber of turbo iterations, that are performed in the turbo-decoder for each CW. + /* A variable "ret" is a nuumber of turbo iterations, that are performed in the turbo-decoder for each CW. The decoder checks CRC, and if CRC test fails, it increments "ret". Ret is between 1 and 4, where 4 is for - the max number of turbo iterations. If the CRC is passed, ret is equal to a current iteration. - This is done separately for each CW inside decoding process. + the max number of turbo iterations. If the CRC is passed, ret is equal to a current iteration. + This is done separately for each CW inside decoding process. Again: this is not a HARQ retransmission!*/ unsigned int ret[2]; unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; @@ -258,6 +259,9 @@ int main(int argc, char **argv) int llr8_flag=0; double effective_rate=0.0; + double thr_cw0_tm4 = 0.0; + double thr_cw0_tm4_nonconst = 0.0; + double thr_cw0[4]={0,0,0,0}, thr_cw1[4]={0,0,0,0}, thr_cw0_tot = 0.0, thr_cw1_tot = 0.0; char channel_model_input[17]="I"; int TB0_active = 1; @@ -356,7 +360,7 @@ int main(int argc, char **argv) common_flag = 1; TPC = atoi(optarg); break; - + case 'E': threequarter_fs=1; break; @@ -427,7 +431,7 @@ int main(int argc, char **argv) case 'w': snr_int = atof(optarg); break; - + case 'N': n_ch_rlz= atof(optarg); break; @@ -455,10 +459,10 @@ int main(int argc, char **argv) case 'E': channel_model=EPA; break; - case 'F': + case 'F': channel_model=EVA; break; - case 'G': + case 'G': channel_model=ETU; break; case 'H': @@ -534,7 +538,7 @@ int main(int argc, char **argv) exit(-1); } break; - + case 'R': num_rounds=atoi(optarg); break; @@ -543,7 +547,7 @@ int main(int argc, char **argv) break; case 'T': n_rnti=atoi(optarg); - break; + break; case 'u': rx_type = (RX_type_t) atoi(optarg); if (rx_typerx_SIC_dual_stream) { @@ -572,7 +576,7 @@ int main(int argc, char **argv) break; case 'V': interf_unaw_shift0=atoi(optarg); - break; + break; case 'W': interf_unaw_shift1=atoi(optarg); break; @@ -608,10 +612,10 @@ int main(int argc, char **argv) printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n"); exit(1); break; - + } } - + if (common_flag == 0) { switch (N_RB_DL) { case 6: @@ -636,7 +640,7 @@ int main(int argc, char **argv) } else NB_RB = 4; - NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); + NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); if ((transmission_mode > 1) && (n_tx != 2)) { @@ -671,12 +675,12 @@ int main(int argc, char **argv) */ } - if (transmission_mode==5) { + if (transmission_mode==5) { n_users = 2; eNB_id_i = PHY_vars_UE->n_connected_eNB; //eNB_id_i=1; } - else + else eNB_id_i = eNB_id; lte_param_init(n_tx, @@ -730,7 +734,7 @@ int main(int argc, char **argv) SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); if(transmission_mode==5) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); - else if (abstx == 1) + else if (abstx == 1) if (perfect_ce==1) sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else @@ -740,7 +744,7 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); - + bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",bler_fname); @@ -749,7 +753,7 @@ int main(int argc, char **argv) fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); if (test_perf != 0) { - + char hostname[1024]; hostname[1023] = '\0'; @@ -766,14 +770,14 @@ int main(int argc, char **argv) exit(-1); } } - + if(abstx){ // CSV file // add here second stream mcs - + if (transmission_mode == 5) sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d_abstr.m",transmission_mode,rx_type,mcs1,channel_model,n_frames,num_rounds); - - else + + else if (perfect_ce==1) sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else @@ -901,7 +905,7 @@ n(tikz_fname,"w"); PHY_vars_UE->transmission_mode[eNB_id]=transmission_mode; if (PHY_vars_UE->transmission_mode[eNB_id] !=4) // add TM3 exception PHY_vars_UE->PHY_measurements.rank[eNB_id]=0; - else + else PHY_vars_UE->PHY_measurements.rank[eNB_id]=1; // Fill in UL_alloc UL_alloc_pdu.type = 0; @@ -911,7 +915,7 @@ n(tikz_fname,"w"); UL_alloc_pdu.ndi = 1; UL_alloc_pdu.TPC = 0; UL_alloc_pdu.cqi_req = 1; - + CCCH_alloc_pdu.type = 0; CCCH_alloc_pdu.vrb_type = 0; CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; @@ -966,7 +970,7 @@ n(tikz_fname,"w"); rx_sample_offset, 0); } - + if (eNB2UE[0]==NULL) { @@ -974,7 +978,7 @@ n(tikz_fname,"w"); exit(-1); } - if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8)) + if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8)) Kmimo=2; else Kmimo=1; @@ -1060,9 +1064,9 @@ n(tikz_fname,"w"); case 1: case 2: if (common_flag == 0) { - + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1_1_5MHz_TDD_t; @@ -1072,7 +1076,7 @@ n(tikz_fname,"w"); ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1084,7 +1088,7 @@ n(tikz_fname,"w"); ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1096,7 +1100,7 @@ n(tikz_fname,"w"); ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1106,7 +1110,7 @@ n(tikz_fname,"w"); ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1_20MHz_TDD_t; @@ -1123,7 +1127,7 @@ n(tikz_fname,"w"); ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1134,7 +1138,7 @@ n(tikz_fname,"w"); ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1145,7 +1149,7 @@ n(tikz_fname,"w"); ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1156,18 +1160,18 @@ n(tikz_fname,"w"); ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; dci_alloc[num_dci].L = 1; dci_alloc[num_dci].rnti = n_rnti+k; dci_alloc[num_dci].format = format1; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, @@ -1187,7 +1191,7 @@ n(tikz_fname,"w"); } else { //common flag =1 if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; @@ -1198,7 +1202,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1211,7 +1215,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1224,7 +1228,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1235,7 +1239,7 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; @@ -1253,7 +1257,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1265,7 +1269,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1277,7 +1281,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1289,11 +1293,11 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -1301,7 +1305,7 @@ n(tikz_fname,"w"); dci_alloc[num_dci].rnti = SI_RNTI; dci_alloc[num_dci].format = format1A; dci_alloc[num_dci].firstCCE = 0; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, @@ -1316,19 +1320,19 @@ n(tikz_fname,"w"); 0, P_RNTI, PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single); - + num_common_dci++; num_dci++; - + } break; case 3: //LARGE CDD if (common_flag == 0) { - + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) {// here DCI does not contain any precoder information. matrix is fixed as identity, but dont forget aboy cycling if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; @@ -1337,10 +1341,10 @@ n(tikz_fname,"w"); ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1352,10 +1356,10 @@ n(tikz_fname,"w"); ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1367,10 +1371,10 @@ n(tikz_fname,"w"); ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1380,10 +1384,10 @@ n(tikz_fname,"w"); ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; @@ -1391,7 +1395,7 @@ n(tikz_fname,"w"); break; } } - + else { // fdd switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: @@ -1400,10 +1404,10 @@ n(tikz_fname,"w"); ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1414,10 +1418,10 @@ n(tikz_fname,"w"); ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1428,10 +1432,10 @@ n(tikz_fname,"w"); ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1442,27 +1446,27 @@ n(tikz_fname,"w"); ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; - } + } } } else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { //4 antenna, needs diff precoding codebook index depeneding on layers } - + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; dci_alloc[num_dci].L = 1; dci_alloc[num_dci].rnti = n_rnti+k; dci_alloc[num_dci].format = format2A; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -1476,13 +1480,13 @@ n(tikz_fname,"w"); 0, P_RNTI, PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single); - + num_dci++; num_ue_spec_dci++; } else { //commonn flag 1 if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { //tdd - + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; @@ -1493,7 +1497,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1506,7 +1510,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1519,7 +1523,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1530,7 +1534,7 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; @@ -1548,7 +1552,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1560,7 +1564,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1572,7 +1576,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1584,11 +1588,11 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -1596,8 +1600,8 @@ n(tikz_fname,"w"); dci_alloc[num_dci].rnti = SI_RNTI; dci_alloc[num_dci].format = format1A; dci_alloc[num_dci].firstCCE = 0; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -1611,33 +1615,33 @@ n(tikz_fname,"w"); 0, P_RNTI, PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single); - + num_common_dci++; num_dci++; - + } printf("Generated DCI format 2A (Transmission Mode 3)\n"); break; case 4: // !!! this dci format contains precoder information if (common_flag == 0) { - + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) { if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; + dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1648,13 +1652,13 @@ n(tikz_fname,"w"); dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1669,10 +1673,10 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1685,10 +1689,10 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1698,7 +1702,7 @@ n(tikz_fname,"w"); break; } } - + else { switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: @@ -1707,10 +1711,10 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1723,10 +1727,10 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1739,10 +1743,10 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1755,36 +1759,36 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; - } + } } } else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { } - - printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); - if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { + + printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); + if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); - + } - + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; dci_alloc[num_dci].L = 1; dci_alloc[num_dci].rnti = n_rnti+k; dci_alloc[num_dci].format = format2; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); - + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -1798,13 +1802,13 @@ n(tikz_fname,"w"); 0, P_RNTI, PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single); - + num_dci++; num_ue_spec_dci++; } else { //common_flag==1 if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; @@ -1815,7 +1819,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1828,7 +1832,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1841,7 +1845,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1852,7 +1856,7 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; @@ -1870,7 +1874,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1882,7 +1886,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1894,7 +1898,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1906,11 +1910,11 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -1918,7 +1922,7 @@ n(tikz_fname,"w"); dci_alloc[num_dci].rnti = SI_RNTI; dci_alloc[num_dci].format = format1A; dci_alloc[num_dci].firstCCE = 0; - dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, @@ -1933,7 +1937,7 @@ n(tikz_fname,"w"); 0, P_RNTI, PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single); - + num_common_dci++; num_dci++; @@ -1985,12 +1989,12 @@ n(tikz_fname,"w"); */ } - if (n_frames==1) + if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE); numCCE = get_nCCE(num_pdcch_symbols,&PHY_vars_eNB->lte_frame_parms,get_mi(&PHY_vars_eNB->lte_frame_parms,subframe)); - if (n_frames==1) + if (n_frames==1) printf("%d\n",numCCE); // apply RNTI-based nCCE allocation @@ -2123,7 +2127,7 @@ n(tikz_fname,"w"); initialize(&time_vector_rx_demod); struct list time_vector_rx_dec; initialize(&time_vector_rx_dec); - + for (trials = 0;trials PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) && - (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations))) || - ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && + (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations))) || + ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) { - + //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); - + if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) round_trials[0][round]++; - + if (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) round_trials[1][round]++; + // printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials TB0 = %d, round_trials TB1 = %d \n",trials,round, ret[0], ret[1], round_trials[0][round], round_trials[1][round]); + /*printf("Trial %d, round cw0 = %d , round cw1 = %d, ret[0] = %d, ret[1] = %d, round_trials cw0 [%d]= %d, round_trials cw1 [%d]= %d\n",trials, round, round, \ ret[0], ret[1], round, round_trials[0][round], round, round_trials[1][round]);*/ //printf("round_trials %d round %d\n", round_trials[round], round); - if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) pmi_feedback=1; - else + else pmi_feedback=0; - + if (abstx) { if (trials==0 && round==0 && SNR==snr0) //generate a new channel hold_channel = 0; @@ -2176,12 +2182,12 @@ n(tikz_fname,"w"); hold_channel = 0;//(round==0) ? 0 : 1; PMI_FEEDBACK: - + //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aalte_frame_parms.nb_antennas_tx;aa++) { memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } - + if (input_fd==NULL) { start_meas(&PHY_vars_eNB->phy_proc_tx); @@ -2189,15 +2195,22 @@ n(tikz_fname,"w"); // Simulate HARQ procedures!!! if (common_flag == 0) { + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; - if (transmission_mode == 3 || transmission_mode == 4) + if (transmission_mode == 3 || transmission_mode == 4) PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rvidx = round&3; - + if (round == 0) { // First round TB0_active = 1; + /* PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + if (transmission_mode == 3 || transmission_mode == 4) + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rvidx = round&3;*/ + + + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { - + switch (transmission_mode) { case 1: case 2: @@ -2257,7 +2270,7 @@ n(tikz_fname,"w"); } break; case 4: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; @@ -2287,8 +2300,8 @@ n(tikz_fname,"w"); memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); break; } - break; - + break; + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; @@ -2356,7 +2369,7 @@ n(tikz_fname,"w"); } break; case 4: - switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; @@ -2386,18 +2399,18 @@ n(tikz_fname,"w"); memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); break; } - break; + break; case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); break; } - + } } - else { - + else { + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { switch (transmission_mode) { case 1: @@ -2437,7 +2450,7 @@ n(tikz_fname,"w"); else { // deactivate TB0 ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); @@ -2499,6 +2512,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2514,6 +2528,8 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + printf("\n Requesting only TB1 from temp DCI\n"); + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2529,6 +2545,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2544,6 +2561,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2553,7 +2571,7 @@ n(tikz_fname,"w"); break; } break; - + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; @@ -2662,6 +2680,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2677,6 +2696,8 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + printf("\n Requesting only TB1 from temp DCI\n"); + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2692,6 +2713,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2707,6 +2729,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2715,9 +2738,9 @@ n(tikz_fname,"w"); memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); break; } - break; - - + break; + + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; @@ -2725,9 +2748,8 @@ n(tikz_fname,"w"); break; } } - } + } } - num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci, num_common_dci, dci_alloc, @@ -2742,120 +2764,113 @@ n(tikz_fname,"w"); exit(-1); } - for (k=0;klte_frame_parms, - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Nl, + for (k=0;kdlsch_eNB[0][TB] == NULL) + continue; + + coded_bits_per_codeword[TB] = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Nl, num_pdcch_symbols, 0,subframe); #ifdef TBS_FIX // This is for MESH operation!!! - tbs[cw] = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][cw]->nb_rb-1]/4; + tbs[TB] = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][TB]->nb_rb-1]/4; #else - tbs[cw] = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->TBS; + tbs[TB] = PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->TBS; #endif - rate[cw] = (double)tbs[cw]/(double)coded_bits_per_codeword[cw]; - + rate[TB] = (double)tbs[TB]/(double)coded_bits_per_codeword[TB]; + if ((SNR == snr0) && (trials == 0) && (round == 0) && (pmi_feedback == 0)) - printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", - k,cw,rate[cw],rate[cw]*get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), - coded_bits_per_codeword[cw], - tbs[cw], - get_Qm(PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->mcs), + printf("User %d, TB %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", + k,TB,rate[TB],rate[TB]*get_Qm(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs), + coded_bits_per_codeword[TB], + tbs[TB], + get_Qm(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs), num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->round); + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->round); // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); - if (n_users>1) - PHY_vars_eNB->dlsch_eNB[1][0]->harq_processes[0]->pmi_alloc = (PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); + if (n_users>1) + PHY_vars_eNB->dlsch_eNB[1][0]->harq_processes[0]->pmi_alloc = (PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); /* if ((trials<10) && (round==0)) { printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[0][0]->pmi_alloc),pmi_feedback); if (transmission_mode ==5) printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[1][0]->pmi_alloc)); } - */ + */ } - - - if (transmission_mode==4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); - PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + + //Here need to add cases for TPMI 6 and TPMI 5 and check for both TB. + if (transmission_mode == 4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); } - - - start_meas(&PHY_vars_eNB->dlsch_encoding_stats); - if (dlsch_encoding(((cw==0) ? input_buffer0[k] : input_buffer1[k]), + + + start_meas(&PHY_vars_eNB->dlsch_encoding_stats); + if (dlsch_encoding(((TB==0) ? input_buffer0[k] : input_buffer1[k]), &PHY_vars_eNB->lte_frame_parms, num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][cw], + PHY_vars_eNB->dlsch_eNB[k][TB], 0,subframe, &PHY_vars_eNB->dlsch_rate_matching_stats, &PHY_vars_eNB->dlsch_turbo_encoding_stats, &PHY_vars_eNB->dlsch_interleaving_stats)<0) exit(-1); - stop_meas(&PHY_vars_eNB->dlsch_encoding_stats); + stop_meas(&PHY_vars_eNB->dlsch_encoding_stats); - PHY_vars_eNB->dlsch_eNB[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; - start_meas(&PHY_vars_eNB->dlsch_scrambling_stats); + PHY_vars_eNB->dlsch_eNB[k][TB]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; + start_meas(&PHY_vars_eNB->dlsch_scrambling_stats); dlsch_scrambling(&PHY_vars_eNB->lte_frame_parms, - 0, - PHY_vars_eNB->dlsch_eNB[k][cw], - coded_bits_per_codeword[cw], - cw, - subframe<<1); - stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); + 0, + PHY_vars_eNB->dlsch_eNB[k][TB], + coded_bits_per_codeword[TB], + TB, + subframe<<1); + stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); if (n_frames==1) { - for (s=0;sdlsch_eNB[k][cw]->harq_processes[0]->C;s++) { - if (sdlsch_eNB[k][cw]->harq_processes[0]->Cminus) - Kr = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Kminus; + for (s=0;sdlsch_eNB[k][TB]->harq_processes[0]->C;s++) { + if (sdlsch_eNB[k][TB]->harq_processes[0]->Cminus) + Kr = PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Kminus; else - Kr = PHY_vars_eNB->dlsch_eNB[k][cw]->harq_processes[0]->Kplus; - + Kr = PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; - - // for (i=0;idlsch_eNB[k][cw]->harq_processes[0]->c[s][i]); } } } - - start_meas(&PHY_vars_eNB->dlsch_modulation_stats); + + start_meas(&PHY_vars_eNB->dlsch_modulation_stats); re_allocated = dlsch_modulation(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], AMP, subframe, &PHY_vars_eNB->lte_frame_parms, num_pdcch_symbols, PHY_vars_eNB->dlsch_eNB[k][0], - PHY_vars_eNB->dlsch_eNB[k][1] - ); - stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); - /* - if (trials==0 && round==0) - printf("RE count %d\n",re_allocated); - */ + PHY_vars_eNB->dlsch_eNB[k][1]); + stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); } //n_users - generate_pilots(PHY_vars_eNB, PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - + start_meas(&PHY_vars_eNB->ofdm_mod_stats); - + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], (subframe*2), @@ -2865,10 +2880,10 @@ n(tikz_fname,"w"); PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], (subframe*2)+1, &PHY_vars_eNB->lte_frame_parms); - + stop_meas(&PHY_vars_eNB->ofdm_mod_stats); - stop_meas(&PHY_vars_eNB->phy_proc_tx); - + stop_meas(&PHY_vars_eNB->phy_proc_tx); + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], (subframe*2)+2, @@ -2887,11 +2902,24 @@ n(tikz_fname,"w"); PHY_vars_eNB->lte_frame_parms.samples_per_tti); } tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - + + if (n_frames==1) { + write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) + write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + } + + tx_lev = 0; + for (aa=0; aalte_frame_parms.nb_antennas_tx; aa++) { + tx_lev += signal_energy(&PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa] + [subframe*PHY_vars_eNB->lte_frame_parms.samples_per_tti], + PHY_vars_eNB->lte_frame_parms.samples_per_tti); + } + tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + if (n_frames==1) { printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); - write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti], - PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1); + write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti], PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1); } } /* @@ -2899,7 +2927,7 @@ n(tikz_fname,"w"); i=0; while (!feof(input_fd)) { fscanf(input_fd,"%s %s",input_val_str,input_val_str2); - + if ((i%4)==0) { ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); @@ -2918,7 +2946,7 @@ n(tikz_fname,"w"); tx_lev_dB = (unsigned int) dB_fixed(tx_lev); } */ - + // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,awgn_flag); for (i=0;i<2*frame_parms->samples_per_tti;i++) { for (aa=0;aalte_frame_parms.nb_antennas_tx;aa++) { @@ -2937,7 +2965,7 @@ n(tikz_fname,"w"); //printf("r_im0 = %d\n",r_im[0][i]); //printf("r_re1 = %d\n",r_re[1][i]); //printf("r_im1 = %d\n",r_im[1][i]); - + } else { for (aarx=0;aarxlte_frame_parms.nb_antennas_rx;aarx++) { @@ -2956,8 +2984,8 @@ n(tikz_fname,"w"); } // Multipath channel - if (awgn_flag == 0) { - multipath_channel(eNB2UE[round+round],s_re,s_im,r_re,r_im, + if (awgn_flag == 0) { + multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, 2*frame_parms->samples_per_tti,hold_channel); // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); if(abstx==1 && num_rounds>1) @@ -2967,7 +2995,7 @@ n(tikz_fname,"w"); random_channel(eNB2UE[3],0); } if (PHY_vars_UE->perfect_ce==1){ - freq_channel(eNB2UE[round+round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); } @@ -2979,7 +3007,7 @@ n(tikz_fname,"w"); freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1); // snr=pow(10.0,.1*SNR); fprintf(csv_fd,"%f,",SNR); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -2989,10 +3017,10 @@ n(tikz_fname,"w"); } } } - + if(num_rounds>1){ freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -3003,7 +3031,7 @@ n(tikz_fname,"w"); } } freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -3013,9 +3041,9 @@ n(tikz_fname,"w"); } } } - + freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -3028,28 +3056,28 @@ n(tikz_fname,"w"); } } } - + //AWGN // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated); sigma2 = pow(10,sigma2_dB/10); if (n_frames==1) printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated)); - + for (i=0; i<2*frame_parms->samples_per_tti; i++) { for (aa=0;aalte_frame_parms.nb_antennas_rx;aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); - ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] = + ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i+1] = + ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i+1] = (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); } - } - + } + // lte_sync_time_init(PHY_vars_eNB->lte_frame_parms,lte_ue_common_vars); // lte_sync_time(lte_ue_common_vars->rxdata, PHY_vars_eNB->lte_frame_parms); // lte_sync_time_free(); - + /* // optional: read rx_frame from file if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL) @@ -3057,22 +3085,22 @@ n(tikz_fname,"w"); printf("Cannot open rx_frame.m data file\n"); exit(0); } - + result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); printf("Read %d bytes\n",result); result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); printf("Read %d bytes\n",result); - + fclose(rx_frame_file); */ - + if (n_frames==1) { printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); } - + if (PHY_vars_eNB->lte_frame_parms.Ncp == 0) { // normal prefix pilot1 = 4; pilot2 = 7; @@ -3082,8 +3110,8 @@ n(tikz_fname,"w"); pilot1 = 3; pilot2 = 6; pilot3 = 9; - } - + } + start_meas(&PHY_vars_UE->phy_proc_rx); // Inner receiver scheduling for 3 slots for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) { @@ -3092,17 +3120,17 @@ n(tikz_fname,"w"); printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2); /* This function implements the OFDM front end processor (FEP). - + Parameters: frame_parms LTE DL Frame Parameters ue_common_vars LTE UE Common Vars l symbol within slot (0..6/7) Ns Slot number (0..19) sample_offset offset within rxdata (points to beginning of subframe) - no_prefix if 1 prefix is removed by HW - + no_prefix if 1 prefix is removed by HW + */ - + start_meas(&PHY_vars_UE->ofdm_demod_stats); slot_fep(PHY_vars_UE, l, @@ -3119,9 +3147,9 @@ n(tikz_fname,"w"); for (aarx=0; aarxnb_antennas_rx; aarx++) { for (i=0; iN_RB_DL*12; i++) { ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= - (int16_t)(eNB2UE[round+round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= - (int16_t)(eNB2UE[round+round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); } } } @@ -3143,14 +3171,14 @@ n(tikz_fname,"w"); for (aarx=0; aarxnb_antennas_rx; aarx++) { for (i=0; iN_RB_DL*12; i++) { ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; } } } } } } - + if ((Ns==((2*subframe))) && (l==0)) { lte_ue_measurements(PHY_vars_UE, subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti, @@ -3215,7 +3243,7 @@ n(tikz_fname,"w"); eNB_id, subframe); printf("dci_cnt %d\n",dci_cnt); - + if (dci_cnt==0) { dlsch_active = 0; if (round==0) { @@ -3227,7 +3255,7 @@ n(tikz_fname,"w"); printf("DCI error trial %d errs[0][0] %d\n",trials,errs[0][0]); } } - + for (i=0;idlsch_ue[0][1]->harq_processes[0]->first_tx=1; } - if ((dci_alloc_rx[i].rnti == n_rnti) && + if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, subframe, dci_alloc_rx[i].dci_pdu, @@ -3281,9 +3309,9 @@ n(tikz_fname,"w"); errs[0][0]++; round=5; - if (n_frames==1) + if (n_frames==1) printf("DCI misdetection trial %d\n",trials); - + } } } @@ -3329,7 +3357,7 @@ n(tikz_fname,"w"); break; case 4: generate_ue_dlsch_params_from_dci(0, - subframe, + subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A,//format1A only for a codeblock @@ -3373,7 +3401,7 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_llr_stats); - + for (m=PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols; mdlsch_llr_stats); } - - if ((Ns==(1+(2*subframe))) && (l==pilot1)){// process symbols (6 Extended Prefix),7,8,9 + + if ((Ns==(1+(2*subframe))) && (l==pilot1)){// process symbols (6 Extended Prefix),7,8,9 start_meas(&PHY_vars_UE->dlsch_llr_stats); for (m=pilot2;mdlsch_llr_stats); } - + if ((Ns==(2+(2*subframe))) && (l==0)) { // process symbols 10,11,(12,13 Normal Prefix) do deinterleaving for TTI start_meas(&PHY_vars_UE->dlsch_llr_stats); for (m=pilot3; mlte_frame_parms.symbols_per_tti; m++) { @@ -3446,122 +3474,124 @@ n(tikz_fname,"w"); } } } - - if (rx_type==rx_SIC_dual_stream){ + + /*if (rx_type==rx_SIC_dual_stream){ cw_to_decode_interf=1; cw_to_decode_interf_free=1; } else { - cw_to_decode_interf=Kmimo; - } - - for (cw_non_sic=0; cw_non_sicdlsch_ue[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword[cw_non_sic] = get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->Nl, + for (TB=0; TBdlsch_ue[0][TB] == NULL) + continue; + + PHY_vars_UE->dlsch_ue[0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword[TB] = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->Nl, num_pdcch_symbols, 0,subframe); - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_non_sic]; - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->mcs); - + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs); + if (n_frames==1) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword[cw_non_sic], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->TBS); - + printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->TBS); + // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_non_sic]); + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - - sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_non_sic); - sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword[cw_non_sic],1,0); - sprintf(fname,"dlsch_cw%d_e.m", cw_non_sic); - sprintf(vname,"dlschcw%d_e", cw_non_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_non_sic],1,4); + + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); + sprintf(fname,"dlsch_cw%d_e.m", TB); + sprintf(vname,"dlschcw%d_e", TB); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4); uncoded_ber=0; printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_non_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_non_sic][i]<0)) { + for (i=0;idlsch_eNB[0][TB]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } else uncoded_ber_bit[i] = 0; - - uncoded_ber/=coded_bits_per_codeword[cw_non_sic]; + + uncoded_ber/=coded_bits_per_codeword[TB]; avg_ber += uncoded_ber; - sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_non_sic); - sprintf(vname,"uncoded_ber_bit_cw%d", cw_non_sic); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[cw_non_sic],1,0); - printf("cw %d, uncoded ber %f\n",cw_non_sic,uncoded_ber); - + sprintf(fname,"cw%d_uncoded_ber_bit.m", TB); + sprintf(vname,"uncoded_ber_bit_cw%d", TB); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[TB],1,0); + printf("cw %d, uncoded ber %f\n",TB,uncoded_ber); + free(uncoded_ber_bit); - uncoded_ber_bit = NULL; + uncoded_ber_bit = NULL; } - start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, 0, - PHY_vars_UE->dlsch_ue[0][cw_non_sic], - coded_bits_per_codeword[cw_non_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], - cw_non_sic, + PHY_vars_UE->dlsch_ue[0][TB], + coded_bits_per_codeword[TB], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword], + TB, subframe<<1); - stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); - ret[cw_non_sic] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_non_sic], + ret[TB] = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[TB], &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw_non_sic], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid], + PHY_vars_UE->dlsch_ue[0][TB], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid], subframe, - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid, + PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid, 1,llr8_flag); - stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); //printf("retr cw 0 = %d\n", ret[0]); //printf("current round = %d\n", PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->round); - - - if (ret[cw_non_sic] <= PHY_vars_UE->dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 - - if (cw_non_sic==0) { - avg_iter[0] += ret[0]; - iter_trials[0]++; - } - + + + if (ret[TB] <= PHY_vars_UE->dlsch_ue[0][TB]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 + + + /*avg_iter[TB] += ret[TB]; + iter_trials[TB]++;*/ + if (n_frames==2) { - printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); - #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; + printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][TB]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][TB]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kminus; else - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; - + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kplus; + Kr_bytes = Kr>>3; - + printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->c[s][i]); } - #endif +#endif } - - PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][cw_non_sic]->current_harq_pid]->TBS; - // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER + PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][TB]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][TB]->current_harq_pid]->TBS; + + // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) if (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* @@ -3577,15 +3607,15 @@ n(tikz_fname,"w"); dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; dlsch0_eNB_harq->round = dlsch0_ue_harq->round; - + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - + dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, &PHY_vars_UE->lte_frame_parms, num_pdcch_symbols, @@ -3595,7 +3625,7 @@ n(tikz_fname,"w"); &PHY_vars_UE->dlsch_turbo_encoding_stats, &PHY_vars_UE->dlsch_interleaving_stats ); - + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, @@ -3603,8 +3633,8 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, num_pdcch_symbols, 0,subframe); - - + + //scrambling dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, 0, @@ -3612,8 +3642,8 @@ n(tikz_fname,"w"); coded_bits_per_codeword, 0, subframe<<1); - - + + //modulation re_allocated = dlsch_modulation(sic_buffer, AMP, @@ -3627,7 +3657,7 @@ n(tikz_fname,"w"); // compute the norm of the effective channel for both receive antennas -> alphha[0], alphha[2] // multiply with the norm of the effective channnel */ - + //stripping (from matched filter output of first stream = rxdataF_comp0) // this is pseudocode /* @@ -3635,8 +3665,8 @@ n(tikz_fname,"w"); PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext[i] -= alpha[i].*sic_buffer[i]; } */ - - //apply rho to output + + //apply rho to output /* dlsch_channel_compensation(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext, PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].dl_ch_rho_ext[harq_pid][round], @@ -3654,22 +3684,26 @@ n(tikz_fname,"w"); */ - //detection of second stream + //detection of second stream //} - + } - + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && rx_type==rx_SIC_dual_stream) { // printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round); + + //printf("\n CW 0 is decoded, i go for , round %d\n", round); + //printf("\n ret[TB0] = %d round %d\n", ret[TB], round); + for (round_sic = 0 ; round_sic < (round +1); round_sic++) { //printf("I enter round_sic loop \n"); //printf("round_sic= %d\n", round_sic); dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - + dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; @@ -3680,11 +3714,11 @@ n(tikz_fname,"w"); dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; - + dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, &PHY_vars_UE->lte_frame_parms, num_pdcch_symbols, @@ -3694,9 +3728,9 @@ n(tikz_fname,"w"); &PHY_vars_UE->dlsch_rate_matching_stats, &PHY_vars_UE->dlsch_turbo_encoding_stats, &PHY_vars_UE->dlsch_interleaving_stats); - - - coded_bits_per_codeword[cw_non_sic]= get_G(&PHY_vars_UE->lte_frame_parms, + + + coded_bits_per_codeword[TB]= get_G(&PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), @@ -3708,7 +3742,7 @@ n(tikz_fname,"w"); dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, 0, PHY_vars_UE->dlsch_eNB[eNB_id], - coded_bits_per_codeword[cw_non_sic], + coded_bits_per_codeword[TB], 0, subframe<<1); @@ -3718,241 +3752,236 @@ n(tikz_fname,"w"); num_pdcch_symbols, &PHY_vars_UE->dlsch_eNB[0][0], NULL, - coded_bits_per_codeword[cw_non_sic]); - + coded_bits_per_codeword[TB]); + // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ - + switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->mcs)){ + case 2: dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], num_pdcch_symbols, dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); + get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][TB]); break; case 4: dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), PHY_vars_UE->dlsch_ue[eNB_id][0]); break; case 6: dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][0]); + get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][TB]); break; } } - + // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); - - for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch_ue[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword[cw_sic]= get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->Nl, + + // replace cw_sic with TB+1 + PHY_vars_UE->dlsch_ue[0][TB+1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword[TB+1]= get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->Nl, num_pdcch_symbols, 0, subframe); - - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_sic]; - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->mcs); - + + PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->G = coded_bits_per_codeword[TB+1]; + PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->mcs); + if (n_frames==1) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword[cw_sic], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid]->TBS); - + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,TB+1,coded_bits_per_codeword[TB+1], + PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->TBS); + // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_sic]); + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB+1]); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_sic); - sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_sic); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic],coded_bits_per_codeword[cw_sic],1,0); - sprintf(fname,"dlsch_cw%d_e.m", cw_sic); - sprintf(vname,"dlschcw%d_e", cw_sic); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_sic],1,4); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB+1); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB+1); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[TB+1],coded_bits_per_codeword[TB+1],1,0); + sprintf(fname,"dlsch_cw%d_e.m", TB+1); + sprintf(vname,"dlschcw%d_e", TB+1); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->e,coded_bits_per_codeword[TB+1],1,4); uncoded_ber=0; printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][cw_sic]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[cw_sic][i]<0)) { + for (i=0;idlsch_eNB[0][TB+1]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; - } + } else uncoded_ber_bit[i] = 0; - - uncoded_ber/=coded_bits_per_codeword[cw_sic]; + + uncoded_ber/=coded_bits_per_codeword[TB+1]; avg_ber += uncoded_ber; - sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); - sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[cw_sic],1,0); - printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); + sprintf(fname,"cw%d_uncoded_ber_bit.m", TB+1); + sprintf(vname,"uncoded_ber_bit_cw%d", TB+1); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[TB+1],1,0); + printf("cw %d, uncoded ber %f\n",TB+1,uncoded_ber); free(uncoded_ber_bit); - uncoded_ber_bit = NULL; + uncoded_ber_bit = NULL; } start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, 0, - PHY_vars_UE->dlsch_ue[0][cw_sic], - coded_bits_per_codeword[cw_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], - cw_sic, + PHY_vars_UE->dlsch_ue[0][TB+1], + coded_bits_per_codeword[TB+1], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], + TB+1, subframe<<1); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); ret[1] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[cw_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][cw_sic], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid], + PHY_vars_UE->dlsch_ue[0][TB+1], + PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid], subframe, - PHY_vars_UE->dlsch_ue[0][cw_sic]->current_harq_pid, + PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid, 1,llr8_flag); - stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + + //printf("ret TB 1 = %d round %d \n", ret[1], round); + + if (ret[TB+1] <= PHY_vars_UE->dlsch_ue[0][TB+1]->max_turbo_iterations ) { + + avg_iter[TB+1] += ret[TB+1]; + iter_trials[TB+1]++; + - // printf("retr cw 1 = %d\n", ret[1]); - - if (ret[1] <= PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) { - - avg_iter[1] += ret[1]; - iter_trials[1]++; - - if (n_frames==1) { - printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); - + printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB+1,round,uncoded_ber); + #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; + for (s=0;sdlsch_ue[0][TB+1]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][TB+1]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kminus; else - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; + Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; - + printf("Decoded_output (Segment %d):\n",s); - + for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->c[s][i]); } #endif - } - - } - else { - errs[cw_sic][round]++; - // exit(0); - - if (cw_sic==1) { - avg_iter[1] += ret[1]-1; - iter_trials[1]++; } - - if (n_frames==2) { - //if ((n_frames==1) || (SNR>=30)) { - printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); - #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_sic]->harq_processes[0]->c[s][i]); - } - #endif + } else{ + errs[TB+1][round]++; + // exit(0); + + avg_iter[TB+1] += ret[TB+1]-1; + iter_trials[TB+1]++; + + if (n_frames==1) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",TB+1,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][TB+1]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][TB+1]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][TB+1]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->c[s][i]); + } +#endif } //n_frames==1 // exit(0); - } //if (ret > PHY_vars_UE->dlsch_ue[0][cw_sic]->max_turbo_iterations ) - } //for (int cw_1=cw_to_decode_interf_free; cw_1dlsch_ue[0][cw_non_sic]->max_turbo_iterations ) - else { - errs[cw_non_sic][round]++; - - if (cw_non_sic==0) { + } //if (ret > PHY_vars_UE->dlsch_ue[0][TB+1]->max_turbo_iterations ) + }//if SIC + } else { + + errs[TB][round]++; + + + /*if (cw_non_sic==0) { avg_iter[0] += ret[0]-1; iter_trials[0]++; + }*/ + + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + (rx_type==rx_SIC_dual_stream)) { + errs[TB+1][round]++; } - - if (rx_type==rx_SIC_dual_stream) { - errs[1][round]++; - } - - if (cw_non_sic==1) { + + /*if (cw_non_sic==1) { avg_iter[1] += ret[1]-1; iter_trials[1]++; - } - - + }*/ + + if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { - printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); - #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][cw_non_sic]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][cw_non_sic]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kminus; - else - Kr = PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->Kplus; - - Kr_bytes = Kr>>3; - - printf("Decoded_output (Segment %d):\n",s); - for (i=0;idlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][cw_non_sic]->harq_processes[0]->c[s][i]); - } - #endif + printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][TB]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][TB]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][TB]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->c[s][i]); + } +#endif } } + TB++; // to terminate the loop over TB } - + stop_meas(&PHY_vars_UE->phy_proc_rx); - + if (n_frames==1) { //rxsig @@ -4024,25 +4053,26 @@ n(tikz_fname,"w"); //pdcch_vars write_output("pdcchF0_ext.m","pdcchF_ext", PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,1,1); write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); write_output("pdcch_rxF_llr.m","pdcch_llr",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->llr,2400,1,4); - - + + if (round == 3) exit(-1); } if (xforms==1) { - phy_scope_UE(form_ue, + phy_scope_UE(form_ue, PHY_vars_UE, eNB_id, 0,// UE_id - subframe); + subframe); } - - + + if ((transmission_mode != 3 && transmission_mode !=4 ) && ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + //printf("flag 1 \n"); round++; } @@ -4052,51 +4082,56 @@ n(tikz_fname,"w"); round++; resend_cw0_cw1=1; //resend both cws resend_cw1=0; - + TB0_active=1; + //printf("flag 2 \n"); + } if ((transmission_mode == 3 || transmission_mode == 4 ) && (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) && (ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ resend_one[round]++; round++; resend_cw0_cw1=0; - resend_cw1=1; //resend only cw1, alamouti - + TB0_active=0; + //PHY_vars_UE->PHY_measurements.rank[eNB_id]=0; + // printf("\n DLSIM TB0 disactivated\n"); + //printf("flag 3 \n"); + } } - //} //round + if(transmission_mode != 3 && transmission_mode !=4 ){ if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) break; - } + } //len = chbch_stats_read(stats_buffer,NULL,0,4096); //printf("%s\n\n",stats_buffer); - + if (PHY_vars_UE->frame_rx % 10 == 0) { PHY_vars_UE->bitrate[eNB_id] = (PHY_vars_UE->total_TBS[eNB_id] - PHY_vars_UE->total_TBS_last[eNB_id])*10; LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",PHY_vars_UE->Mod_id,PHY_vars_UE->total_TBS[eNB_id],PHY_vars_UE->total_TBS_last[eNB_id],PHY_vars_UE->bitrate[eNB_id]/1000); PHY_vars_UE->total_TBS_last[eNB_id] = PHY_vars_UE->total_TBS[eNB_id]; } - + PHY_vars_UE->frame_rx++; - - /* calculate the total processing time for each packet, + + /* calculate the total processing time for each packet, * get the max, min, and number of packets that exceed t>2000us */ - double t_tx = (double)PHY_vars_eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)PHY_vars_eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)PHY_vars_eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)PHY_vars_eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - - - double t_rx = (double)PHY_vars_UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)PHY_vars_UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)PHY_vars_UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)PHY_vars_UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; - + double t_tx = (double)PHY_vars_eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; + double t_tx_ifft = (double)PHY_vars_eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_mod = (double)PHY_vars_eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_enc = (double)PHY_vars_eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; + + + double t_rx = (double)PHY_vars_UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)PHY_vars_UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_demod = (double)PHY_vars_UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_dec = (double)PHY_vars_UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + if (t_tx > t_tx_max) t_tx_max = t_tx; if (t_tx < t_tx_min) @@ -4109,13 +4144,13 @@ n(tikz_fname,"w"); n_tx_dropped++; if (t_rx > 2000) n_rx_dropped++; - + push_front(&time_vector_tx, t_tx); push_front(&time_vector_tx_ifft, t_tx_ifft); push_front(&time_vector_tx_mod, t_tx_mod); push_front(&time_vector_tx_enc, t_tx_enc); - + push_front(&time_vector_rx, t_rx); push_front(&time_vector_rx_fft, t_rx_fft); push_front(&time_vector_rx_demod, t_rx_demod); @@ -4123,8 +4158,8 @@ n(tikz_fname,"w"); } //trials - printf("both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); - printf("one failed round 0 = %d, one failed round 1 = %d, one failed round 2 = %d, one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); + printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); + printf(" one failed round 0 = %d, one failed round 1 = %d, one failed round 2 = %d, one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); // round_trials[0]: number of code word : goodput the protocol double table_tx[time_vector_tx.size]; @@ -4221,13 +4256,72 @@ n(tikz_fname,"w"); ((double)(round_trials[1][0])/((double)round_trials[1][0] + round_trials[1][1] + round_trials[1][2] + round_trials[1][3])); } + /* + Here we compute throughput per cw based on the formula + T=P_suc[r1]R(mcs) + sum[r=2 ..r=4] (P_(suc r, fail r-1)*R/r). + The non-constr formula should not be used, when there are some errors on the last round, + meaning when not all the packages are finally decoded. + */ + + if (transmission_mode == 3 || transmission_mode == 4) { + // FOR CW0 + thr_cw0[0] = rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])); + thr_cw0[1] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/2)*(((double)errs[0][0] - (double)errs[0][1])/(double)round_trials[0][0]); + thr_cw0[2] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/3)*(((double)errs[0][1] - (double)errs[0][2])/(double)round_trials[0][0]); + thr_cw0[3] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/4)*(((double)errs[0][2] - (double)errs[0][3])/(double)round_trials[0][0]); + thr_cw0_tot = (double)thr_cw0[0]+(double)thr_cw0[1]+(double)thr_cw0[2]+(double)thr_cw0[3]; + printf("\n Throughput cw0 sum = %f \n", thr_cw0_tot); + printf("round_trials = %d, errs[0][0] = %d, round_trials[0][1] = %d, errs[0][1] = %d, round_trials[0][2] = %d, errs[0][2] = %d, \ + round_trials[0][3] = %d, errs[0][3] = %d \n", round_trials[0][0], errs[0][0],round_trials[0][1], errs[0][1], round_trials[0][2], \ + errs[0][2], round_trials[0][3], errs[0][3]); + + thr_cw1[0] = rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])); + thr_cw1[1] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]); + thr_cw1[2] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/3)*(((double)errs[1][1] - (double)errs[1][2])/(double)round_trials[1][0]); + thr_cw1[3] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/4)*(((double)errs[1][2] - (double)errs[1][3])/(double)round_trials[1][0]); + thr_cw1_tot = (double)thr_cw1[0]+(double)thr_cw1[1]+(double)thr_cw1[2]+(double)thr_cw1[3]; + printf("Throughput cw1 sum = %f \n", thr_cw1_tot); + printf("Throughput cw1 round 0 = %f \n", thr_cw1[0]); + printf("Throughput cw1 round 1 = %f \n", thr_cw1[1]); + printf("Throughput cw1 round 2 = %f \n", thr_cw1[2]); + printf("Throughput cw1 round 3 = %f \n", thr_cw1[3]); + printf("round_trials[1][0] = %d, errs[1][0] = %d, round_trials[1][1] = %d, errs[1][1] = %d, round_trials[1][2] = %d, errs[1][2] = %d, \ + round_trials[1][3] = %d, errs[1][3] = %d \n", round_trials[1][0], errs[1][0], round_trials[1][1], errs[1][1], round_trials[1][2], \ + errs[1][2], round_trials[1][3], errs[1][3]); + } + +#if 0 + thr_cw0_tm4_nonconst = rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)* \ + ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3])); + printf("Throughput cw0 noncnstr = %f \n", thr_cw0_tm4_nonconst); +#endif + //FOR CW1 + /*thr_cw1[0] = rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])) \ + *(1-((double)errs[1][0]/(double)round_trials[1][0])); + printf("thr cw1 round 0 = %f\n", thr_cw1[0]); + thr_cw1[1]=(rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/2)*\ + (((double)errs[1][0]-(double)errs[1][1])*((double)round_trials[0][0] - (double)errs[0][1])/((double)round_trials[0][0]*(double)round_trials[1][0])); + printf("thr cw1 round 1 = %f\n", thr_cw1[1]); + thr_cw1[2] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/3)*\ + ((double)errs[1][1]-(double)errs[1][2])*((double)round_trials[0][0]-(double)errs[0][2])/((double)round_trials[0][0]*(double)round_trials[1][0]); + printf("thr cw1 round 2 = %f\n", thr_cw1[2]); + thr_cw1[3] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/4)*\ + ((double)errs[1][2]-(double)errs[1][3])*((double)round_trials[0][0] - (double)errs[0][3])/((double)round_trials[0][0]*(double)round_trials[1][0]); + resid_errs= + printf("thr cw1 round 3 = %f\n", thr_cw1[3]); + thr_cw1_tot =thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+thr_cw1[3]; + printf("Throughput cw1 sum = %f \n", thr_cw1_tot); + printf("round_trials = %d, errs[1][0] = %d, round_trials[1][1] = %d, errs[1][1] = %d, round_trials[1][2] = %d, errs[1][2] = %d, \ + round_trials[1][3] = %d, errs[1][3] = %d \n", round_trials[1][0], errs[1][0],round_trials[1][1], errs[1][1], round_trials[1][2], \ + errs[1][2], round_trials[1][3], errs[1][3]); + }*/ printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n", SNR, (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), sigma2_dB); - + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e))," "dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f), " "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n", @@ -4262,14 +4356,19 @@ n(tikz_fname,"w"); 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) +4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]), - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])), - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0][1])), - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0]))+ - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0][1])), + thr_cw0_tot, + thr_cw1_tot, + thr_cw0_tot + thr_cw1_tot, rate[0], rate[1]); - - + + + + + + + + if (print_perf==1) { printf("eNB TX function statistics (per 1ms subframe)\n\n"); @@ -4417,19 +4516,19 @@ n(tikz_fname,"w"); rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])), dci_errors); } - + if(abstx){ //ABSTRACTION - if ((transmission_mode != 3)&& (transmission_mode != 4)) { + if ((transmission_mode != 3)&& (transmission_mode != 4)) { blerr[0][0] = (double)errs[0][0]/(round_trials[0][0]); - + if(num_rounds>1){ blerr[0][1] = (double)errs[0][1]/(round_trials[0][1]); - + blerr[0][2] = (double)errs[0][2]/(round_trials[0][2]); - + blerr[0][3] = (double)errs[0][3]/(round_trials[0][3]); - + fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]); } else { @@ -4453,7 +4552,7 @@ n(tikz_fname,"w"); } } } - + if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); if ((transmission_mode != 3) && (transmission_mode != 4)) { @@ -4515,7 +4614,7 @@ n(tikz_fname,"w"); errs[0][3], round_trials[0][3], dci_errors); - + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", SNR, @@ -4545,7 +4644,7 @@ n(tikz_fname,"w"); (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])); } //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", - fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", + fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", PHY_vars_eNB->phy_proc_tx.trials, PHY_vars_eNB->ofdm_mod_stats.trials, PHY_vars_eNB->dlsch_modulation_stats.trials, @@ -4573,31 +4672,31 @@ n(tikz_fname,"w"); ); //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); - + //fprintf(time_meas_fd,"IFFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - + //fprintf(time_meas_fd,"MOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - + //fprintf(time_meas_fd,"ENC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - - + + //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); //fprintf(time_meas_fd,"FFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - + //fprintf(time_meas_fd,"DEMOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); - + //fprintf(time_meas_fd,"DEC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - - /* + + /* fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", PHY_vars_eNB->phy_proc_tx.trials, PHY_vars_eNB->ofdm_mod_stats.trials, @@ -4622,34 +4721,34 @@ n(tikz_fname,"w"); if (((double)errs[0][0]/(round_trials[0][0]))<1e-2 && ((double)errs[1][0]/(round_trials[1][0]))<1e-2) break; } - else{ - if (((double)errs[0][0]/(round_trials[0][0]))<1e-2) + else{ + if (((double)errs[0][0]/(round_trials[0][0]))<1e-2) break; - + } } else { - + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { if (((double)errs[0][0]/(round_trials[0][0]))<1e-3 && ((double)errs[1][0]/(round_trials[1][0]))<1e-3) break; } - else{ - if (((double)errs[0][0]/(round_trials[0][0]))<1e-3) + else{ + if (((double)errs[0][0]/(round_trials[0][0]))<1e-3) break; - + } - + } - - + + if (n_frames==1) break; }// SNR - + } //ch_realization - + fclose(bler_fd); if (test_perf !=0) From 9c65225869e761f7cbb62fc71fa5465111fead39 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 16 Nov 2016 16:20:00 +0100 Subject: [PATCH 113/571] Full Support for TM4 HARQ, excpept for PUSCH precoder at this moment. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 55 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 1419 +++++++++-------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 40 +- openair1/PHY/LTE_TRANSPORT/power_control.c | 48 +- openair1/PHY/LTE_TRANSPORT/proto.h | 185 +-- openair1/PHY/defs.h | 2 +- openair1/PHY/impl_defs_lte.h | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 599 +++---- openair1/SIMULATION/TOOLS/random_channel.c | 980 ++++++------ openair1/SIMULATION/TOOLS/rangen_double.c | 25 +- openair1/SIMULATION/TOOLS/taus.c | 33 +- 11 files changed, 1769 insertions(+), 1619 deletions(-) mode change 100755 => 100644 openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 0da47dbdff..d044ea45d8 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -44,6 +44,7 @@ #include "PHY/vars.h" #endif #include "assertions.h" +//#define DEBUG_HARQ //#define DEBUG_DCI @@ -1525,7 +1526,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch1_harq->status = ACTIVE; dlsch0_harq->codeword=0; dlsch1_harq->codeword=1; +#ifdef DEBUG_HARQ printf("\n ENB: BOTH ACTIVE\n"); +#endif } else if (TB0_active && TB1_active && tbswap==1) { dlsch0=dlsch[0]; @@ -1564,7 +1567,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch1_harq->codeword = 0; dlsch0=NULL; dlsch0_harq = NULL; +#ifdef DEBUG_HARQ printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); +#endif } if (dlsch0 != NULL){ @@ -2800,8 +2805,15 @@ int generate_eNB_dlsch_params_from_dci(int frame, #endif // compute DL power control parameters + if (dlsch0 != NULL){ computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off); +} + if (dlsch1 != NULL){ + computeRhoA_eNB(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); + computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[1],dlsch1_harq->dl_power_off); + } + return(0); } @@ -4879,6 +4891,9 @@ int generate_ue_dlsch_params_from_dci(int frame, if ((rv2 == 1) && (mcs2 == 0)) { TB1_active=0; } +#ifdef DEBUG_HARQ + printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active); +#endif //printf("RV TB0 = %d\n", rv1); @@ -4898,7 +4913,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->status = ACTIVE; dlsch0_harq->codeword=0; dlsch1_harq->codeword=1; - //printf("\n UE: BOTH ACTIVE\n"); +#ifdef DEBUG_HARQ + printf("[DCI UE]: BOTH ACTIVE\n"); +#endif } else if (TB0_active && TB1_active && tbswap==1) { dlsch0=dlsch[0]; @@ -4937,7 +4954,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->codeword = 0; dlsch0=NULL; dlsch0_harq = NULL; - //printf("\n UE: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); +#ifdef DEBUG_HARQ + printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); +#endif } @@ -4990,7 +5009,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1]; dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2]; dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3]; - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + dlsch1_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); } @@ -5010,6 +5031,9 @@ int generate_ue_dlsch_params_from_dci(int frame, if (dlsch1_harq != NULL) dlsch1_harq->Nl = 1; +#ifdef DEBUG_HARQ + printf ("[DCI UE] tpmi = %d\n", tpmi); +#endif if ((dlsch0 != NULL) && (dlsch1 != NULL)){ //two CW active @@ -5112,7 +5136,10 @@ int generate_ue_dlsch_params_from_dci(int frame, break; } } - +#ifdef DEBUG_HARQ + printf("[DCI UE] harq1 MIMO mode = %d\n", dlsch1_harq->mimo_mode); +#endif + //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); if ((frame_parms->mode1_flag == 1) && (dlsch0_harq != NULL)) dlsch0_harq->mimo_mode = SISO; @@ -5196,6 +5223,12 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1->rnti = rnti; } +#ifdef DEBUG_HARQ + if (dlsch0 != NULL) + printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status); + else + printf("[DCI UE] dlsch1_harq status = %d\n", dlsch1_harq->status); +#endif break; @@ -5869,11 +5902,19 @@ int generate_ue_dlsch_params_from_dci(int frame, } #endif - dlsch[0]->active=1; + //dlsch[0]->active=1; // compute DL power control parameters - computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); - computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off); + if (dlsch0_harq != NULL){ + computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); + computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off); + } + + if (dlsch1_harq != NULL) { + computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antennas_tx_eNB); + computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[1],dlsch1_harq->dl_power_off); + } + return(0); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c old mode 100755 new mode 100644 index 59e988861b..0b16c1953f --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -37,8 +37,7 @@ * \note * \warning */ - -#include "PHY/defs.h" +//#include "PHY/defs.h" #include "PHY/extern.h" #include "defs.h" #include "extern.h" @@ -51,6 +50,8 @@ #define NOCYGWIN_STATIC #endif +//#define DEBUG_HARQ + //#undef LOG_D //#define LOG_D LOG_I @@ -68,9 +69,9 @@ uint8_t interf_unaw_shift1=0; uint8_t interf_unaw_shift=0; //inferference-free case unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; + 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1, - 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous + 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous /* //original values from sebastion + same hand tuning @@ -139,12 +140,30 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, break; case PDSCH: + lte_ue_pdsch_vars = &phy_vars_ue->lte_ue_pdsch_vars[eNB_id]; dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id]; - codeword_TB0 = dlsch_ue[0]->harq_processes[harq_pid]->codeword; - codeword_TB1 = dlsch_ue[1]->harq_processes[harq_pid]->codeword; - dlsch0_harq = dlsch_ue[codeword_TB0]->harq_processes[harq_pid]; - dlsch1_harq = dlsch_ue[codeword_TB1]->harq_processes[harq_pid]; + if ((dlsch_ue[0]->harq_processes[harq_pid]->status == ACTIVE) && + (dlsch_ue[1]->harq_processes[harq_pid]->status == ACTIVE)){ + codeword_TB0 = dlsch_ue[0]->harq_processes[harq_pid]->codeword; + codeword_TB1 = dlsch_ue[1]->harq_processes[harq_pid]->codeword; + dlsch0_harq = dlsch_ue[codeword_TB0]->harq_processes[harq_pid]; + dlsch1_harq = dlsch_ue[codeword_TB1]->harq_processes[harq_pid]; + } + else if ((dlsch_ue[0]->harq_processes[harq_pid]->status == ACTIVE) && + (dlsch_ue[1]->harq_processes[harq_pid]->status != ACTIVE) ) { + codeword_TB0 = dlsch_ue[0]->harq_processes[harq_pid]->codeword; + dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid]; + dlsch1_harq = NULL; + codeword_TB1 = -1; + } + else if ((dlsch_ue[0]->harq_processes[harq_pid]->status != ACTIVE) && + (dlsch_ue[1]->harq_processes[harq_pid]->status == ACTIVE) ){ + codeword_TB1 = dlsch_ue[1]->harq_processes[harq_pid]->codeword; + dlsch0_harq = dlsch_ue[1]->harq_processes[harq_pid]; + dlsch1_harq = NULL; + codeword_TB0 = -1; + } break; default: @@ -152,6 +171,10 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, return(-1); break; } +#ifdef DEBUG_HARQ + printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode); + printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1); +#endif DevAssert(dlsch0_harq); round = dlsch0_harq->round; @@ -216,11 +239,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, subframe, phy_vars_ue->high_speed_flag, frame_parms, - dlsch0_harq->mimo_mode); + dlsch0_harq->mimo_mode); //#ifdef DEBUG_DLSCH_MOD /* printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); for (rb=0;rbpmi_ext[rb]); + printf("%d",lte_ue_pdsch_vars[eNB_id]->pmi_ext[rb]); printf("\n");*/ //#endif @@ -237,7 +260,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, subframe, phy_vars_ue->high_speed_flag, frame_parms, - dlsch0_harq->mimo_mode); + dlsch0_harq->mimo_mode); else nb_rb = dlsch_extract_rbs_dual(lte_ue_common_vars->rxdataF, lte_ue_common_vars->dl_ch_estimates[eNB_id], @@ -250,7 +273,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, subframe, phy_vars_ue->high_speed_flag, frame_parms, - dlsch0_harq->mimo_mode); + dlsch0_harq->mimo_mode); } } // if n_tx>1 else { @@ -311,14 +334,15 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (dlsch0_harq->mimo_modedl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); + frame_parms, + dlsch_ue, + symbol, + nb_rb); if (first_symbol_flag==1) { - dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, avg, symbol, @@ -339,7 +363,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } - dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, + dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, lte_ue_pdsch_vars[eNB_id]->dl_ch_magb0, @@ -359,7 +383,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if ((rx_type==rx_IC_single_stream) && (eNB_id_in_connected_eNB)) { - dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, + dlsch_channel_compensation(lte_ue_pdsch_vars[eNB_id_i]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_mag0, lte_ue_pdsch_vars[eNB_id_i]->dl_ch_magb0, @@ -399,23 +423,23 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, if (frame_parms->nb_antennas_tx_eNB == 2) { - // scaling interfering channel (following for TM56) - dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); + // scaling interfering channel (following for TM56) + dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + dlsch_ue, + symbol, + nb_rb); if (first_symbol_flag==1) { // effective channel of desired user is always stronger than interfering eff. channel dlsch_channel_level_TM34(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, avg_0, - avg_1, - symbol, - nb_rb, + avg_1, + symbol, + nb_rb, dlsch0_harq->mimo_mode); @@ -423,27 +447,27 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // write_output("dlsch0_r0_aver_chan_1.m","dl_aver_ch1_r0_0",&avg_1[0],1,1,2); - if (rx_type>rx_standard) { - // Shifts are needed to avoid tails in SNR/BLER curves. - // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); + if (rx_type>rx_standard) { + // Shifts are needed to avoid tails in SNR/BLER curves. + // LUT will be introduced with mcs-dependent shift + avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); - } - else { - // Shifts are needed to avoid tails in SNR/BLER curves. - // LUT will be introduced with mcs-dependent shift - avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; - lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); - lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + } + else { + // Shifts are needed to avoid tails in SNR/BLER curves. + // LUT will be introduced with mcs-dependent shift + avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; + avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; + lte_ue_pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); + //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); + //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); } } @@ -459,7 +483,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, dlsch0_harq->mimo_mode, nb_rb, lte_ue_pdsch_vars[eNB_id]->log2_maxh0, - lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); /* if (symbol == 5) { @@ -469,11 +493,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, write_output("rxF_comp_d11.m","rxF_c_d11",<e_ue_pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } */ + } */ // compute correlation between signal and interference channels (rho12 and rho21) - dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22 + dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22 symbol, nb_rb, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -481,17 +505,17 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); + //printf("rho stream1 =%d\n", <e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); //to be optimized (just take complex conjugate) dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21 symbol, nb_rb, - &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + &(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->log2_maxh1); // printf("rho stream2 =%d\n",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext ); //printf("TM3 log2_maxh : %d\n",lte_ue_pdsch_vars[eNB_id]->log2_maxh); @@ -503,7 +527,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, write_output("rho2_1.m","rho2_1",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } */ + } */ } else { @@ -534,11 +558,11 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, // effective channel of desired user is always stronger than interfering eff. channel dlsch_channel_level_TM56(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - lte_ue_pdsch_vars[eNB_id]->pmi_ext, - avg, - symbol, - nb_rb); + frame_parms, + lte_ue_pdsch_vars[eNB_id]->pmi_ext, + avg, + symbol, + nb_rb); // LOG_D(PHY,"llr_offset = %d\n",offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]); avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; @@ -623,13 +647,14 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, else if (dlsch0_harq->dl_power_off==1) { dlsch_scale_channel(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - dlsch_ue, - symbol, - nb_rb); + frame_parms, + dlsch_ue, + symbol, + nb_rb); if (first_symbol_flag==1) { - dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, + + dlsch_channel_level(lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, avg, symbol, @@ -638,19 +663,19 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, LOG_D(PHY,"[DLSCH] avg[0] %d\n",avg[0]); #endif - avgs = 0; + avgs = 0; - for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) - for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); - // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); + for (aatx=0;aatxnb_antennas_tx_eNB;aatx++) + for (aarx=0;aarxnb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + // avgs = cmax(avgs,avg[(aarx<<1)+aatx]); - lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + interf_unaw_shift_tm1_mcs[dlsch0_harq->mcs]; + lte_ue_pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; + lte_ue_pdsch_vars[eNB_id]->log2_maxh++; } - dlsch_channel_compensation_TM56(lte_ue_pdsch_vars[eNB_id]->rxdataF_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_estimates_ext, lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, @@ -676,20 +701,20 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 if (frame_parms->nb_antennas_tx_eNB == 2) { - dlsch_detection_mrc_TM34(frame_parms, + dlsch_detection_mrc_TM34(frame_parms, lte_ue_pdsch_vars[eNB_id], - harq_pid, + harq_pid, dlsch0_harq->round, - symbol, - nb_rb, - 1); + symbol, + nb_rb, + 1); /* if (symbol == 5) { write_output("rho0_mrc.m","rho0_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM write_output("rho2_mrc.m","rho2_0",<e_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - } */ + } */ } @@ -748,7 +773,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, switch (dlsch0_harq->Qm) { case 2 : - if (rx_type==rx_standard) { + if ((rx_type==rx_standard) || (codeword_TB0 = 1)) { dlsch_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, lte_ue_pdsch_vars[eNB_id]->llr[0], @@ -824,7 +849,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } break; case 4 : - if (rx_type==rx_standard) { + if ((rx_type==rx_standard ) || (codeword_TB0 = 1) ) { dlsch_16qam_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, lte_ue_pdsch_vars[eNB_id]->llr[0], @@ -833,7 +858,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128); } - else if (rx_type >= rx_IC_single_stream) { + else if ((rx_type >= rx_IC_single_stream) && (codeword_TB0 != -1)) { if (dlsch1_harq->Qm == 2) { dlsch_16qam_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, @@ -857,57 +882,57 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } } else if (dlsch1_harq->Qm == 4) { - dlsch_16qam_16qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_16qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); - } + dlsch_16qam_16qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_16qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } } else { - dlsch_16qam_64qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_64qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - dl_ch_mag_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); - } + dlsch_16qam_64qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_64qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } } } break; case 6 : - if (rx_type==rx_standard) { + if ((rx_type==rx_standard) || (codeword_TB0 == -1)) { dlsch_64qam_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, lte_ue_pdsch_vars[eNB_id]->llr[0], @@ -917,76 +942,76 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128); } - else if (rx_type >= rx_IC_single_stream) { + else if ((rx_type >= rx_IC_single_stream) && (codeword_TB0 != -1)){ if (dlsch1_harq->Qm == 2) { - dlsch_64qam_qpsk_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_qpsk_64qam_llr(frame_parms, - rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); - } + dlsch_64qam_qpsk_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_qpsk_64qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } } else if (dlsch1_harq->Qm == 4) { - dlsch_64qam_16qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_16qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); - } + dlsch_64qam_16qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_16qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } } else { - dlsch_64qam_64qam_llr(frame_parms, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, - lte_ue_pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_64qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i - lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - lte_ue_pdsch_vars[eNB_id]->llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), - lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); - } + dlsch_64qam_64qam_llr(frame_parms, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho2_ext, + lte_ue_pdsch_vars[eNB_id]->llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + dlsch_64qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + lte_ue_pdsch_vars[eNB_id]->dl_ch_mag0,//i + lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + lte_ue_pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), + lte_ue_pdsch_vars[eNB_id]->llr128_2ndstream); + } } } @@ -1689,7 +1714,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, Nre = (pilots==0) ? 12 : 8; precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))) - (phy_measurements->n0_power[aarx])); + (nb_rb*Nre))) - (phy_measurements->n0_power[aarx])); } // rx_antennas phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,phy_measurements->n0_power_tot); @@ -1754,51 +1779,51 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[1],&dl_ch1_128b[1]); if (pilots==0) { - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[2],&dl_ch1_128b[2]); + prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[2],&dl_ch1_128b[2]); } if (mod_order>2) { - // get channel amplitude if not QPSK - mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); - // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits - mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits - mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - } + } - dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); - dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); - dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); - dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); + dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); + dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); + dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); + dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); - if (pilots==0) { - dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); - dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); - } + if (pilots==0) { + dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); + dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); + } } mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]); //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]); //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); @@ -1806,7 +1831,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); @@ -1816,48 +1841,48 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); - mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - dl_ch0_128+=6; - dl_ch1_128+=6; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - rxdataF128+=6; - rxdataF_comp128+=3; + dl_ch0_128+=6; + dl_ch1_128+=6; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + rxdataF128+=6; + rxdataF_comp128+=3; } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch0_128+=4; - dl_ch1_128+=4; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - rxdataF128+=4; - rxdataF_comp128+=2; + dl_ch0_128+=4; + dl_ch1_128+=4; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=4; + rxdataF_comp128+=2; } } @@ -1865,7 +1890,7 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))) - (phy_measurements->n0_power[aarx])); + (nb_rb*Nre))) - (phy_measurements->n0_power[aarx])); // rx_antennas } phy_measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,phy_measurements->n0_power_tot); @@ -1890,7 +1915,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode, unsigned short nb_rb, unsigned char output_shift0, - unsigned char output_shift1) { + unsigned char output_shift1) { #if defined(__x86_64__) || defined(__i386__) @@ -1943,7 +1968,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, output_shift=output_shift0; } else { - output_shift=output_shift1; + output_shift=output_shift1; } */ // printf("antenna %d\n", aarx); @@ -2384,79 +2409,79 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (mod_order0>2) { - // get channel amplitude if not QPSK - mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); - // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits - mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits - mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(dl_ch0_128[1], dl_ch0_128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(dl_ch0_128[2], dl_ch0_128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - } + } - dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b); - dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b); - dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128); - dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128); + dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b); + dl_ch_mag0_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128b); + dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128); + dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128); - if (pilots==0) { - dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b); - dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128); - } + if (pilots==0) { + dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b); + dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128); + } } if (mod_order1>2) { - // get channel amplitude if not QPSK - mmtmpD0 = vmull_s16(dl_ch1_128[0], dl_ch1_128[0]); - // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits - mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits - mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(dl_ch1_128[0], dl_ch1_128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(dl_ch1_128[1], dl_ch1_128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(dl_ch1_128[2], dl_ch1_128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch1_128[3], dl_ch1_128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch1_128[4], dl_ch1_128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - } + } - dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b); - dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b); - dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128); - dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128); + dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b); + dl_ch_mag1_128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128b); + dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128); + dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128); - if (pilots==0) { - dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b); - dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128); - } + if (pilots==0) { + dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b); + dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128); + } } mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]); @@ -2464,7 +2489,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]); //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); @@ -2472,7 +2497,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); @@ -2482,12 +2507,12 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); @@ -2497,13 +2522,13 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD0 = vmull_s16(dl_ch1_128[0], rxdataF128[0]); mmtmpD1 = vmull_s16(dl_ch1_128[1], rxdataF128[1]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); @@ -2513,46 +2538,46 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD0 = vmull_s16(dl_ch1_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch1_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp1_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); - mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0 = vmull_s16(dl_ch0_128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - mmtmpD0 = vmull_s16(dl_ch1_128[4], rxdataF128[4]); - mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vmull_s16(dl_ch1_128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); } } @@ -2700,7 +2725,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_estimates_ext_i, int **dl_ch_rho_ext, unsigned char output_shift0, - unsigned char output_shift1) + unsigned char output_shift1) { #if defined(__x86_64__)||defined(__i386__) @@ -2726,7 +2751,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, output_shift=output_shift0; } else { - output_shift=output_shift1; + output_shift=output_shift1; } //printf ("antenna %d", aarx); @@ -2852,8 +2877,8 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); // print_shorts("mrc comp0:",&rxdataF_comp128_0[i]); - // print_shorts("mrc mag0:",&dl_ch_mag128_0[i]); - // print_shorts("mrc mag0b:",&dl_ch_mag128_0b[i]); + // print_shorts("mrc mag0:",&dl_ch_mag128_0[i]); + // print_shorts("mrc mag0b:",&dl_ch_mag128_0b[i]); // print_shorts("mrc rho1:",&rho128_1[i]); } @@ -2956,25 +2981,25 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *lte_ue_pdsch_vars, - int harq_pid, - int round, - unsigned char symbol, - unsigned short nb_rb, - unsigned char dual_stream_UE) { + LTE_UE_PDSCH *lte_ue_pdsch_vars, + int harq_pid, + int round, + unsigned char symbol, + unsigned short nb_rb, + unsigned char dual_stream_UE) { unsigned char aatx; int i; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; - int **rxdataF_comp0 =lte_ue_pdsch_vars->rxdataF_comp0; - int **rxdataF_comp1 =lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; - int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for second stream - int **dl_ch_rho2_ext =lte_ue_pdsch_vars->dl_ch_rho2_ext; - int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; - int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1[harq_pid][round]; - int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; - int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1[harq_pid][round]; + int **rxdataF_comp0 =lte_ue_pdsch_vars->rxdataF_comp0; + int **rxdataF_comp1 =lte_ue_pdsch_vars->rxdataF_comp1[harq_pid][round]; + int **dl_ch_rho_ext =lte_ue_pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for second stream + int **dl_ch_rho2_ext =lte_ue_pdsch_vars->dl_ch_rho2_ext; + int **dl_ch_mag0 = lte_ue_pdsch_vars->dl_ch_mag0; + int **dl_ch_mag1 = lte_ue_pdsch_vars->dl_ch_mag1[harq_pid][round]; + int **dl_ch_magb0 = lte_ue_pdsch_vars->dl_ch_magb0; + int **dl_ch_magb1 = lte_ue_pdsch_vars->dl_ch_magb1[harq_pid][round]; if (frame_parms->nb_antennas_rx>1) { @@ -2992,9 +3017,9 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); - // print_shorts("mrc compens0:",&rxdataF_comp128_0[i]); - // print_shorts("mrc mag128_0:",&dl_ch_mag128_0[i]); - // print_shorts("mrc mag128_0b:",&dl_ch_mag128_0b[i]); + // print_shorts("mrc compens0:",&rxdataF_comp128_0[i]); + // print_shorts("mrc mag128_0:",&dl_ch_mag128_0[i]); + // print_shorts("mrc mag128_0b:",&dl_ch_mag128_0b[i]); } } // if (rho) { @@ -3024,9 +3049,9 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i1[i],1)); dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i1b[i],1)); - //print_shorts("mrc compens1:",&rxdataF_comp128_i0[i]); - //print_shorts("mrc mag128_i0:",&dl_ch_mag128_i0[i]); - //print_shorts("mrc mag128_i0b:",&dl_ch_mag128_i0b[i]); + //print_shorts("mrc compens1:",&rxdataF_comp128_i0[i]); + //print_shorts("mrc mag128_i0:",&dl_ch_mag128_i0[i]); + //print_shorts("mrc mag128_i0b:",&dl_ch_mag128_i0b[i]); } } @@ -3228,9 +3253,9 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, //compute average channel_level of effective (precoded) channel void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, - unsigned char *pmi_ext, + unsigned char *pmi_ext, int *avg_0, - int *avg_1, + int *avg_1, uint8_t symbol, unsigned short nb_rb, MIMO_mode_t mimo_mode){ @@ -3269,7 +3294,7 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, for (rb=0; rbofdm_symbol_size)))]), - ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/ + printf("%d : (%d,%d)\n",(rxF+i-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))]), + ((short*)&rxF[i])[0],((short*)&rxF[i])[1]);*/ } dl_ch0_ext+=12; @@ -3801,7 +3826,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, else { // Odd number of RBs for (rb=0; rbN_RB_DL>>1; rb++) { #ifdef DEBUG_DLSCH_DEMOD - printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); + printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); #endif skip_half=0; @@ -3816,8 +3841,8 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, else rb_alloc_ind = 0; - if (rb_alloc_ind == 1) - nb_rb++; + if (rb_alloc_ind == 1) + nb_rb++; // PBCH @@ -3853,9 +3878,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (frame_parms->frame_type == FDD) { //FDD if (((subframe==0)||(subframe==5)) && - (rb>((frame_parms->N_RB_DL>>1)-3)) && - (rb<((frame_parms->N_RB_DL>>1)+3)) && - (l==pss_symb) ) { + (rb>((frame_parms->N_RB_DL>>1)-3)) && + (rb<((frame_parms->N_RB_DL>>1)+3)) && + (l==pss_symb) ) { rb_alloc_ind = 0; } @@ -3880,19 +3905,19 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (rb_alloc_ind==1) { #ifdef DEBUG_DLSCH_DEMOD - printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); + printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif if (pilots==0) { - // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); if (skip_half==1) { memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); for (i=0; i<6; i++) { - rxF_ext[i]=rxF[i]; + rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - } + } dl_ch0_ext+=6; rxF_ext+=6; } else if (skip_half==2) { @@ -3901,9 +3926,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - } + } dl_ch0_ext+=6; rxF_ext+=6; } else { @@ -3914,12 +3939,12 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, #ifdef DEBUG_DLSCH_DEMOD printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - } + } dl_ch0_ext+=12; rxF_ext+=12; } } else { - // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); j=0; if (skip_half==1) { @@ -3932,14 +3957,14 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, dl_ch0_ext[j++]=dl_ch0[i]; } } - rxF_ext+=5; + rxF_ext+=5; dl_ch0_ext+=5; } else if (skip_half==2) { for (i=0; i<6; i++) { if (i!=((frame_parms->nushift+poffset)%6)) { rxF_ext[j]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i+6]; } @@ -3953,7 +3978,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, (i!=((frame_parms->nushift+poffset+6)%12))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; @@ -3984,13 +4009,13 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (rb_alloc_ind == 1) - nb_rb++; + nb_rb++; // PBCH if ((subframe==0) && - (l>=(nsymb>>1)) && - (l<((nsymb>>1) + 4))) { + (l>=(nsymb>>1)) && + (l<((nsymb>>1) + 4))) { rb_alloc_ind = 0; } @@ -4009,8 +4034,8 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, //PSS if ((frame_parms->frame_type == TDD) && (subframe==6) && - (l==pss_symb) ) { - rb_alloc_ind = 0; + (l==pss_symb) ) { + rb_alloc_ind = 0; } @@ -4018,7 +4043,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, // printf("DC rb %d (%p)\n",rb,rxF); if (rb_alloc_ind==1) { #ifdef DEBUG_DLSCH_DEMOD - printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); + printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif if (pilots==0) { for (i=0; i<6; i++) { @@ -4088,8 +4113,8 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, else rb_alloc_ind = 0; - if (rb_alloc_ind == 1) - nb_rb++; + if (rb_alloc_ind == 1) + nb_rb++; // PBCH if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) { @@ -4139,25 +4164,25 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (rb_alloc_ind==1) { #ifdef DEBUG_DLSCH_DEMOD - printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); + printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif /* - printf("rb %d\n",rb); + printf("rb %d\n",rb); for (i=0;i<12;i++) printf("(%d %d)",((short *)dl_ch0)[i<<1],((short*)dl_ch0)[1+(i<<1)]); printf("\n"); */ if (pilots==0) { - // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); if (skip_half==1) { memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); for (i=0; i<6; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - } + } dl_ch0_ext+=6; rxF_ext+=6; @@ -4167,9 +4192,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - } + } dl_ch0_ext+=6; rxF_ext+=6; @@ -4179,14 +4204,14 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<12; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - } + } dl_ch0_ext+=12; rxF_ext+=12; } } else { - // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); + // printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); j=0; if (skip_half==1) { @@ -4194,7 +4219,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (i!=((frame_parms->nushift+poffset)%6)) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; } @@ -4207,7 +4232,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (i!=((frame_parms->nushift+poffset)%6)) { rxF_ext[j]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i+6]; } @@ -4221,7 +4246,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, (i!=((frame_parms->nushift+poffset+6)%12))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; } @@ -4253,7 +4278,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, unsigned char subframe, uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms, - MIMO_mode_t mimo_mode) { + MIMO_mode_t mimo_mode) { int prb,nb_rb=0; int prb_off,prb_off2; @@ -4301,15 +4326,15 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, skip_half=0; if (prb < 32) - rb_alloc_ind = (rb_alloc[0]>>prb) & 1; + rb_alloc_ind = (rb_alloc[0]>>prb) & 1; else if (prb < 64) - rb_alloc_ind = (rb_alloc[1]>>(prb-32)) & 1; + rb_alloc_ind = (rb_alloc[1]>>(prb-32)) & 1; else if (prb < 96) - rb_alloc_ind = (rb_alloc[2]>>(prb-64)) & 1; + rb_alloc_ind = (rb_alloc[2]>>(prb-64)) & 1; else if (prb < 100) - rb_alloc_ind = (rb_alloc[3]>>(prb-96)) & 1; + rb_alloc_ind = (rb_alloc[3]>>(prb-96)) & 1; else - rb_alloc_ind = 0; + rb_alloc_ind = 0; if (rb_alloc_ind == 1) nb_rb++; @@ -4317,73 +4342,73 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs - // PBCH - if ((subframe==0) && - (prb>=((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l>=(nsymb>>1)) && - (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; - // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb); - } + // PBCH + if ((subframe==0) && + (prb>=((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l>=(nsymb>>1)) && + (l<((nsymb>>1) + 4))) { + rb_alloc_ind = 0; + // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb); + } - //SSS + //SSS - if (((subframe==0)||(subframe==5)) && - (prb>=((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb) ) { - rb_alloc_ind = 0; - // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); - } + if (((subframe==0)||(subframe==5)) && + (prb>=((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb) ) { + rb_alloc_ind = 0; + // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); + } - //PSS in subframe 0/5 if FDD - if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && - (prb>=((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l==pss_symb) ) { - rb_alloc_ind = 0; - // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb); - } - } + //PSS in subframe 0/5 if FDD + if (frame_parms->frame_type == FDD) { //FDD + if (((subframe==0)||(subframe==5)) && + (prb>=((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l==pss_symb) ) { + rb_alloc_ind = 0; + // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb); + } + } - if ((frame_parms->frame_type == TDD) && - (subframe==6)) { //TDD Subframe 6 - if ((prb>=((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l==pss_symb) ) { - rb_alloc_ind = 0; - } - } + if ((frame_parms->frame_type == TDD) && + (subframe==6)) { //TDD Subframe 6 + if ((prb>=((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l==pss_symb) ) { + rb_alloc_ind = 0; + } + } - if (rb_alloc_ind==1) { // PRB is allocated + if (rb_alloc_ind==1) { // PRB is allocated - prb_off = 12*prb; - prb_off2 = 1+(12*(prb-(frame_parms->N_RB_DL>>1))); - dl_ch0p = dl_ch0+(12*prb); - dl_ch1p = dl_ch1+(12*prb); - if (prb<(frame_parms->N_RB_DL>>1)){ - rxF = &rxdataF[aarx][prb_off+ - frame_parms->first_carrier_offset + - (symbol*(frame_parms->ofdm_symbol_size))]; - } - else { - rxF = &rxdataF[aarx][prb_off2+ - (symbol*(frame_parms->ofdm_symbol_size))]; - } + prb_off = 12*prb; + prb_off2 = 1+(12*(prb-(frame_parms->N_RB_DL>>1))); + dl_ch0p = dl_ch0+(12*prb); + dl_ch1p = dl_ch1+(12*prb); + if (prb<(frame_parms->N_RB_DL>>1)){ + rxF = &rxdataF[aarx][prb_off+ + frame_parms->first_carrier_offset + + (symbol*(frame_parms->ofdm_symbol_size))]; + } + else { + rxF = &rxdataF[aarx][prb_off2+ + (symbol*(frame_parms->ofdm_symbol_size))]; + } - /* - if (mimo_mode <= PUSCH_PRECODING1) + /* + if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; - else - *pmi_loc=(pmi>>prb)&1;*/ + else + *pmi_loc=(pmi>>prb)&1;*/ - *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; @@ -4408,280 +4433,280 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch1_ext[j++]=dl_ch1p[i]; } } - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; } // pilots==1 - } + } } else { // Odd number of RBs // PBCH - if ((subframe==0) && - (prb>((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l>=(nsymb>>1)) && - (l<((nsymb>>1) + 4))) { - rb_alloc_ind = 0; - // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb); - } + if ((subframe==0) && + (prb>((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l>=(nsymb>>1)) && + (l<((nsymb>>1) + 4))) { + rb_alloc_ind = 0; + // printf("symbol %d / rb %d: skipping PBCH REs\n",symbol,prb); + } - //SSS + //SSS - if (((subframe==0)||(subframe==5)) && - (prb>((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb) ) { - rb_alloc_ind = 0; - // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); - } + if (((subframe==0)||(subframe==5)) && + (prb>((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb) ) { + rb_alloc_ind = 0; + // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); + } - //PSS in subframe 0/5 if FDD - if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && - (prb>((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l==pss_symb) ) { - rb_alloc_ind = 0; - // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb); - } - } + //PSS in subframe 0/5 if FDD + if (frame_parms->frame_type == FDD) { //FDD + if (((subframe==0)||(subframe==5)) && + (prb>((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l==pss_symb) ) { + rb_alloc_ind = 0; + // printf("symbol %d / rb %d: skipping PSS REs\n",symbol,prb); + } + } - if ((frame_parms->frame_type == TDD) && - ((subframe==1) || (subframe==6))) { //TDD Subframe 1-6 - if ((prb>((frame_parms->N_RB_DL>>1)-3)) && - (prb<((frame_parms->N_RB_DL>>1)+3)) && - (l==pss_symb) ) { - rb_alloc_ind = 0; - } - } + if ((frame_parms->frame_type == TDD) && + ((subframe==1) || (subframe==6))) { //TDD Subframe 1-6 + if ((prb>((frame_parms->N_RB_DL>>1)-3)) && + (prb<((frame_parms->N_RB_DL>>1)+3)) && + (l==pss_symb) ) { + rb_alloc_ind = 0; + } + } - if (rb_alloc_ind == 1) { - skip_half=0; + if (rb_alloc_ind == 1) { + skip_half=0; - //Check if we have to drop half a PRB due to PSS/SSS/PBCH - // skip_half == 0 means full PRB - // skip_half == 1 means first half is used (leftmost half-PRB from PSS/SSS/PBCH) - // skip_half == 2 means second half is used (rightmost half-PRB from PSS/SSS/PBCH) - //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 - if ((subframe==0) && - (prb==((frame_parms->N_RB_DL>>1)-3)) && - (l>=(nsymb>>1)) && - (l<((nsymb>>1) + 4))) - skip_half=1; - else if ((subframe==0) && - (prb==((frame_parms->N_RB_DL>>1)+3)) && - (l>=(nsymb>>1)) && - (l<((nsymb>>1) + 4))) - skip_half=2; + //Check if we have to drop half a PRB due to PSS/SSS/PBCH + // skip_half == 0 means full PRB + // skip_half == 1 means first half is used (leftmost half-PRB from PSS/SSS/PBCH) + // skip_half == 2 means second half is used (rightmost half-PRB from PSS/SSS/PBCH) + //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 + if ((subframe==0) && + (prb==((frame_parms->N_RB_DL>>1)-3)) && + (l>=(nsymb>>1)) && + (l<((nsymb>>1) + 4))) + skip_half=1; + else if ((subframe==0) && + (prb==((frame_parms->N_RB_DL>>1)+3)) && + (l>=(nsymb>>1)) && + (l<((nsymb>>1) + 4))) + skip_half=2; - //SSS - if (((subframe==0)||(subframe==5)) && - (prb==((frame_parms->N_RB_DL>>1)-3)) && - (l==sss_symb)) - skip_half=1; - else if (((subframe==0)||(subframe==5)) && - (prb==((frame_parms->N_RB_DL>>1)+3)) && - (l==sss_symb)) - skip_half=2; + //SSS + if (((subframe==0)||(subframe==5)) && + (prb==((frame_parms->N_RB_DL>>1)-3)) && + (l==sss_symb)) + skip_half=1; + else if (((subframe==0)||(subframe==5)) && + (prb==((frame_parms->N_RB_DL>>1)+3)) && + (l==sss_symb)) + skip_half=2; - //PSS Subframe 0,5 - if (((frame_parms->frame_type == FDD) && - (((subframe==0)||(subframe==5)))) || //FDD Subframes 0,5 - ((frame_parms->frame_type == TDD) && - (((subframe==1) || (subframe==6))))) { //TDD Subframes 1,6 + //PSS Subframe 0,5 + if (((frame_parms->frame_type == FDD) && + (((subframe==0)||(subframe==5)))) || //FDD Subframes 0,5 + ((frame_parms->frame_type == TDD) && + (((subframe==1) || (subframe==6))))) { //TDD Subframes 1,6 - if ((prb==((frame_parms->N_RB_DL>>1)-3)) && - (l==pss_symb)) - skip_half=1; - else if ((prb==((frame_parms->N_RB_DL>>1)+3)) && - (l==pss_symb)) - skip_half=2; - } + if ((prb==((frame_parms->N_RB_DL>>1)-3)) && + (l==pss_symb)) + skip_half=1; + else if ((prb==((frame_parms->N_RB_DL>>1)+3)) && + (l==pss_symb)) + skip_half=2; + } - prb_off = 12*prb; - prb_off2 = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1)); - dl_ch0p = dl_ch0+(12*prb); - dl_ch1p = dl_ch1+(12*prb); + prb_off = 12*prb; + prb_off2 = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1)); + dl_ch0p = dl_ch0+(12*prb); + dl_ch1p = dl_ch1+(12*prb); - if (prb<=(frame_parms->N_RB_DL>>1)){ - rxF = &rxdataF[aarx][prb_off+ - frame_parms->first_carrier_offset + - (symbol*(frame_parms->ofdm_symbol_size))]; - } - else { - rxF = &rxdataF[aarx][prb_off2+ - (symbol*(frame_parms->ofdm_symbol_size))]; - } + if (prb<=(frame_parms->N_RB_DL>>1)){ + rxF = &rxdataF[aarx][prb_off+ + frame_parms->first_carrier_offset + + (symbol*(frame_parms->ofdm_symbol_size))]; + } + else { + rxF = &rxdataF[aarx][prb_off2+ + (symbol*(frame_parms->ofdm_symbol_size))]; + } #ifdef DEBUG_DLSCH_DEMOD - printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); + printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); #endif /* if (mimo_mode <= PUSCH_PRECODING1) *pmi_loc = (pmi>>((prb>>2)<<1))&3; - else - *pmi_loc=(pmi>>prb)&1; + else + *pmi_loc=(pmi>>prb)&1; // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); */ - *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; - if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC - if (pilots==0) { - if (skip_half==1) { - memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); - memcpy(rxF_ext,rxF,6*sizeof(int32_t)); + if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC + if (pilots==0) { + if (skip_half==1) { + memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); + memcpy(rxF_ext,rxF,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0;i<6;i++) - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + for (i=0;i<6;i++) + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - } else if (skip_half==2) { - memcpy(dl_ch0_ext,dl_ch0p+6,6*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1p+6,6*sizeof(int32_t)); - memcpy(rxF_ext,rxF+6,6*sizeof(int32_t)); + dl_ch0_ext+=6; + dl_ch1_ext+=6; + rxF_ext+=6; + } else if (skip_half==2) { + memcpy(dl_ch0_ext,dl_ch0p+6,6*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1p+6,6*sizeof(int32_t)); + memcpy(rxF_ext,rxF+6,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0;i<6;i++) - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + for (i=0;i<6;i++) + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - dl_ch0_ext+=6; - dl_ch1_ext+=6; - rxF_ext+=6; - } else { // skip_half==0 - memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int32_t)); - memcpy(rxF_ext,rxF,12*sizeof(int32_t)); + dl_ch0_ext+=6; + dl_ch1_ext+=6; + rxF_ext+=6; + } else { // skip_half==0 + memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int32_t)); + memcpy(rxF_ext,rxF,12*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0;i<12;i++) - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + for (i=0;i<12;i++) + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); #endif - dl_ch0_ext+=12; - dl_ch1_ext+=12; - rxF_ext+=12; - } - } else { // pilots=1 - j=0; + dl_ch0_ext+=12; + dl_ch1_ext+=12; + rxF_ext+=12; + } + } else { // pilots=1 + j=0; - if (skip_half==1) { - for (i=0; i<6; i++) { - if ((i!=frame_parms->nushift) && - (i!=((frame_parms->nushift+3)%6))) { - rxF_ext[j]=rxF[i]; + if (skip_half==1) { + for (i=0; i<6; i++) { + if ((i!=frame_parms->nushift) && + (i!=((frame_parms->nushift+3)%6))) { + rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots,skip1)extract rb %d, re %d (%d)=> (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("(pilots,skip1)extract rb %d, re %d (%d)=> (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif - dl_ch0_ext[j]=dl_ch0p[i]; - dl_ch1_ext[j++]=dl_ch1p[i]; - } - } - dl_ch0_ext+=4; - dl_ch1_ext+=4; - rxF_ext+=4; - } else if (skip_half==2) { - for (i=0; i<6; i++) { - if ((i!=frame_parms->nushift) && - (i!=((frame_parms->nushift+3)%6))) { - rxF_ext[j]=rxF[(i+6)]; + dl_ch0_ext[j]=dl_ch0p[i]; + dl_ch1_ext[j++]=dl_ch1p[i]; + } + } + dl_ch0_ext+=4; + dl_ch1_ext+=4; + rxF_ext+=4; + } else if (skip_half==2) { + for (i=0; i<6; i++) { + if ((i!=frame_parms->nushift) && + (i!=((frame_parms->nushift+3)%6))) { + rxF_ext[j]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots,skip2)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("(pilots,skip2)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif - dl_ch0_ext[j]=dl_ch0p[i+6]; - dl_ch1_ext[j++]=dl_ch1p[i+6]; - } - } - dl_ch0_ext+=4; - dl_ch1_ext+=4; - rxF_ext+=4; + dl_ch0_ext[j]=dl_ch0p[i+6]; + dl_ch1_ext[j++]=dl_ch1p[i+6]; + } + } + dl_ch0_ext+=4; + dl_ch1_ext+=4; + rxF_ext+=4; - } else { //skip_half==0 - for (i=0; i<12; i++) { - if ((i!=frame_parms->nushift) && - (i!=frame_parms->nushift+3) && - (i!=frame_parms->nushift+6) && - (i!=((frame_parms->nushift+9)%12))) { - rxF_ext[j]=rxF[i]; + } else { //skip_half==0 + for (i=0; i<12; i++) { + if ((i!=frame_parms->nushift) && + (i!=frame_parms->nushift+3) && + (i!=frame_parms->nushift+6) && + (i!=((frame_parms->nushift+9)%12))) { + rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots)extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("(pilots)extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); #endif - dl_ch0_ext[j] =dl_ch0p[i]; - dl_ch1_ext[j++]=dl_ch1p[i]; - } - } - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - } //skip_half==0 - } //pilots==1 - } else { // Do middle RB (around DC) + dl_ch0_ext[j] =dl_ch0p[i]; + dl_ch1_ext[j++]=dl_ch1p[i]; + } + } + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + } //skip_half==0 + } //pilots==1 + } else { // Do middle RB (around DC) - if (pilots==0) { - memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); - memcpy(rxF_ext,rxF,6*sizeof(int32_t)); + if (pilots==0) { + memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); + memcpy(rxF_ext,rxF,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0; i<6; i++) { - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); - } + for (i=0; i<6; i++) { + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + } #endif - rxF_ext+=6; - dl_ch0_ext+=6; - dl_ch1_ext+=6; - dl_ch0p+=6; - dl_ch1p+=6; + rxF_ext+=6; + dl_ch0_ext+=6; + dl_ch1_ext+=6; + dl_ch0p+=6; + dl_ch1p+=6; - rxF = &rxdataF[aarx][1+((symbol*(frame_parms->ofdm_symbol_size)))]; + rxF = &rxdataF[aarx][1+((symbol*(frame_parms->ofdm_symbol_size)))]; - memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); - memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); - memcpy(rxF_ext,rxF,6*sizeof(int32_t)); + memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); + memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); + memcpy(rxF_ext,rxF,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0; i<6; i++) { - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); - } + for (i=0; i<6; i++) { + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + } #endif - rxF_ext+=6; - dl_ch0_ext+=6; - dl_ch1_ext+=6; - } else { // pilots==1 - j=0; + rxF_ext+=6; + dl_ch0_ext+=6; + dl_ch1_ext+=6; + } else { // pilots==1 + j=0; - for (i=0; i<6; i++) { - if ((i!=frame_parms->nushift) && - (i!=((frame_parms->nushift+3)%6))) { - dl_ch0_ext[j]=dl_ch0p[i]; - dl_ch1_ext[j]=dl_ch1p[i]; - rxF_ext[j++]=rxF[i]; + for (i=0; i<6; i++) { + if ((i!=frame_parms->nushift) && + (i!=((frame_parms->nushift+3)%6))) { + dl_ch0_ext[j]=dl_ch0p[i]; + dl_ch1_ext[j]=dl_ch1p[i]; + rxF_ext[j++]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[i],*(1+(short*)&rxF[i])); + printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[i],*(1+(short*)&rxF[i])); #endif - } - } - rxF = &rxdataF[aarx][1+symbol*(frame_parms->ofdm_symbol_size)]; + } + } + rxF = &rxdataF[aarx][1+symbol*(frame_parms->ofdm_symbol_size)]; - for (; i<12; i++) { - if ((i!=((frame_parms->nushift+6)%12)) && - (i!=((frame_parms->nushift+9)%12))) { - dl_ch0_ext[j]=dl_ch0p[i]; - dl_ch1_ext[j]=dl_ch1p[i]; - rxF_ext[j++]=rxF[i-6]; + for (; i<12; i++) { + if ((i!=((frame_parms->nushift+6)%12)) && + (i!=((frame_parms->nushift+9)%12))) { + dl_ch0_ext[j]=dl_ch0p[i]; + dl_ch1_ext[j]=dl_ch1p[i]; + rxF_ext[j++]=rxF[i-6]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short*)&rxF[1+i-6])); + printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short*)&rxF[1+i-6])); #endif - } - } + } + } - dl_ch0_ext+=8; - dl_ch1_ext+=8; - rxF_ext+=8; - } //pilots==1 - } // if Middle PRB - } // if odd PRB + dl_ch0_ext+=8; + dl_ch1_ext+=8; + rxF_ext+=8; + } //pilots==1 + } // if Middle PRB + } // if odd PRB } // if rballoc==1 } // for prb } // for aarx @@ -4784,7 +4809,7 @@ void print_bytes(char *s,__m128i *x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",s, tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7], tempb[8],tempb[9],tempb[10],tempb[11],tempb[12],tempb[13],tempb[14],tempb[15] - ); + ); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 4c70f08230..04353aa663 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -156,7 +156,7 @@ int allocate_REs_in_RB(LTE_DL_FRAME_PARMS *frame_parms, uint8_t *x0 = NULL; //dlsch0_harq->e; - MIMO_mode_t mimo_mode = dlsch0_harq->mimo_mode; + MIMO_mode_t mimo_mode;//= dlsch0_harq->mimo_mode; int first_layer0; //= dlsch0_harq->first_layer; int Nlayers0; // = dlsch0_harq->Nlayers; @@ -1411,8 +1411,13 @@ int dlsch_modulation(int32_t **txdataF, nsymb = (frame_parms->Ncp==0) ? 14:12; + if (dlsch0 != NULL){ amp_rho_a = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_a)>>13); //amp=512 in full scale; dlsch0->sqrt_rho_a=8192in Q2.13, 1 in full scale amp_rho_b = (int16_t)(((int32_t)amp*dlsch0->sqrt_rho_b)>>13); + } else{ + amp_rho_a = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_a)>>13); + amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13); + } if (mod_order0 == 4) for (i=0; i<4; i++) { @@ -1445,6 +1450,7 @@ int dlsch_modulation(int32_t **txdataF, // printf("num_pdcch_symbols %d, nsymb %d\n",num_pdcch_symbols,nsymb); for (l=num_pdcch_symbols; lNcp==0) { // normal prefix if ((l==4)||(l==11)) @@ -1611,9 +1618,11 @@ int dlsch_modulation(int32_t **txdataF, } } - if (dlsch0_harq->Nlayers>1) { - msg("Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset); - return(-1); + if (dlsch0) { + if (dlsch0_harq->Nlayers>1) { + msg("Nlayers %d: re_offset %d, symbol %d offset %d\n",dlsch0_harq->Nlayers,re_offset,l,symbol_offset); + return(-1); + } } if (dlsch1) { @@ -1639,6 +1648,17 @@ int dlsch_modulation(int32_t **txdataF, if (rb_alloc_ind > 0) { // printf("Allocated rb %d/symbol %d, skip_half %d, subframe_offset %d, symbol_offset %d, re_offset %d, jj %d\n",rb,l,skip_half,subframe_offset,symbol_offset,re_offset,jj); + if (dlsch0 != NULL) { + get_pmi_temp = get_pmi(frame_parms->N_RB_DL, + dlsch0->harq_processes[harq_pid]->mimo_mode, + dlsch0->harq_processes[harq_pid]->pmi_alloc, + rb); + } else + get_pmi_temp = get_pmi(frame_parms->N_RB_DL, + dlsch1->harq_processes[harq_pid]->mimo_mode, + dlsch1->harq_processes[harq_pid]->pmi_alloc, + rb); + allocate_REs_in_RB(frame_parms, txdataF, @@ -1646,11 +1666,11 @@ int dlsch_modulation(int32_t **txdataF, &jj2, re_offset, symbol_offset, - dlsch0->harq_processes[harq_pid], - (dlsch1==NULL) ? NULL : dlsch1->harq_processes[harq_pid], + (dlsch0 == NULL) ? NULL : dlsch0->harq_processes[harq_pid], + (dlsch1 == NULL) ? NULL : dlsch1->harq_processes[harq_pid], pilots, ((pilots) ? amp_rho_b : amp_rho_a), - get_pmi(frame_parms->N_RB_DL,dlsch0->harq_processes[harq_pid]->mimo_mode,dlsch0->harq_processes[harq_pid]->pmi_alloc,rb), + get_pmi_temp, qam_table_s0, qam_table_s1, &re_allocated, @@ -1672,7 +1692,11 @@ int dlsch_modulation(int32_t **txdataF, } #ifdef DEBUG_DLSCH_MODULATION - msg("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset)); + if (dlsch0 != NULL){ + msg("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch0_harq->nb_rb,dlsch0_harq->rb_alloc,mod_order0,Nl0,2,0,subframe_offset)); + }else{ + msg("generate_dlsch : jj = %d,re_allocated = %d (G %d)\n",jj,re_allocated,get_G(frame_parms,dlsch1_harq->nb_rb,dlsch1_harq->rb_alloc,mod_order1,Nl1,2,0,subframe_offset)); + } #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT); diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index f811f7524b..bd6b6387f1 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -34,9 +34,9 @@ double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0}, { 5.0/4.0,1.0,3.0/4.0,1.0/2.0}}; */ - + double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db - { 0.96910, 0.00000, -1.24939, -3.01030}}; + { 0.96910, 0.00000, -1.24939, -3.01030}}; double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by higher layers @@ -45,21 +45,21 @@ double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated) return(pa_values[pdsch_config_dedicated->p_a]); } -double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - LTE_eNB_DLSCH_t *dlsch_eNB,int dl_power_off, uint8_t n_antenna_port){ +double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, + LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port){ double rho_a_dB; double sqrt_rho_a_lin; rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; - + if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5 rho_a_dB-=10*log10(2); - + if(n_antenna_port==4) // see TS 36.213 Section 5.2 rho_a_dB=+10*log10(2); - - sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); - + + sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); + dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); #if DEBUG_PC @@ -78,9 +78,9 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB, rho_b_dB; double sqrt_rho_b_lin; - + rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off, n_antenna_port); - + if(n_antenna_port>1) rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; else @@ -99,24 +99,24 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_UE_DLSCH_t *dlsch_ue, - unsigned char dl_power_off, - uint8_t n_antenna_port - ){ - + unsigned char dl_power_off, + uint8_t n_antenna_port + ){ + double rho_a_dB; double sqrt_rho_a_lin; rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; - - if(!dl_power_off) - rho_a_dB-=10*log10(2); + + if(!dl_power_off) + rho_a_dB-=10*log10(2); //if dl_power_offset is 0, this is for MU-interference, TM5. But in practice UE may assume 16 or 64QAM TM4 as multiuser - + if(n_antenna_port==4) // see TS 36.213 Section 5.2 rho_a_dB=+10*log10(2); - - sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); - + + sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); + dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); #ifdef DEBUG_PC @@ -135,9 +135,9 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB, rho_b_dB; double sqrt_rho_b_lin; - + rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off, n_antenna_port); - + if(n_antenna_port>1) rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; else diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 6a889c5dfb..b4874569ae 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -217,7 +217,7 @@ int32_t dlsch_modulation_SIC(int32_t **sic_buffer, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch0, LTE_eNB_DLSCH_t *dlsch1, - int G); + int G); /* \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH. @param txdataF Table of pointers for frequency-domain TX signals @@ -720,15 +720,15 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp, - int32_t **sic_buffer, - int **rho_i, + int32_t **sic_buffer, + int **rho_i, short *dlsch_llr, - uint8_t num_pdcch_symbols, + uint8_t num_pdcch_symbols, uint16_t nb_rb, uint8_t subframe, - uint32_t rb_alloc, + uint32_t rb_alloc, uint16_t mod_order_0, - LTE_UE_DLSCH_t *dlsch0); + LTE_UE_DLSCH_t *dlsch0); void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, @@ -753,30 +753,30 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms, */ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, - int32_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, uint16_t mod_order_0, - LTE_UE_DLSCH_t *dlsch0); + LTE_UE_DLSCH_t *dlsch0); void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, - int32_t **sic_buffer, //Q15 - int32_t **rho_i, - int16_t *dlsch_llr, - uint8_t num_pdcch_symbols, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - uint16_t nb_rb, - uint8_t subframe, - uint32_t rb_alloc, + int32_t **sic_buffer, //Q15 + int32_t **rho_i, + int16_t *dlsch_llr, + uint8_t num_pdcch_symbols, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + uint16_t nb_rb, + uint8_t subframe, + uint32_t rb_alloc, uint16_t mod_order_0, - LTE_UE_DLSCH_t *dlsch0); + LTE_UE_DLSCH_t *dlsch0); void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, @@ -889,12 +889,12 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, uint8_t dual_stream_UE); void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *lte_ue_pdsch_vars, - int harq_pid, - int round, - unsigned char symbol, - unsigned short nb_rb, - unsigned char dual_stream_UE); + LTE_UE_PDSCH *lte_ue_pdsch_vars, + int harq_pid, + int round, + unsigned char symbol, + unsigned short nb_rb, + unsigned char dual_stream_UE); /** \fn dlsch_extract_rbs_single(int32_t **rxdataF, int32_t **dl_ch_estimates, @@ -966,8 +966,8 @@ uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF, uint8_t symbol, uint8_t subframe, uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms, - MIMO_mode_t mimo_mode); + LTE_DL_FRAME_PARMS *frame_parms, + MIMO_mode_t mimo_mode); /** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation) @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated @@ -1013,7 +1013,7 @@ void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_estimates_ext_i, int **dl_ch_rho_ext, unsigned char output_shift0, - unsigned char output_shift1); + unsigned char output_shift1); void dlsch_channel_compensation_TM56(int **rxdataF_ext, int **dl_ch_estimates_ext, @@ -1032,18 +1032,18 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *lte_ue_pdsch_vars, - PHY_MEASUREMENTS *phy_measurements, - int eNB_id, - unsigned char symbol, - unsigned char mod_order0, - unsigned char mod_order1, - int harq_pid, - int round, - MIMO_mode_t mimo_mode, - unsigned short nb_rb, - unsigned char output_shift0, - unsigned char output_shift1); + LTE_UE_PDSCH *lte_ue_pdsch_vars, + PHY_MEASUREMENTS *phy_measurements, + int eNB_id, + unsigned char symbol, + unsigned char mod_order0, + unsigned char mod_order1, + int harq_pid, + int round, + MIMO_mode_t mimo_mode, + unsigned short nb_rb, + unsigned char output_shift0, + unsigned char output_shift1); /** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal @@ -1061,13 +1061,13 @@ void dlsch_channel_level(int32_t **dl_ch_estimates_ext, void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - unsigned char *pmi_ext, - int *avg_0, - int *avg_1, - uint8_t symbol, - unsigned short nb_rb, - MIMO_mode_t mimo_mode); + LTE_DL_FRAME_PARMS *frame_parms, + unsigned char *pmi_ext, + int *avg_0, + int *avg_1, + uint8_t symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode); void dlsch_channel_level_TM56(int32_t **dl_ch_estimates_ext, @@ -1121,7 +1121,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, - RE extraction (pilot, PBCH, synch. signals) - antenna combining (MRC, Alamouti, cycling) - LLR computation - This function supports TM1, 2, 3, 5, and 6. + This function supports TM1, 2, 3, 5, and 6. @param phy_vars_ue Pointer to PHY variables @param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH) @param eNB_id eNb index (Nid1) 0,1,2 @@ -1129,19 +1129,19 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, @param subframe Subframe number @param symbol Symbol on which to act (within sub-frame) @param first_symbol_flag set to 1 on first DLSCH symbol - @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice. + @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice. @param i_mod Modulation order of the interfering stream */ int32_t rx_pdsch(PHY_VARS_UE *phy_vars_ue, - PDSCH_t type, - uint8_t eNB_id, - uint8_t eNB_id_i, - uint8_t subframe, - uint8_t symbol, - uint8_t first_symbol_flag, - RX_type_t rx_type, - uint8_t i_mod, - uint8_t harq_pid); + PDSCH_t type, + uint8_t eNB_id, + uint8_t eNB_id_i, + uint8_t subframe, + uint8_t symbol, + uint8_t first_symbol_flag, + RX_type_t rx_type, + uint8_t i_mod, + uint8_t harq_pid); int32_t rx_pdcch(LTE_UE_COMMON *lte_ue_common_vars, LTE_UE_PDCCH **lte_ue_pdcch_vars, @@ -1322,7 +1322,7 @@ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb); */ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap); -/* \brief Return prb for a given vrb index +/* \brief Return prb for a given vrb index @param vrb_type VRB type (0=localized,1=distributed) @param rb_alloc_dci rballoc field from DCI */ @@ -1437,7 +1437,7 @@ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t uint8_t subframe2harq_pid_eNBrx(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); int generate_ue_dlsch_params_from_dci(int frame, - uint8_t subframe, + uint8_t subframe, void *dci_pdu, rnti_t rnti, DCI_format_t dci_format, @@ -1676,7 +1676,7 @@ uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs); /** \brief This routine expands a single (wideband) PMI to subband PMI bitmap similar to the one used in the UCI and in the dlsch_modulation routine @param frame_parms Pointer to DL frame configuration parameters - @param wideband_pmi (0,1,2,3 for rank 0 and 0,1 for rank 1) + @param wideband_pmi (0,1,2,3 for rank 0 and 0,1 for rank 1) @param rank (0 or 1) @returns subband PMI bitmap */ @@ -1684,7 +1684,7 @@ uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_ /** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function @param N_RB_DL number of resource blocks - @param mimo_mode + @param mimo_mode @param pmi_alloc subband PMI bitmap @param rb resource block for which to extract PMI @returns subband PMI @@ -1692,11 +1692,11 @@ uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_ uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb); int get_nCCE_offset_l1(int *CCE_table, - const unsigned char L, - const int nCCE, - const int common_dci, - const unsigned short rnti, - const unsigned char subframe); + const unsigned char L, + const int nCCE, + const int common_dci, + const unsigned short rnti, + const unsigned char subframe); uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi); @@ -1758,22 +1758,22 @@ void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue, uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, - PUCCH_FMT_t fmt, - uint8_t UE_id, - uint16_t n1_pucch, - uint16_t n2_pucch, - uint8_t shortened_format, - uint8_t *payload, - int frame, - uint8_t subframe, - uint8_t pucch1_thres); + PUCCH_FMT_t fmt, + uint8_t UE_id, + uint16_t n1_pucch, + uint16_t n2_pucch, + uint8_t shortened_format, + uint8_t *payload, + int frame, + uint8_t subframe, + uint8_t pucch1_thres); int32_t rx_pucch_emul(PHY_VARS_eNB *phy_vars_eNB, - uint8_t UE_index, - PUCCH_FMT_t fmt, - uint8_t n1_pucch_sel, - uint8_t *payload, - uint8_t subframe); + uint8_t UE_index, + PUCCH_FMT_t fmt, + uint8_t n1_pucch_sel, + uint8_t *payload, + uint8_t subframe); /*! @@ -1865,18 +1865,19 @@ double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated); double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_eNB_DLSCH_t *dlsch_eNB, - int dl_power_off, - uint8_t n_antenna_port); + int dl_power_off, + uint8_t n_antenna_port); double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, PDSCH_CONFIG_COMMON *pdsch_config_common, uint8_t n_antenna_port, - LTE_eNB_DLSCH_t *dlsch_eNB,int dl_power_off); + LTE_eNB_DLSCH_t *dlsch_eNB, + int dl_power_off); double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_UE_DLSCH_t *dlsch_ue, uint8_t dl_power_off, - uint8_t n_antenna_port); + uint8_t n_antenna_port); double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, PDSCH_CONFIG_COMMON *pdsch_config_common, @@ -1890,7 +1891,7 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, LTE_UE_DLSCH_t *dlsch_ue); */ -uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf); +uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf); uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 9d941d3bd6..529f629771 100755 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -387,7 +387,7 @@ typedef struct PHY_VARS_eNB_s { #ifdef LOCALIZATION /// time state for localization time_stats_t localization_stats; -#endif +#endif int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX][10]; int32_t pucch1_stats[NUMBER_OF_UE_MAX][10*1024]; diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index e1736c9c9a..b47f95d270 100755 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -793,7 +793,7 @@ typedef struct { /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid /// - second index: ? [0..7] (hard coded) accessed via \c round /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - fourth index: ? [0..168*N_RB_DL[ + /// - fourth index: ? [0..168*N_RB_DL[ int32_t **rxdataF_comp1[8][8]; /// \brief Downlink channel estimates extracted in PRBS. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 0b39a3580a..e7408ac06a 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -38,6 +38,9 @@ \warning */ +//#define DEBUG_HARQ +//#define PRINT_THROUGHPUT + #include #include #include @@ -163,6 +166,7 @@ int main(int argc, char **argv) int n_users = 1; int TB=0; RX_type_t rx_type=rx_standard; + unsigned char cur_harq_pid; SCM_t channel_model=Rayleigh1; @@ -262,6 +266,7 @@ int main(int argc, char **argv) double thr_cw0_tm4 = 0.0; double thr_cw0_tm4_nonconst = 0.0; double thr_cw0[4]={0,0,0,0}, thr_cw1[4]={0,0,0,0}, thr_cw0_tot = 0.0, thr_cw1_tot = 0.0; + double tbs0_init=0.0, tbs1_init=0.0, rate0_init=0.0, rate1_init=0.0; char channel_model_input[17]="I"; int TB0_active = 1; @@ -597,7 +602,7 @@ int main(int argc, char **argv) printf("-o Sample offset for receiver\n"); printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); printf("-f step size of SNR, default value is 1.\n"); - printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); + printf("-r resource block allocation (see section 7.1.6.3 in 36.213\n"); printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T') \n"); printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); printf("-x Transmission mode (1,2,6 for the moment)\n"); @@ -607,7 +612,7 @@ int main(int argc, char **argv) printf("-R Number of HARQ rounds (fixed)\n"); printf("-A Turns on calibration mode for abstraction.\n"); printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); - printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); + printf("-O Set the percentage of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); printf("-I Input filename for TrCH data (binary)\n"); printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n"); exit(1); @@ -736,22 +741,26 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi4.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi4.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi4.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_pnort_rtpmi4.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",bler_fname); exit(-1); } + if ((transmission_mode != 3) && (transmission_mode != 4)) + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); + else + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2; trials0 r0; trials1 r0; err1_st1; err1_st2; trials0_r1; trials1_r1;; err2_st1; err2_st2; trials0_r2; trials1_r2; err3_st1; err3_st2; trials0_r3; trials1_r3; th0_r0; th1_r0; th_sum_r0; th0_r1; th1_r1; th_sum_r1; th0_r2; th1_r2; th_sum_r2; th0_r3; th1_r3; th_sum_r3; tot_th\n"); + - fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); if (test_perf != 0) { char hostname[1024]; @@ -791,104 +800,6 @@ int main(int argc, char **argv) } } - /* - //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames); - sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames); - tikz_fd = fopesprintf(csv_fname,"dataout_tx%d_mcs%d_mcs_interf%d_chan%d_nsimus%d_R%d_abstr_old_perf_ce_llr.m",transmission_mode,mcs1,mcs2,channel_model,n_frames,num_rounds); -n(tikz_fname,"w"); - //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {"); - switch (mcs) - { - case 0: - fprintf(tikz_fd,"\\addplot[color=blue, mark=star] plot coordinates {"); - break; - case 1: - fprintf(tikz_fd,"\\addplot[color=red, mark=star] plot coordinates {"); - break; - case 2: - fprintf(tikz_fd,"\\addplot[color=green, mark=star] plot coordinates {"); - break; - case 3: - fprintf(tikz_fd,"\\addplot[color=yellow, mark=star] plot coordinates {"); - break; - case 4: - fprintf(tikz_fd,"\\addplot[color=black, mark=star] plot coordinates {"); - break; - case 5: - fprintf(tikz_fd,"\\addplot[color=blue, mark=o] plot coordinates {"); - break; - case 6: - fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {"); - break; - case 7: - fprintf(tikz_fd,"\\addplot[color=green, mark=o] plot coordinates {"); - break; - case 8: - fprintf(tikz_fd,"\\addplot[color=yellow, mark=o] plot coordinates {"); - break; - case 9: - fprintf(tikz_fd,"\\addplot[color=black, mark=o] plot coordinates {"); - break; - case 10: - fprintf(tikz_fd,"\\addplot[color=blue, mark=square] plot coordinates {"); - break; - case 11: - fprintf(tikz_fd,"\\addplot[color=red, mark=square] plot coordinates {"); - break; - case 12: - fprintf(tikz_fd,"\\addplot[color=green, mark=square] plot coordinates {"); - break; - case 13: - fprintf(tikz_fd,"\\addplot[color=yellow, mark=square] plot coordinates {"); - break; - case 14: - fprintf(tikz_fd,"\\addplot[color=black, mark=square] plot coordinates {"); - break; - case 15: - fprintf(tikz_fd,"\\addplot[color=blue, mark=diamond] plot coordinates {"); - break; - case 16: - fprintf(tikz_fd,"\\addplot[color=red, mark=diamond] plot coordinates {"); - break; - case 17: - fprintf(tikz_fd,"\\addplot[color=green, mark=diamond] plot coordinates {"); - break; - case 18: - fprintf(tikz_fd,"\\addplot[color=yellow, mark=diamond] plot coordinates {"); - break; - case 19: - fprintf(tikz_fd,"\\addplot[color=black, mark=diamond] plot coordinates {"); - break; - case 20: - fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {"); - break; - case 21: - fprintf(tikz_fd,"\\addplot[color=red, mark=x] plot coordinates {"); - break; - case 22: - fprintf(tikz_fd,"\\addplot[color=green, mark=x] plot coordinates {"); - break; - case 23: - fprintf(tikz_fd,"\\addplot[color=yellow, mark=x] plot coordinates {"); - break; - case 24: - fprintf(tikz_fd,"\\addplot[color=black, mark=x] plot coordinates {"); - break; - case 25: - fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {"); - break; - case 26: - fprintf(tikz_fd,"\\addplot[color=red, mark=+] plot coordinates {"); - break; - case 27: - fprintf(tikz_fd,"\\addplot[color=green, mark=+] plot coordinates {"); - break; - case 28: - fprintf(tikz_fd,"\\addplot[color=yellow, mark=+] plot coordinates {"); - break; - } - */ - for (i=0; i<2; i++) { s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -1048,15 +959,6 @@ n(tikz_fname,"w"); } if (input_fd==NULL) { - /* - // common DCI - memcpy(&dci_alloc[num_dci].dci_pdu[0],&CCCH_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); - dci_alloc[num_dci].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_alloc[num_dci].L = 2; - dci_alloc[num_dci].rnti = SI_RNTI; - num_dci++; - num_common_dci++; - */ // UE specific DCI for(k=0; knb_antennas_tx; i++) { memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } + //PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + //memset(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[0], 0, (8*((3*8*6144)+12))*sizeof(int16_t)); + //memset(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], 0, (8*((3*8*6144)+12))*sizeof(int16_t)); //if (trials%100==0) eNB2UE[0]->first_run = 1; @@ -2144,20 +2052,33 @@ n(tikz_fname,"w"); resend_cw0_cw1=1; resend_cw1=0; + TB0_active=1; while (((transmission_mode == 3 || transmission_mode == 4) && - ((round < num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) && - (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations))) || + ((round < num_rounds) && ((ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) || + (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) || ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) { +#ifdef DEBUG_HARQ + printf("\n [DLSIM] On top round is %d\n", round); +#endif + + + round_trials[0][round]++; + round_trials[1][round]++; //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); - if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) + /*if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) { round_trials[0][round]++; - - if (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) round_trials[1][round]++; + } else if ((ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) && (ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) + round_trials[1][round]++;*/ + + +#ifdef DEBUG_HARQ + printf("[DLSIM] Just after while loop TB0 status %d round %d\n", TB0_active, round); +#endif // printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials TB0 = %d, round_trials TB1 = %d \n",trials,round, ret[0], ret[1], round_trials[0][round], round_trials[1][round]); @@ -2200,6 +2121,8 @@ n(tikz_fname,"w"); if (transmission_mode == 3 || transmission_mode == 4) PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rvidx = round&3; + //printf("TB0 status %d round %d \n ", TB0_active, round); + if (round == 0) { // First round TB0_active = 1; @@ -2303,6 +2226,7 @@ n(tikz_fname,"w"); break; case 5: + case 6: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); @@ -2401,6 +2325,7 @@ n(tikz_fname,"w"); } break; case 5: + case 6: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); @@ -2512,7 +2437,7 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2528,14 +2453,29 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - printf("\n Requesting only TB1 from temp DCI\n"); - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; +#ifdef DEBUG_HARQ + printf("\n[DLSIM] Requesting only TB1 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2, + PHY_vars_eNB->dlsch_eNB[0], + &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); + break; case 50: if (TB0_active==1) { @@ -2545,7 +2485,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2561,7 +2501,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2573,6 +2513,7 @@ n(tikz_fname,"w"); break; case 5: + case 6: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); @@ -2696,14 +2637,28 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - printf("\n Requesting only TB1 from temp DCI\n"); - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; +#ifdef DEBUG_HARQ + printf("\n [DLSIM] Requesting only TB1 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2, + PHY_vars_eNB->dlsch_eNB[0], + &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); break; case 50: if (TB0_active==1) { @@ -2713,7 +2668,7 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2729,7 +2684,7 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2742,6 +2697,7 @@ n(tikz_fname,"w"); case 5: + case 6: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); @@ -2764,10 +2720,18 @@ n(tikz_fname,"w"); exit(-1); } - for (k=0;kdlsch_eNB[0][TB] == NULL) - continue; + if (TB0_active == 0){ +#ifdef DEBUG_HARQ + printf("[DLSIM ENC] Skip TB0 \n"); +#endif + TB++; + + } +#ifdef DEBUG_HARQ + printf("[DLSIM ENC] process TB %d \n", TB); +#endif coded_bits_per_codeword[TB] = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->nb_rb, @@ -2776,8 +2740,6 @@ n(tikz_fname,"w"); PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Nl, num_pdcch_symbols, 0,subframe); - - #ifdef TBS_FIX // This is for MESH operation!!! tbs[TB] = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][TB]->nb_rb-1]/4; #else @@ -2842,7 +2804,7 @@ n(tikz_fname,"w"); subframe<<1); stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); - if (n_frames==1) { + if (n_frames==2) { for (s=0;sdlsch_eNB[k][TB]->harq_processes[0]->C;s++) { if (sdlsch_eNB[k][TB]->harq_processes[0]->Cminus) Kr = PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Kminus; @@ -2859,11 +2821,19 @@ n(tikz_fname,"w"); subframe, &PHY_vars_eNB->lte_frame_parms, num_pdcch_symbols, - PHY_vars_eNB->dlsch_eNB[k][0], + ((TB0_active == 1)? PHY_vars_eNB->dlsch_eNB[k][0]: NULL), PHY_vars_eNB->dlsch_eNB[k][1]); stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); } //n_users + + if (((transmission_mode == 3) || (transmission_mode == 4)) && (SNR == snr0) && (trials == 0) && (round == 0)){ + rate0_init = rate[0]; + rate1_init = rate[1]; + tbs0_init=tbs[0]; + tbs1_init=tbs[1]; + } + generate_pilots(PHY_vars_eNB, PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], AMP, @@ -2889,7 +2859,7 @@ n(tikz_fname,"w"); (subframe*2)+2, &PHY_vars_eNB->lte_frame_parms); - if (n_frames==1) { + if (n_frames==2) { write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); @@ -2903,7 +2873,7 @@ n(tikz_fname,"w"); } tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - if (n_frames==1) { + if (n_frames==2) { write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); @@ -2917,7 +2887,7 @@ n(tikz_fname,"w"); } tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - if (n_frames==1) { + if (n_frames==2) { printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti], PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1); } @@ -3061,7 +3031,7 @@ n(tikz_fname,"w"); // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated); sigma2 = pow(10,sigma2_dB/10); - if (n_frames==1) + if (n_frames==2) printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated)); for (i=0; i<2*frame_parms->samples_per_tti; i++) { @@ -3094,7 +3064,7 @@ n(tikz_fname,"w"); fclose(rx_frame_file); */ - if (n_frames==1) { + if (n_frames==2) { printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); @@ -3116,7 +3086,7 @@ n(tikz_fname,"w"); // Inner receiver scheduling for 3 slots for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) { for (l=0;ldlsch_ue[0][0]->current_harq_pid; + else + cur_harq_pid =PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid; + if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix if (transmission_mode == 5) { - if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->dl_power_off==0) && + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && (openair_daq_vars.use_ia_receiver ==1)) { rx_type = rx_IC_single_stream; } else { @@ -3403,6 +3379,7 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_llr_stats); for (m=PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols; mlte_ue_pdcch_vars[0]->num_pdcch_symbols)?1:0, rx_type, i_mod, - PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1){ + cur_harq_pid)==-1){ dlsch_active = 0; break; } @@ -3432,7 +3409,7 @@ n(tikz_fname,"w"); 0, rx_type, i_mod, - PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1){ + cur_harq_pid)==-1){ dlsch_active=0; break; } @@ -3452,7 +3429,7 @@ n(tikz_fname,"w"); 0, rx_type, i_mod, - PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid)==-1) { + cur_harq_pid)==-1) { dlsch_active=0; break; } @@ -3485,8 +3462,22 @@ n(tikz_fname,"w"); for (TB=0; TBdlsch_ue[0][TB] == NULL) - continue; + /* if (PHY_vars_UE->dlsch_ue[0][TB] == NULL){ + printf("[DLSIM] PHY_vars_UE->dlsch_ue[0][TB] == NULL\n"); + printf("HERE HERE HERE HERE\n"); + continue; + }*/ + + if (TB0_active == 0){ +#ifdef DEBUG_HARQ + printf("[DLSIM] Skip TB0 \n"); +#endif + TB++; + + } +#ifdef DEBUG_HARQ + printf("[DLSIM] process TB %d \n", TB); +#endif PHY_vars_UE->dlsch_ue[0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[TB] = get_G(&PHY_vars_eNB->lte_frame_parms, @@ -3500,7 +3491,7 @@ n(tikz_fname,"w"); PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs); - if (n_frames==1) { + if (n_frames==2) { printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB], PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->TBS); @@ -3551,21 +3542,27 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_decoding_stats); ret[TB] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[TB], - &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][TB], - PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid], - subframe, - PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid, - 1,llr8_flag); + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][TB], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid, + 1,llr8_flag); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); +#ifdef DEBUG_HARQ + printf("[DLSIM] ret[%d] = %d\n", TB, ret[TB]); +#endif + //printf("retr cw 0 = %d\n", ret[0]); //printf("current round = %d\n", PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->round); if (ret[TB] <= PHY_vars_UE->dlsch_ue[0][TB]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 - +#ifdef DEBUG_HARQ + printf("[DLSIM] TB%d is decoded\n", TB); +#endif /*avg_iter[TB] += ret[TB]; iter_trials[TB]++;*/ @@ -3690,8 +3687,11 @@ n(tikz_fname,"w"); } if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && - rx_type==rx_SIC_dual_stream) { + (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && + (rx_type==rx_SIC_dual_stream)) { +#ifdef DEBUG_HARQ + printf("[DLSIM] Starting SIC procedure\n"); +#endif // printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round); @@ -3699,10 +3699,14 @@ n(tikz_fname,"w"); //printf("\n ret[TB0] = %d round %d\n", ret[TB], round); for (round_sic = 0 ; round_sic < (round +1); round_sic++) { + +#ifdef DEBUG_HARQ + printf("[DLSIM] 0 Round sic = %d\n", round_sic); +#endif //printf("I enter round_sic loop \n"); //printf("round_sic= %d\n", round_sic); - dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; @@ -3730,7 +3734,7 @@ n(tikz_fname,"w"); &PHY_vars_UE->dlsch_interleaving_stats); - coded_bits_per_codeword[TB]= get_G(&PHY_vars_UE->lte_frame_parms, + coded_bits_per_codeword[0]= get_G(&PHY_vars_UE->lte_frame_parms, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), @@ -3752,38 +3756,39 @@ n(tikz_fname,"w"); num_pdcch_symbols, &PHY_vars_UE->dlsch_eNB[0][0], NULL, - coded_bits_per_codeword[TB]); + coded_bits_per_codeword[0]); // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); - switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->mcs)){ + switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ + case 2: dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], num_pdcch_symbols, dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), - PHY_vars_UE->dlsch_ue[eNB_id][TB]); + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); break; case 4: dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], @@ -3792,67 +3797,70 @@ n(tikz_fname,"w"); break; case 6: dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], sic_buffer, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], - get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), PHY_vars_UE->dlsch_ue[eNB_id][TB]); break; } - } + //}// rouns sic +#ifdef DEBUG_HARQ + printf("[DLSIM] TB1 is mapped into CW%d\n", PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword); +#endif // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); // replace cw_sic with TB+1 - PHY_vars_UE->dlsch_ue[0][TB+1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; - coded_bits_per_codeword[TB+1]= get_G(&PHY_vars_eNB->lte_frame_parms, - PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->nb_rb, - PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->rb_alloc, - get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->mcs), - PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->Nl, + PHY_vars_UE->dlsch_ue[0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword[1]= get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->Nl, num_pdcch_symbols, 0, subframe); - PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->G = coded_bits_per_codeword[TB+1]; - PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->mcs); + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs); - if (n_frames==1) { - printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,TB+1,coded_bits_per_codeword[TB+1], - PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->TBS); + if (n_frames==2) { + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->TBS); // calculate uncoded BER - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB+1]); + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB+1); - sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB+1); - write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[TB+1],coded_bits_per_codeword[TB+1],1,0); - sprintf(fname,"dlsch_cw%d_e.m", TB+1); - sprintf(vname,"dlschcw%d_e", TB+1); - write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->e,coded_bits_per_codeword[TB+1],1,4); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round,1); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, 1); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[1],coded_bits_per_codeword[1],1,0); + sprintf(fname,"dlsch_cw%d_e.m", 1); + sprintf(vname,"dlschcw%d_e", 1); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->e,coded_bits_per_codeword[1],1,4); uncoded_ber=0; printf("trials=%d\n", trials); - for (i=0;idlsch_eNB[0][TB+1]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword][i]<0)) { + for (i=0;idlsch_eNB[0][1]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } else uncoded_ber_bit[i] = 0; - uncoded_ber/=coded_bits_per_codeword[TB+1]; + uncoded_ber/=coded_bits_per_codeword[1]; avg_ber += uncoded_ber; - sprintf(fname,"cw%d_uncoded_ber_bit.m", TB+1); - sprintf(vname,"uncoded_ber_bit_cw%d", TB+1); - write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[TB+1],1,0); - printf("cw %d, uncoded ber %f\n",TB+1,uncoded_ber); + sprintf(fname,"cw%d_uncoded_ber_bit.m", 1); + sprintf(vname,"uncoded_ber_bit_cw%d", 1); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[1],1,0); + printf("cw %d, uncoded ber %f\n",1,uncoded_ber); free(uncoded_ber_bit); uncoded_ber_bit = NULL; } @@ -3860,84 +3868,102 @@ n(tikz_fname,"w"); start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, 0, - PHY_vars_UE->dlsch_ue[0][TB+1], - coded_bits_per_codeword[TB+1], - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], - TB+1, + PHY_vars_UE->dlsch_ue[0][1], + coded_bits_per_codeword[1], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + 1, subframe<<1); stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); ret[1] = dlsch_decoding(PHY_vars_UE, - PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid]->codeword], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], &PHY_vars_UE->lte_frame_parms, - PHY_vars_UE->dlsch_ue[0][TB+1], - PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid], + PHY_vars_UE->dlsch_ue[0][1], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid], subframe, - PHY_vars_UE->dlsch_ue[0][TB+1]->current_harq_pid, + PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid, 1,llr8_flag); stop_meas(&PHY_vars_UE->dlsch_decoding_stats); +#ifdef DEBUG_HARQ + printf("[DLSIM] Decoding TB1 in SIC: ret[1] = %d, round sic %d\n", ret[1], round_sic); +#endif + //printf("ret TB 1 = %d round %d \n", ret[1], round); - if (ret[TB+1] <= PHY_vars_UE->dlsch_ue[0][TB+1]->max_turbo_iterations ) { - - avg_iter[TB+1] += ret[TB+1]; - iter_trials[TB+1]++; + if (ret[1] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) { + round_sic = round+1; // to exit round_sic +#ifdef DEBUG_HARQ + printf("[DLSIM] TB1 is decoded in SIC loop\n"); +#endif + avg_iter[1] += ret[1]; + iter_trials[1]++; - if (n_frames==1) { - printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB+1,round,uncoded_ber); + if (n_frames==2) { + printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][TB+1]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][TB+1]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kminus; + for (s=0;sdlsch_ue[0][1]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][1]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kminus; else - Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kplus; + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch_ue[0][TB+1]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->c[s][i]); } #endif } - } else{ - errs[TB+1][round]++; + } + } //round_sic + + + if (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ){ + errs[1][round]++; +#ifdef DEBUG_HARQ + printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]); +#endif + // exit(0); - avg_iter[TB+1] += ret[TB+1]-1; - iter_trials[TB+1]++; + avg_iter[1] += ret[1]-1; + iter_trials[1]++; - if (n_frames==1) { + if (n_frames==2) { //if ((n_frames==1) || (SNR>=30)) { - printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",TB+1,round,uncoded_ber); + printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch_ue[0][TB+1]->harq_processes[0]->C;s++) { - if (sdlsch_ue[0][TB+1]->harq_processes[0]->Cminus) - Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kminus; + for (s=0;sdlsch_ue[0][1]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][1]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kminus; else - Kr = PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->Kplus; + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch_ue[0][TB+1]->harq_processes[0]->c[s][i], - PHY_vars_UE->dlsch_ue[0][TB+1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB+1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->c[s][i]); } #endif } //n_frames==1 // exit(0); - } //if (ret > PHY_vars_UE->dlsch_ue[0][TB+1]->max_turbo_iterations ) + } //if (ret > PHY_vars_UE->dlsch_ue[0][1]->max_turbo_iterations ) }//if SIC } else { errs[TB][round]++; +#ifdef DEBUG_HARQ + printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", TB, TB, round, errs[TB][round]); +#endif /*if (cw_non_sic==0) { @@ -3947,17 +3973,21 @@ n(tikz_fname,"w"); if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && - (rx_type==rx_SIC_dual_stream)) { - errs[TB+1][round]++; + (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) { + errs[1][round]++; +#ifdef DEBUG_HARQ + printf("[DLSIM] HERE OR NOT TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", 1, 1, round, errs[1][round]); +#endif } + /*if (cw_non_sic==1) { avg_iter[1] += ret[1]-1; iter_trials[1]++; }*/ - if (n_frames==1) { + if (n_frames==2) { //if ((n_frames==1) || (SNR>=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); #ifdef PRINT_BYTES @@ -3982,7 +4012,7 @@ n(tikz_fname,"w"); stop_meas(&PHY_vars_UE->phy_proc_rx); - if (n_frames==1) { + if (n_frames==2) { //rxsig sprintf(fname,"rxsig0_r%d.m",round); @@ -4068,10 +4098,11 @@ n(tikz_fname,"w"); 0,// UE_id subframe); } +#ifdef DEBUG_HARQ + printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]); +#endif - - - if ((transmission_mode != 3 && transmission_mode !=4 ) && ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ //printf("flag 1 \n"); round++; } @@ -4083,20 +4114,23 @@ n(tikz_fname,"w"); resend_cw0_cw1=1; //resend both cws resend_cw1=0; TB0_active=1; - //printf("flag 2 \n"); } if ((transmission_mode == 3 || transmission_mode == 4 ) && (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) && (ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ resend_one[round]++; - round++; resend_cw0_cw1=0; TB0_active=0; - //PHY_vars_UE->PHY_measurements.rank[eNB_id]=0; - // printf("\n DLSIM TB0 disactivated\n"); - //printf("flag 3 \n"); - +#ifdef DEBUG_HARQ + printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials); + printf("[DLSIM] TB0 deactivated\n"); +#endif + round++; } +#ifdef DEBUG_HARQ + printf("[DLSIM] Now round is %d, trial %d\n" , round, trials); +#endif + } @@ -4265,21 +4299,31 @@ n(tikz_fname,"w"); if (transmission_mode == 3 || transmission_mode == 4) { // FOR CW0 - thr_cw0[0] = rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])); - thr_cw0[1] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/2)*(((double)errs[0][0] - (double)errs[0][1])/(double)round_trials[0][0]); - thr_cw0[2] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/3)*(((double)errs[0][1] - (double)errs[0][2])/(double)round_trials[0][0]); - thr_cw0[3] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/4)*(((double)errs[0][2] - (double)errs[0][3])/(double)round_trials[0][0]); + thr_cw0[0] = rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])); + thr_cw0[1] = (rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/2)*(((double)errs[0][0] - (double)errs[0][1])/(double)round_trials[0][0]); + thr_cw0[2] = (rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/3)*(((double)errs[0][1] - (double)errs[0][2])/(double)round_trials[0][0]); + thr_cw0[3] = (rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/4)*(((double)errs[0][2] - (double)errs[0][3])/(double)round_trials[0][0]); thr_cw0_tot = (double)thr_cw0[0]+(double)thr_cw0[1]+(double)thr_cw0[2]+(double)thr_cw0[3]; - printf("\n Throughput cw0 sum = %f \n", thr_cw0_tot); +#ifdef PRINT_THROUGHPUT + printf("rate %f \n", rate0_init); + printf("rate*mod_order %f \n", rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)); + printf("Probability %f \n", (1-((double)errs[0][0]/(double)round_trials[0][0]))); + printf("Throughput cw0 sum = %f \n", thr_cw0_tot); + printf("Throughput cw0 round 0 = %f \n", thr_cw0[0]); + printf("Throughput cw0 round 1 = %f \n", thr_cw0[1]); + printf("Throughput cw0 round 2 = %f \n", thr_cw0[2]); + printf("Throughput cw0 round 3 = %f \n", thr_cw0[3]); printf("round_trials = %d, errs[0][0] = %d, round_trials[0][1] = %d, errs[0][1] = %d, round_trials[0][2] = %d, errs[0][2] = %d, \ round_trials[0][3] = %d, errs[0][3] = %d \n", round_trials[0][0], errs[0][0],round_trials[0][1], errs[0][1], round_trials[0][2], \ errs[0][2], round_trials[0][3], errs[0][3]); +#endif - thr_cw1[0] = rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])); - thr_cw1[1] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]); - thr_cw1[2] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/3)*(((double)errs[1][1] - (double)errs[1][2])/(double)round_trials[1][0]); - thr_cw1[3] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/4)*(((double)errs[1][2] - (double)errs[1][3])/(double)round_trials[1][0]); + thr_cw1[0] = rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])); + thr_cw1[1] = (rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]); + thr_cw1[2] = (rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/3)*(((double)errs[1][1] - (double)errs[1][2])/(double)round_trials[1][0]); + thr_cw1[3] = (rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/4)*(((double)errs[1][2] - (double)errs[1][3])/(double)round_trials[1][0]); thr_cw1_tot = (double)thr_cw1[0]+(double)thr_cw1[1]+(double)thr_cw1[2]+(double)thr_cw1[3]; +#ifdef PRINT_THROUGHPUT printf("Throughput cw1 sum = %f \n", thr_cw1_tot); printf("Throughput cw1 round 0 = %f \n", thr_cw1[0]); printf("Throughput cw1 round 1 = %f \n", thr_cw1[1]); @@ -4288,6 +4332,7 @@ n(tikz_fname,"w"); printf("round_trials[1][0] = %d, errs[1][0] = %d, round_trials[1][1] = %d, errs[1][1] = %d, round_trials[1][2] = %d, errs[1][2] = %d, \ round_trials[1][3] = %d, errs[1][3] = %d \n", round_trials[1][0], errs[1][0], round_trials[1][1], errs[1][1], round_trials[1][2], \ errs[1][2], round_trials[1][3], errs[1][3]); +#endif } #if 0 @@ -4494,27 +4539,39 @@ n(tikz_fname,"w"); SNR, mcs1, mcs2, - PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, - rate[0], - rate[1], + tbs0_init, + tbs1_init, + rate0_init, + rate1_init, errs[0][0], errs[1][0], round_trials[0][0], + round_trials[1][0], errs[0][1], errs[1][1], round_trials[0][1], + round_trials[1][1], errs[0][2], errs[1][2], round_trials[0][2], + round_trials[1][2], errs[0][3], errs[1][3], round_trials[0][3], - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])), - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])), - rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0]))+ - rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])), - dci_errors); + round_trials[1][3], + thr_cw0[0], + thr_cw1[0], + thr_cw0[0]+thr_cw1[0], + thr_cw0[1], + thr_cw1[1], + thr_cw0[1]+thr_cw1[1], + thr_cw0[2], + thr_cw1[2], + thr_cw0[2]+thr_cw1[2], + thr_cw0[3], + thr_cw1[3], + thr_cw0[3]+thr_cw1[3], + thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[4]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); } @@ -4742,7 +4799,7 @@ n(tikz_fname,"w"); } - if (n_frames==1) + if (n_frames==2) break; }// SNR diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 05995bf1f4..8f3cc7c8bd 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -1,5 +1,5 @@ /******************************************************************************* - OpenAirInterface + OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify @@ -14,15 +14,15 @@ 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, + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, see . Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@eurecom.fr - + Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ @@ -82,28 +82,28 @@ void fill_channel_desc(channel_desc_t *chan_desc, } else chan_desc->delays = delays; - chan_desc->Td = Td; + chan_desc->Td = Td; chan_desc->sampling_rate = sampling_rate; chan_desc->channel_bandwidth = channel_bandwidth; - chan_desc->ricean_factor = ricean_factor; - chan_desc->aoa = aoa; - chan_desc->random_aoa = random_aoa; - chan_desc->forgetting_factor = forgetting_factor; - chan_desc->channel_offset = channel_offset; - chan_desc->path_loss_dB = path_loss_dB; - chan_desc->first_run = 1; - chan_desc->ip = 0.0; - chan_desc->max_Doppler = max_Doppler; - chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); - chan_desc->a = (struct complex**) malloc(nb_taps*sizeof(struct complex*)); + chan_desc->ricean_factor = ricean_factor; + chan_desc->aoa = aoa; + chan_desc->random_aoa = random_aoa; + chan_desc->forgetting_factor = forgetting_factor; + chan_desc->channel_offset = channel_offset; + chan_desc->path_loss_dB = path_loss_dB; + chan_desc->first_run = 1; + chan_desc->ip = 0.0; + chan_desc->max_Doppler = max_Doppler; + chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->a = (struct complex**) malloc(nb_taps*sizeof(struct complex*)); LOG_D(OCM,"[CHANNEL] Filling ch \n"); - for (i = 0; ich[i] = (struct complex*) malloc(channel_length * sizeof(struct complex)); + for (i = 0; ich[i] = (struct complex*) malloc(channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); // allocate for up to 100 RBs, 12 samples per RB LOG_D(OCM,"[CHANNEL] Filling a (nb_taps %d)\n",nb_taps); @@ -118,8 +118,8 @@ void fill_channel_desc(channel_desc_t *chan_desc, for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; + chan_desc->R_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; } } } @@ -127,9 +127,9 @@ void fill_channel_desc(channel_desc_t *chan_desc, chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); - //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; - chan_desc->R_sqrt[i] = R_sqrt[0]; - } + //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; + chan_desc->R_sqrt[i] = R_sqrt[0]; + } } for (i = 0; inb_tx = nb_tx; - chan_desc->nb_rx = nb_rx; + chan_desc->nb_tx = nb_tx; + chan_desc->nb_rx = nb_rx; chan_desc->sampling_rate = sampling_rate; chan_desc->channel_bandwidth = channel_bandwidth; - chan_desc->forgetting_factor = forgetting_factor; - chan_desc->channel_offset = channel_offset; - chan_desc->path_loss_dB = path_loss_dB; - chan_desc->first_run = 1; - chan_desc->ip = 0.0; + chan_desc->forgetting_factor = forgetting_factor; + chan_desc->channel_offset = channel_offset; + chan_desc->path_loss_dB = path_loss_dB; + chan_desc->first_run = 1; + chan_desc->ip = 0.0; LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model); @@ -272,7 +272,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; } for (i = 0; inb_taps; i++) @@ -284,34 +284,34 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; } else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; } else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; } else { for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); } } break; @@ -323,7 +323,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; } for (i = 0; inb_taps; i++) @@ -335,34 +335,34 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); if (nb_tx==2 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; } else if (nb_tx==2 && nb_rx==1) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R21_sqrt[i][0]; } else if (nb_tx==1 && nb_rx==2) { - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R12_sqrt[i][0]; } else { for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx); } } break; @@ -373,7 +373,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; } for (i = 0; inb_taps; i++) @@ -385,26 +385,26 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; } else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } break; @@ -415,7 +415,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); sum_amps += chan_desc->amps[i]; } for (i = 0; inb_taps; i++) @@ -427,26 +427,26 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; } else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } break; @@ -457,7 +457,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); sum_amps += chan_desc->amps[i]; } for (i = 0; inb_taps; i++) @@ -469,26 +469,26 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); if (nb_tx==2 && nb_rx==2) { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); - for (i = 0; i<6; i++) - chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; + for (i = 0; i<6; i++) + chan_desc->R_sqrt[i] = (struct complex*) &R22_sqrt[i][0]; } else { chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); for (i = 0; i<6; i++) { - chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; - } - LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } } break; @@ -499,7 +499,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, sum_amps = 0; chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); for (i = 0; inb_taps; i++) { - chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); + chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); sum_amps += chan_desc->amps[i]; } for (i = 0; inb_taps; i++) @@ -511,19 +511,19 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); - for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); - for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); - for (i = 0; inb_taps; i++) + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex*)); for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); for (j = 0; jR_sqrt[i][j].x = 1.0; - chan_desc->R_sqrt[i][j].y = 0.0; + chan_desc->R_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; } LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } @@ -538,23 +538,23 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; fill_channel_desc(chan_desc, - nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; case Rice8: @@ -566,22 +566,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; case Rayleigh1: @@ -593,22 +593,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; case Rayleigh1_800: @@ -620,22 +620,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 800; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; case Rayleigh1_corr: @@ -647,31 +647,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; if ((nb_tx==2) && (nb_rx==1)) { - R_sqrt_ptr2 = R_sqrt_21_corr; + R_sqrt_ptr2 = R_sqrt_21_corr; } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_corr; + R_sqrt_ptr2 = R_sqrt_22_corr; } else - R_sqrt_ptr2 = NULL; + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; case Rayleigh1_anticorr: @@ -683,31 +683,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; if ((nb_tx==2) && (nb_rx==1)) { //check this - R_sqrt_ptr2 = R_sqrt_21_anticorr; + R_sqrt_ptr2 = R_sqrt_21_anticorr; } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_anticorr; + R_sqrt_ptr2 = R_sqrt_22_anticorr; } - else - R_sqrt_ptr2 = NULL; + else + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; case Rice1: @@ -719,22 +719,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; case AWGN: @@ -746,22 +746,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); printf("AWGN: ricean_factor %f\n",chan_desc->ricean_factor); break; @@ -775,22 +775,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - ts_shift_amps, - ts_shift_delays, - NULL, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + ts_shift_amps, + ts_shift_delays, + NULL, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); printf("TS_SHIFT: ricean_factor %f\n",chan_desc->ricean_factor); break; @@ -804,31 +804,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; if ((nb_tx==2) && (nb_rx==1)) { - R_sqrt_ptr2 = R_sqrt_21_corr; + R_sqrt_ptr2 = R_sqrt_21_corr; } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_corr; + R_sqrt_ptr2 = R_sqrt_22_corr; } else - R_sqrt_ptr2 = NULL; + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; case Rice1_anticorr: @@ -840,33 +840,33 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; if ((nb_tx==2) && (nb_rx==1)) { - R_sqrt_ptr2 = R_sqrt_21_anticorr; + R_sqrt_ptr2 = R_sqrt_21_anticorr; } else if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_anticorr; + R_sqrt_ptr2 = R_sqrt_22_anticorr; } - else - R_sqrt_ptr2 = NULL; + else + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; - + case Rayleigh1_orthogonal: nb_taps = 1; Td = 0; @@ -875,32 +875,32 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, aoa = 0.03; maxDoppler = 0; - + if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_orthogonal; + R_sqrt_ptr2 = R_sqrt_22_orthogonal; } - else - R_sqrt_ptr2 = NULL; + else + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - + case Rayleigh1_orth_eff_ch_TM4_prec_real: nb_taps = 1; Td = 0; @@ -909,32 +909,32 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, aoa = 0.03; maxDoppler = 0; - + if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; } - else - R_sqrt_ptr2 = NULL; + else + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 1); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 1); break; - + case Rayleigh1_orth_eff_ch_TM4_prec_imag: nb_taps = 1; Td = 0; @@ -943,42 +943,42 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, aoa = 0.03; maxDoppler = 0; - + if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; } - else - R_sqrt_ptr2 = NULL; + else + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc,nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amp_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_rx, + nb_taps, + channel_length, + default_amp_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - + case Rayleigh8_orth_eff_ch_TM4_prec_real: if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; - //R_sqrt_ptr2 = NULL; + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_real; + //R_sqrt_ptr2 = NULL; } - else - R_sqrt_ptr2 = NULL; + else + R_sqrt_ptr2 = NULL; + - nb_taps = 8; Td = 0.8; channel_length = (int)11+2*sampling_rate*Td; @@ -987,26 +987,26 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; fill_channel_desc(chan_desc, - nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); - + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); + break; - + case Rayleigh8_orth_eff_ch_TM4_prec_imag: nb_taps = 8; Td = 0.8; @@ -1016,31 +1016,31 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, maxDoppler = 0; if ((nb_tx==2) && (nb_rx==2)) { - R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; + R_sqrt_ptr2 = R_sqrt_22_orth_eff_ch_TM4_prec_imag; } - else - R_sqrt_ptr2 = NULL; + else + R_sqrt_ptr2 = NULL; fill_channel_desc(chan_desc, - nb_tx, - nb_rx, - nb_taps, - channel_length, - default_amps_lin, - NULL, - R_sqrt_ptr2, - Td, - sampling_rate, - channel_bandwidth, - ricean_factor, - aoa, - forgetting_factor, - maxDoppler, - channel_offset, - path_loss_dB, - 0); + nb_tx, + nb_rx, + nb_taps, + channel_length, + default_amps_lin, + NULL, + R_sqrt_ptr2, + Td, + sampling_rate, + channel_bandwidth, + ricean_factor, + aoa, + forgetting_factor, + maxDoppler, + channel_offset, + path_loss_dB, + 0); break; - + default: LOG_W(OCM,"channel model not yet supported\n"); free(chan_desc); @@ -1057,12 +1057,12 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { - + double s; int i,k,l,aarx,aatx; struct complex anew[NB_ANTENNAS_TX*NB_ANTENNAS_RX],acorr[NB_ANTENNAS_TX*NB_ANTENNAS_RX]; struct complex phase, alpha, beta; - + if ((desc->nb_tx>NB_ANTENNAS_TX) || (desc->nb_rx > NB_ANTENNAS_RX)) { msg("random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); return(-1); @@ -1073,26 +1073,26 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - anew[aarx+(aatx*desc->nb_rx)].x = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - anew[aarx+(aatx*desc->nb_rx)].y = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); + anew[aarx+(aatx*desc->nb_rx)].x = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); + anew[aarx+(aatx*desc->nb_rx)].y = sqrt(desc->ricean_factor*desc->amps[i]/2) * gaussdouble(0.0,1.0); - if ((i==0) && (desc->ricean_factor != 1.0)) { - if (desc->random_aoa==1) { - desc->aoa = uniformrandom()*2*M_PI; - } + if ((i==0) && (desc->ricean_factor != 1.0)) { + if (desc->random_aoa==1) { + desc->aoa = uniformrandom()*2*M_PI; + } - // this assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. - // Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so - // that we can safely assume plane wave propagation. - phase.x = cos(M_PI*((aarx-aatx)*sin(desc->aoa))); - phase.y = sin(M_PI*((aarx-aatx)*sin(desc->aoa))); - - anew[aarx+(aatx*desc->nb_rx)].x += phase.x * sqrt(1.0-desc->ricean_factor); - anew[aarx+(aatx*desc->nb_rx)].y += phase.y * sqrt(1.0-desc->ricean_factor); - } + // this assumes that both RX and TX have linear antenna arrays with lambda/2 antenna spacing. + // Furhter it is assumed that the arrays are parallel to each other and that they are far enough apart so + // that we can safely assume plane wave propagation. + phase.x = cos(M_PI*((aarx-aatx)*sin(desc->aoa))); + phase.y = sin(M_PI*((aarx-aatx)*sin(desc->aoa))); + + anew[aarx+(aatx*desc->nb_rx)].x += phase.x * sqrt(1.0-desc->ricean_factor); + anew[aarx+(aatx*desc->nb_rx)].y += phase.y * sqrt(1.0-desc->ricean_factor); + } #ifdef DEBUG_CH - printf("(%d,%d,%d) %f->(%f,%f) (%f,%f) phase (%f,%f)\n",aarx,aatx,i,desc->amps[i],anew[aarx+(aatx*desc->nb_rx)].x,anew[aarx+(aatx*desc->nb_rx)].y,desc->aoa,desc->ricean_factor,phase.x,phase.y); -#endif + printf("(%d,%d,%d) %f->(%f,%f) (%f,%f) phase (%f,%f)\n",aarx,aatx,i,desc->amps[i],anew[aarx+(aatx*desc->nb_rx)].x,anew[aarx+(aatx*desc->nb_rx)].y,desc->aoa,desc->ricean_factor,phase.x,phase.y); +#endif } //aatx } //aarx @@ -1100,9 +1100,9 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { // for debugging set a=anew; for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - desc->a[i][aarx+(aatx*desc->nb_rx)].x = anew[aarx+(aatx*desc->nb_rx)].x; - desc->a[i][aarx+(aatx*desc->nb_rx)].y = anew[aarx+(aatx*desc->nb_rx)].y; - printf("anew(%d,%d) = %f+1j*%f\n",aatx,aarx,anew[aarx+(aatx*desc->nb_rx)].x, anew[aarx+(aatx*desc->nb_rx)].y); + desc->a[i][aarx+(aatx*desc->nb_rx)].x = anew[aarx+(aatx*desc->nb_rx)].x; + desc->a[i][aarx+(aatx*desc->nb_rx)].y = anew[aarx+(aatx*desc->nb_rx)].y; + printf("anew(%d,%d) = %f+1j*%f\n",aatx,aarx,anew[aarx+(aatx*desc->nb_rx)].x, anew[aarx+(aatx*desc->nb_rx)].y); } } */ @@ -1113,16 +1113,16 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { beta.x = 0.0; beta.y = 0.0; - cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx, - (void*) &alpha, (void*) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, - (void*) anew, 1, (void*) &beta, (void*) acorr, 1); + cblas_zgemv(CblasRowMajor, CblasNoTrans, desc->nb_tx*desc->nb_rx, desc->nb_tx*desc->nb_rx, + (void*) &alpha, (void*) desc->R_sqrt[i/3], desc->nb_rx*desc->nb_tx, + (void*) anew, 1, (void*) &beta, (void*) acorr, 1); /* for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; - desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; - printf("tap %d, acorr1(%d,%d) = %f+1j*%f\n",i,aatx,aarx,acorr[aarx+(aatx*desc->nb_rx)].x, acorr[aarx+(aatx*desc->nb_rx)].y); + desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; + desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; + printf("tap %d, acorr1(%d,%d) = %f+1j*%f\n",i,aatx,aarx,acorr[aarx+(aatx*desc->nb_rx)].x, acorr[aarx+(aatx*desc->nb_rx)].y); } } */ @@ -1148,18 +1148,18 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { /* for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { - //desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; - //desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; - printf("tap %d, a(%d,%d) = %f+1j*%f\n",i,aatx,aarx,desc->a[i][aarx+(aatx*desc->nb_rx)].x, desc->a[i][aarx+(aatx*desc->nb_rx)].y); + //desc->a[i][aarx+(aatx*desc->nb_rx)].x = acorr[aarx+(aatx*desc->nb_rx)].x; + //desc->a[i][aarx+(aatx*desc->nb_rx)].y = acorr[aarx+(aatx*desc->nb_rx)].y; + printf("tap %d, a(%d,%d) = %f+1j*%f\n",i,aatx,aarx,desc->a[i][aarx+(aatx*desc->nb_rx)].x, desc->a[i][aarx+(aatx*desc->nb_rx)].y); } } */ - } //nb_taps + } //nb_taps stop_meas(&desc->random_channel); //memset((void *)desc->ch[aarx+(aatx*desc->nb_rx)],0,(int)(desc->channel_length)*sizeof(struct complex)); - + if (abstraction_flag==0) { start_meas(&desc->interp_time); @@ -1188,10 +1188,10 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { } //nb_taps #ifdef DEBUG_CH - k=0; - printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); + k=0; + printf("(%d,%d,%d)->(%f,%f)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y); #endif - } + } } //channel_length } //aatx } //aarx @@ -1211,22 +1211,22 @@ double N_RB2sampling_rate(uint16_t N_RB) case 6: sampling_rate = 1.92; break; - + case 25: sampling_rate = 7.68; break; - + case 50: sampling_rate = 15.36; break; - + case 100: sampling_rate = 30.72; break; - + default: LOG_E(PHY,"Unknown N_PRB\n"); - return(-1); + return(-1); } return(sampling_rate); @@ -1239,22 +1239,22 @@ double N_RB2channel_bandwidth(uint16_t N_RB) case 6: channel_bandwidth = 1.25; break; - + case 25: channel_bandwidth = 5.00; break; - + case 50: channel_bandwidth = 10.00; break; - + case 100: channel_bandwidth = 20.00; break; - + default: LOG_E(PHY,"Unknown N_PRB\n"); - return(-1); + return(-1); } return(channel_bandwidth); } @@ -1267,7 +1267,7 @@ main(int argc,char **argv) { double amps[8] = {.8,.2,.1,.04,.02,.01,.005}; struct complex ch[(int)(1+2*sampling_rate*Td)],phase; int i; - + randominit(); phase.x = 1.0; phase.y = 0; diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index d7d0543fae..6b98bbe7a7 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -46,7 +46,7 @@ static unsigned int seed, iy, ir[98]; #define a 1664525lu #define mod 4294967296.0 /* is 2**32 */ - +#if 1 void randominit(unsigned seed_init) { int i; @@ -69,17 +69,18 @@ void randominit(unsigned seed_init) } iy=1; -} +} +#endif - -/*void randominit(unsigned seed_init) +#if 0 +void randominit(unsigned seed_init) { int i; // this need to be integrated with the existing rng, like taus: navid msg("Initializing random number generator, seed %x\n",seed_init); seed_init = 62110; - + if (seed_init == 0) { srand((unsigned)time(NULL)); @@ -90,14 +91,14 @@ void randominit(unsigned seed_init) if (seed % 2 == 0) seed += 1; /* seed and mod are relative prime */ -// for (i=1; i<=97; i++) { -// seed = a*seed; /* mod 2**32 */ -// ir[i]= seed; /* initialize the shuffle table */ -// } - -// iy=1; -//} + for (i=1; i<=97; i++) { + seed = a*seed; /* mod 2**32 */ + ir[i]= seed; /* initialize the shuffle table */ + } + iy=1; +} +#endif /*!\brief Uniform linear congruential random number generator on \f$[0,1)\f$. Returns a double-precision floating-point number.*/ double uniformrandom(void) diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c index be2700d943..8ef3538867 100644 --- a/openair1/SIMULATION/TOOLS/taus.c +++ b/openair1/SIMULATION/TOOLS/taus.c @@ -58,7 +58,7 @@ unsigned int taus(void) s2 = (((s2 & 0xFFFFFFF0) << 17)^ b); return s0 ^ s1 ^ s2; } - +#if 1 void set_taus_seed(unsigned int seed_init) { @@ -87,9 +87,11 @@ void set_taus_seed(unsigned int seed_init) s2 = result; #endif } -} - -/* void set_taus_seed(unsigned int seed_init) +} +#endif + +#if 0 + void set_taus_seed(unsigned int seed_init) { #ifdef USER_MODE @@ -113,18 +115,17 @@ void set_taus_seed(unsigned int seed_init) s2 = (unsigned int)0xfe1a133e; #else // Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ - // srand48_r((long int)seed_init, &buffer); - // mrand48_r(&buffer, (long int *)&result); - // s0 = result; - // mrand48_r(&buffer, (long int *)&result); - // s1 = result; - // mrand48_r(&buffer, (long int *)&result); - // s2 = result; -//#endif - // } -//} - - + srand48_r((long int)seed_init, &buffer); + mrand48_r(&buffer, (long int *)&result); + s0 = result; + mrand48_r(&buffer, (long int *)&result); + s1 = result; + mrand48_r(&buffer, (long int *)&result); + s2 = result; +#endif + } +} +#endif #ifdef MAIN From 22609539b06d3f2f3adbb49ef7f5c16f61d78e2b Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 16 Nov 2016 23:15:26 +0100 Subject: [PATCH 114/571] Fixing DCI overwritinng during retransmissions. Modifying some printouts into the file. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3 + openair1/SIMULATION/LTE_PHY/dlsim.c | 192 ++++++++++++------ 3 files changed, 137 insertions(+), 62 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index d044ea45d8..7f585019e5 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1510,7 +1510,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, if ((rv2 == 1) && (mcs2 == 0)) { TB1_active=0; } - +#ifdef DEBUG_HARQ + printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rv1, rv2, mcs1, mcs2); +#endif if (TB0_active && TB1_active && tbswap==0) { dlsch0=dlsch[0]; dlsch1=dlsch[1]; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 0b16c1953f..4a75e9cbc8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -149,6 +149,9 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, codeword_TB1 = dlsch_ue[1]->harq_processes[harq_pid]->codeword; dlsch0_harq = dlsch_ue[codeword_TB0]->harq_processes[harq_pid]; dlsch1_harq = dlsch_ue[codeword_TB1]->harq_processes[harq_pid]; +#ifdef DEBUG_HARQ + printf("I am assuming both CW active\n"); +#endif } else if ((dlsch_ue[0]->harq_processes[harq_pid]->status == ACTIVE) && (dlsch_ue[1]->harq_processes[harq_pid]->status != ACTIVE) ) { diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index e7408ac06a..30bbac12e1 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -266,7 +266,9 @@ int main(int argc, char **argv) double thr_cw0_tm4 = 0.0; double thr_cw0_tm4_nonconst = 0.0; double thr_cw0[4]={0,0,0,0}, thr_cw1[4]={0,0,0,0}, thr_cw0_tot = 0.0, thr_cw1_tot = 0.0; - double tbs0_init=0.0, tbs1_init=0.0, rate0_init=0.0, rate1_init=0.0; + unsigned int tbs0_init=0, tbs1_init=0; + double rate0_init=0.0, rate1_init=0.0; + int mcs0_init=0, mcs1_init=0, mod_order0_init = 0, mod_order1_init=0; char channel_model_input[17]="I"; int TB0_active = 1; @@ -2195,6 +2197,9 @@ int main(int argc, char **argv) case 4: switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2202,6 +2207,9 @@ int main(int argc, char **argv) memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); break; case 25: + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2209,6 +2217,9 @@ int main(int argc, char **argv) memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); break; case 50: + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2216,6 +2227,9 @@ int main(int argc, char **argv) memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); break; case 100: + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2295,27 +2309,39 @@ int main(int argc, char **argv) case 4: switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); break; case 25: + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); break; case 50: + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); break; case 100: + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2431,13 +2457,16 @@ int main(int argc, char **argv) switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: if (TB0_active==1) { + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 4; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2447,6 +2476,9 @@ int main(int argc, char **argv) break; case 25: if (TB0_active==1) { + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2479,13 +2511,16 @@ int main(int argc, char **argv) break; case 50: if (TB0_active==1) { + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2495,13 +2530,16 @@ int main(int argc, char **argv) break; case 100: if (TB0_active==1) { + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2615,13 +2653,16 @@ int main(int argc, char **argv) switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: if (TB0_active==1) { + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2631,6 +2672,9 @@ int main(int argc, char **argv) break; case 25: if (TB0_active==1) { + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2662,13 +2706,16 @@ int main(int argc, char **argv) break; case 50: if (TB0_active==1) { + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2678,13 +2725,16 @@ int main(int argc, char **argv) break; case 100: if (TB0_active==1) { + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2832,6 +2882,10 @@ int main(int argc, char **argv) rate1_init = rate[1]; tbs0_init=tbs[0]; tbs1_init=tbs[1]; + mod_order0_init=get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs); + mod_order1_init=get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs); + mcs0_init=PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs; + mcs1_init=PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs; } generate_pilots(PHY_vars_eNB, @@ -3559,7 +3613,7 @@ int main(int argc, char **argv) - if (ret[TB] <= PHY_vars_UE->dlsch_ue[0][TB]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 + if (ret[TB] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 #ifdef DEBUG_HARQ printf("[DLSIM] TB%d is decoded\n", TB); #endif @@ -3976,7 +4030,7 @@ int main(int argc, char **argv) (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) { errs[1][round]++; #ifdef DEBUG_HARQ - printf("[DLSIM] HERE OR NOT TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", 1, 1, round, errs[1][round]); + printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", 1, 1, round, errs[1][round]); #endif } @@ -4120,7 +4174,7 @@ int main(int argc, char **argv) if ((transmission_mode == 3 || transmission_mode == 4 ) && (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) && (ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ resend_one[round]++; resend_cw0_cw1=0; - TB0_active=0; + TB0_active=0; #ifdef DEBUG_HARQ printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials); printf("[DLSIM] TB0 deactivated\n"); @@ -4192,9 +4246,10 @@ int main(int argc, char **argv) } //trials +#ifdef DEBUG_HARQ printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); printf(" one failed round 0 = %d, one failed round 1 = %d, one failed round 2 = %d, one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); - +#endif // round_trials[0]: number of code word : goodput the protocol double table_tx[time_vector_tx.size]; totable(table_tx, &time_vector_tx); @@ -4366,54 +4421,69 @@ int main(int argc, char **argv) SNR, (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), sigma2_dB); - - printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e))," - "dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f), " - "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n", - errs[0][0], - errs[1][0], - round_trials[0][0], - errs[0][1], - errs[1][1], - round_trials[0][0], - errs[0][2], - errs[1][2], - round_trials[0][0], - errs[0][3], - errs[1][3], - round_trials[0][0], - (double)errs[0][0]/(round_trials[0][0]), - (double)errs[1][0]/(round_trials[0][0]), - (double)errs[0][1]/(round_trials[0][0]), - (double)errs[1][1]/(round_trials[0][0]), - (double)errs[0][2]/(round_trials[0][0]), - (double)errs[1][2]/(round_trials[0][0]), - (double)errs[0][3]/(round_trials[0][0]), - (double)errs[1][3]/(round_trials[0][0]), - dci_errors, - round_trials[0][0], - (double)dci_errors/(round_trials[0][0]), - rate[0]*effective_rate, - 100*effective_rate, - rate[0], - rate[0]*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), - (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+ - 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, - (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) - +4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]), - thr_cw0_tot, - thr_cw1_tot, - thr_cw0_tot + thr_cw1_tot, - rate[0], - rate[1]); - - - - - - - - + if ((transmission_mode != 3) && (transmission_mode != 4)){ + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e))," + "dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f), " + "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n", + errs[0][0], + errs[1][0], + round_trials[0][0], + errs[0][1], + errs[1][1], + round_trials[0][0], + errs[0][2], + errs[1][2], + round_trials[0][0], + errs[0][3], + errs[1][3], + round_trials[0][0], + (double)errs[0][0]/(round_trials[0][0]), + (double)errs[1][0]/(round_trials[0][0]), + (double)errs[0][1]/(round_trials[0][0]), + (double)errs[1][1]/(round_trials[0][0]), + (double)errs[0][2]/(round_trials[0][0]), + (double)errs[1][2]/(round_trials[0][0]), + (double)errs[0][3]/(round_trials[0][0]), + (double)errs[1][3]/(round_trials[0][0]), + dci_errors, + round_trials[0][0], + (double)dci_errors/(round_trials[0][0]), + rate[0]*effective_rate, + 100*effective_rate, + rate[0], + rate[0]*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+ + 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) + +4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]), + thr_cw0_tot, + thr_cw1_tot, + thr_cw0_tot + thr_cw1_tot, + rate[0], + rate[1]); + }else{ + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d)," + "dci_errors %d/%d, thr TB0 = %f , thr TB1 = %f, overall thr = %f , rate 0 = %f , rate 1 = %f \n", + errs[0][0], + errs[1][0], + round_trials[0][0], + errs[0][1], + errs[1][1], + round_trials[0][0], + errs[0][2], + errs[1][2], + round_trials[0][0], + errs[0][3], + errs[1][3], + round_trials[0][0], + dci_errors, + round_trials[0][0], + thr_cw0_tot, + thr_cw1_tot, + thr_cw0_tot + thr_cw1_tot, + rate0_init, + rate1_init); + } if (print_perf==1) { printf("eNB TX function statistics (per 1ms subframe)\n\n"); @@ -4535,7 +4605,7 @@ int main(int argc, char **argv) dci_errors); } else { - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%d\n", + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", SNR, mcs1, mcs2, @@ -4571,7 +4641,7 @@ int main(int argc, char **argv) thr_cw0[3], thr_cw1[3], thr_cw0[3]+thr_cw1[3], - thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[4]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); + thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); } From 6fe8c9acec3305181c15eb399ef52f3ddf56094b Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Sat, 19 Nov 2016 01:02:16 +0100 Subject: [PATCH 115/571] Implementing PUSCH precoding option for the TB1 retransmission in TM4. The independent retransmission of TB1 will take data from the last PUSCH report, when both TB were active and keep it for all the retransmission rounds. Now the TPMI for the retransmissions of TB1 is passed from the command line with -K(tpmi): -K0 for Alamouti, -K5 for PUSCH column1 , etc. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 62 ++++++++++++++++++-- openair1/PHY/LTE_TRANSPORT/proto.h | 2 + openair1/SIMULATION/LTE_PHY/dlsim.c | 81 ++++++++++++++++++++------ 3 files changed, 123 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 7f585019e5..52b7d52f1e 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5128,12 +5128,19 @@ int generate_ue_dlsch_params_from_dci(int frame, case 5: dlsch1_harq->mimo_mode = PUSCH_PRECODING0; // pmi stored from ulsch allocation routine - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch1_harq->pmi_alloc = dlsch1->pmi_alloc; +#ifdef DEBUG_HARQ + printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch1->pmi_alloc); +#endif + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); break; case 6: dlsch1_harq->mimo_mode = PUSCH_PRECODING1; - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; + dlsch1_harq->pmi_alloc = dlsch1->pmi_alloc; +#ifdef DEBUG_HARQ + printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch1->pmi_alloc); +#endif return(-1); break; } @@ -6069,6 +6076,52 @@ uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, ui } +int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb) +{ + int nb_subbands = 0; + int32_t pmi_alloc_new = 0, pmi_new = 0, pmi_old = 0; + int i; + + switch (nb_rb) { + case 6: + nb_subbands = 6; + break; + default: + case 25: + nb_subbands = 7; + break; + case 50: + nb_subbands = 9; + break; + case 100: + nb_subbands = 13; + break; + } + + for (i = 0; i < nb_subbands; i++) { + pmi_old = (pmi_alloc >> i)&1; + + if (pmi_old == 0) + if (tpmi == 5) + pmi_new = 0; + else + pmi_new = 1; + else + if (tpmi == 5) + pmi_new = 2; + else + pmi_new = 3; + + pmi_alloc_new|=pmi_new<<(2*i); + + } +#ifdef DEBUG_HARQ +printf(" [DCI UE] pmi_alloc_old %d, pmi_alloc_new %d pmi_old %d , pmi_new %d\n", pmi_alloc, pmi_alloc_new,pmi_old, pmi_new ); +#endif +return(pmi_alloc_new); + +} + uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) { @@ -6150,8 +6203,9 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) } } - // printf( "pmivect %d \n", pmivect); - +#ifdef DEBUG_HARQ + printf( "quantize_subband_pmi pmivect %d \n", pmivect); +#endif return(pmivect); } diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index b4874569ae..d7b223455b 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1664,6 +1664,8 @@ void reset_cba_uci(void *o); */ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subbands); +int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb); + //uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands); uint64_t pmi2hex_2Ar1(uint32_t pmi); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 30bbac12e1..79ff3c94f9 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -46,7 +46,7 @@ #include #include #include - +#include #include "SIMULATION/TOOLS/defs.h" #include "PHY/types.h" #include "PHY/defs.h" @@ -167,6 +167,8 @@ int main(int argc, char **argv) int TB=0; RX_type_t rx_type=rx_standard; unsigned char cur_harq_pid; + int hold_rank1_precoder=0; + int tpmi_retr=2; SCM_t channel_model=Rayleigh1; @@ -232,6 +234,7 @@ int main(int argc, char **argv) int ch_realization; int pmi_feedback=0; int hold_channel=0; + bool is_first_time; // temporarily for retransmissions: unsigned char resend_cw1=0; //if 0 resend only cw0 @@ -272,6 +275,7 @@ int main(int argc, char **argv) char channel_model_input[17]="I"; int TB0_active = 1; + uint32_t perfect_ce = 0; LTE_DL_UE_HARQ_t *dlsch0_ue_harq; @@ -326,7 +330,7 @@ int main(int argc, char **argv) // num_layers = 1; perfect_ce = 0; - while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XYv:W:J:")) != -1) { + while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XYv:W:J:K:")) != -1) { switch (c) { case 'a': @@ -590,6 +594,10 @@ int main(int argc, char **argv) case 'J': interf_unaw_shift=atoi(optarg); break; + case 'K': + tpmi_retr = atoi(optarg); + //i_mod = get_Qm(mcs2); /// think here again!!! + break; case 'h': default: printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); @@ -743,14 +751,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi4.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi0.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi4.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi0.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi4.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi0.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_pnort_rtpmi4.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_pnort_rtpmi0.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -2036,9 +2044,11 @@ int main(int argc, char **argv) //printf("Trial %d\n",trials); fflush(stdout); round = 0; + is_first_time = true; #ifdef DEBUG_HARQ printf("[DLSIM] TRIAL %d\n", trials); #endif + printf("TPMI_retr= %d\n", tpmi_retr); for (i=0; inb_antennas_tx; i++) { memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); @@ -2466,7 +2476,7 @@ int main(int argc, char **argv) ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 4; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = tpmi_retr; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2488,7 +2498,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf("\n[DLSIM] Requesting only TB1 from temp DCI\n"); #endif - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2506,8 +2516,8 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single); - + PHY_vars_UE->dlsch_ue[0][1]->pmi_alloc + ); break; case 50: if (TB0_active==1) { @@ -2520,7 +2530,7 @@ int main(int argc, char **argv) ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2539,7 +2549,7 @@ int main(int argc, char **argv) ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2662,7 +2672,7 @@ int main(int argc, char **argv) ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2684,7 +2694,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf("\n [DLSIM] Requesting only TB1 from temp DCI\n"); #endif - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2702,7 +2712,8 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single); + PHY_vars_UE->dlsch_ue[0][1]->pmi_alloc + ); break; case 50: if (TB0_active==1) { @@ -2715,7 +2726,7 @@ int main(int argc, char **argv) ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2734,7 +2745,7 @@ int main(int argc, char **argv) ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } else { // deactivate TB0 - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 4; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; @@ -2828,8 +2839,27 @@ int main(int argc, char **argv) PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); } + if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } - + if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } start_meas(&PHY_vars_eNB->dlsch_encoding_stats); if (dlsch_encoding(((TB==0) ? input_buffer0[k] : input_buffer1[k]), @@ -3204,6 +3234,9 @@ int main(int argc, char **argv) } if ((Ns==((2*subframe))) && (l==0)) { +#ifdef DEBUG_HARQ + +#endif lte_ue_measurements(PHY_vars_UE, subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti, 1, @@ -3236,8 +3269,13 @@ int main(int argc, char **argv) if (pmi_feedback == 1) { pmi_feedback = 0; hold_channel = 1; + if (hold_rank1_precoder == 0) + hold_rank1_precoder = 1; //printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback); //printf ("go to PMI feedback\n"); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am doing measurements and coming back to reencoding\n"); +#endif goto PMI_FEEDBACK; } } @@ -4175,6 +4213,13 @@ int main(int argc, char **argv) resend_one[round]++; resend_cw0_cw1=0; TB0_active=0; + if(is_first_time) { + hold_rank1_precoder = 0; + is_first_time = false; + } + else + hold_rank1_precoder = 1; + #ifdef DEBUG_HARQ printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials); printf("[DLSIM] TB0 deactivated\n"); From d9b32975c91e27cc00cedb924888773542e6d33f Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Sat, 19 Nov 2016 14:20:54 +0100 Subject: [PATCH 116/571] Fixing some printouts into .csv file for TM4. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 79ff3c94f9..041a6576e8 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -751,14 +751,14 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1) if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi0.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi0.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift ); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); else //abstx=0 if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi0.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_pnort_rtpmi0.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_pnort_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -768,7 +768,7 @@ int main(int argc, char **argv) if ((transmission_mode != 3) && (transmission_mode != 4)) fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); else - fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2; trials0 r0; trials1 r0; err1_st1; err1_st2; trials0_r1; trials1_r1;; err2_st1; err2_st2; trials0_r2; trials1_r2; err3_st1; err3_st2; trials0_r3; trials1_r3; th0_r0; th1_r0; th_sum_r0; th0_r1; th1_r1; th_sum_r1; th0_r2; th1_r2; th_sum_r2; th0_r3; th1_r3; th_sum_r3; tot_th\n"); + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2; trials0 r0; trials1 r0; err1_st1; err1_st2; trials0_r1; trials1_r1; err2_st1; err2_st2; trials0_r2; trials1_r2; err3_st1; err3_st2; trials0_r3; trials1_r3; th0_r0; th1_r0; th_sum_r0; th0_r1; th1_r1; th_sum_r1; th0_r2; th1_r2; th_sum_r2; th0_r3; th1_r3; th_sum_r3; tot_th\n"); if (test_perf != 0) { @@ -2047,8 +2047,8 @@ int main(int argc, char **argv) is_first_time = true; #ifdef DEBUG_HARQ printf("[DLSIM] TRIAL %d\n", trials); -#endif printf("TPMI_retr= %d\n", tpmi_retr); +#endif for (i=0; inb_antennas_tx; i++) { memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); From 8cb78dc4d52dca832f0856ad101192e7ddc46f3d Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Mon, 21 Nov 2016 22:18:21 +0100 Subject: [PATCH 117/571] Adding the updated CSI option for retransmission of TB1 in TM4. Pass -U from the command line to enable. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 107 ++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 041a6576e8..c07169a5c1 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -169,6 +169,8 @@ int main(int argc, char **argv) unsigned char cur_harq_pid; int hold_rank1_precoder=0; int tpmi_retr=2; + bool is_first_time; + int updated_csi = 0; SCM_t channel_model=Rayleigh1; @@ -234,7 +236,7 @@ int main(int argc, char **argv) int ch_realization; int pmi_feedback=0; int hold_channel=0; - bool is_first_time; + // temporarily for retransmissions: unsigned char resend_cw1=0; //if 0 resend only cw0 @@ -330,7 +332,7 @@ int main(int argc, char **argv) // num_layers = 1; perfect_ce = 0; - while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XYv:W:J:K:")) != -1) { + while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XYv:W:J:K:U")) != -1) { switch (c) { case 'a': @@ -598,6 +600,9 @@ int main(int argc, char **argv) tpmi_retr = atoi(optarg); //i_mod = get_Qm(mcs2); /// think here again!!! break; + case 'U': + updated_csi=1; + break; case 'h': default: printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); @@ -2835,32 +2840,89 @@ int main(int argc, char **argv) //Here need to add cases for TPMI 6 and TPMI 5 and check for both TB. if (transmission_mode == 4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); } - if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ + if (updated_csi == 0){ + + if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 1\n"); + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + } else if (updated_csi == 1){ + + + if ((transmission_mode == 4) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] Updating CSI\n"); + printf ("[DLSIM] I quantize from ENodeB 1\n"); +#endif + + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); #endif PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 2\n"); + printf ("[DLSIM] I quantize from ENodeB 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); } - if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ + if ((transmission_mode == 4) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 1\n"); + printf ("[DLSIM] Updating CSI\n"); + printf ("[DLSIM] I quantize from ENodeB 1\n"); +#endif + + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); #endif PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 2\n"); + printf ("[DLSIM] I quantize from ENodeB 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); } + } + start_meas(&PHY_vars_eNB->dlsch_encoding_stats); if (dlsch_encoding(((TB==0) ? input_buffer0[k] : input_buffer1[k]), &PHY_vars_eNB->lte_frame_parms, @@ -3039,20 +3101,20 @@ int main(int argc, char **argv) // Multipath channel if (awgn_flag == 0) { - multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, - 2*frame_parms->samples_per_tti,hold_channel); - // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); - if(abstx==1 && num_rounds>1) - if(round==0 && hold_channel==0){ - random_channel(eNB2UE[1],0); - random_channel(eNB2UE[2],0); - random_channel(eNB2UE[3],0); + multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, + 2*frame_parms->samples_per_tti,hold_channel); + // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); + if(abstx==1 && num_rounds>1) + if(round==0 && hold_channel==0){ + random_channel(eNB2UE[1],0); + random_channel(eNB2UE[2],0); + random_channel(eNB2UE[3],0); + } + if (PHY_vars_UE->perfect_ce==1){ + freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); + // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); } - if (PHY_vars_UE->perfect_ce==1){ - freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); - // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); - // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); - } } if(abstx){ // TODO: check the rounds here!! @@ -3269,8 +3331,11 @@ int main(int argc, char **argv) if (pmi_feedback == 1) { pmi_feedback = 0; hold_channel = 1; + + if (updated_csi==0) { if (hold_rank1_precoder == 0) hold_rank1_precoder = 1; + } //printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback); //printf ("go to PMI feedback\n"); #ifdef DEBUG_HARQ From 7a6ef377b51f6edf4e7c63f9864d2467988ad47d Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Tue, 22 Nov 2016 00:30:08 +0100 Subject: [PATCH 118/571] Fixing a bug in dlsch_demodulation.c for llr calls. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 10 +++++----- openair1/SIMULATION/LTE_PHY/dlsim.c | 6 +----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 4a75e9cbc8..aa7e8fe283 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -776,7 +776,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, switch (dlsch0_harq->Qm) { case 2 : - if ((rx_type==rx_standard) || (codeword_TB0 = 1)) { + if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { dlsch_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, lte_ue_pdsch_vars[eNB_id]->llr[0], @@ -852,7 +852,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } break; case 4 : - if ((rx_type==rx_standard ) || (codeword_TB0 = 1) ) { + if ((rx_type==rx_standard ) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { dlsch_16qam_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, lte_ue_pdsch_vars[eNB_id]->llr[0], @@ -861,7 +861,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128); } - else if ((rx_type >= rx_IC_single_stream) && (codeword_TB0 != -1)) { + else if (rx_type >= rx_IC_single_stream) { if (dlsch1_harq->Qm == 2) { dlsch_16qam_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, @@ -935,7 +935,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, } break; case 6 : - if ((rx_type==rx_standard) || (codeword_TB0 == -1)) { + if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { dlsch_64qam_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, lte_ue_pdsch_vars[eNB_id]->llr[0], @@ -945,7 +945,7 @@ int rx_pdsch(PHY_VARS_UE *phy_vars_ue, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), lte_ue_pdsch_vars[eNB_id]->llr128); } - else if ((rx_type >= rx_IC_single_stream) && (codeword_TB0 != -1)){ + else if (rx_type >= rx_IC_single_stream) { if (dlsch1_harq->Qm == 2) { dlsch_64qam_qpsk_llr(frame_parms, lte_ue_pdsch_vars[eNB_id]->rxdataF_comp0, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index c07169a5c1..4639a0cfe2 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -3619,11 +3619,6 @@ int main(int argc, char **argv) for (TB=0; TBdlsch_ue[0][TB] == NULL){ - printf("[DLSIM] PHY_vars_UE->dlsch_ue[0][TB] == NULL\n"); - printf("HERE HERE HERE HERE\n"); - continue; - }*/ if (TB0_active == 0){ #ifdef DEBUG_HARQ @@ -4164,6 +4159,7 @@ int main(int argc, char **argv) #endif } } + if (rx_type==rx_SIC_dual_stream) TB++; // to terminate the loop over TB } From 5869ec96337aa021d3f3cb93deecc9c3184f4237 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Tue, 22 Nov 2016 23:25:18 +0100 Subject: [PATCH 119/571] Modifying names of output files for updated CSI. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 30 +++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 4639a0cfe2..178b58a755 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -754,16 +754,30 @@ int main(int argc, char **argv) SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); if(transmission_mode==5) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); - else if (abstx == 1) + else if (abstx == 1){ if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); else sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); - else //abstx=0 - if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); - else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_pnort_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + else {//abstx=0 + if (perfect_ce==1){ + if (updated_csi==1){ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + else{ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + } + else{ + if (updated_csi==1){ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + else{ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%d.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + } + } bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { @@ -2839,7 +2853,7 @@ int main(int argc, char **argv) } //Here need to add cases for TPMI 6 and TPMI 5 and check for both TB. - if (transmission_mode == 4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ + if (transmission_mode == 4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) && (TB0_active == 1)){ #ifdef DEBUG_HARQ printf ("[DLSIM] I am calling from the eNode B 1\n"); #endif From 8cfd5f29f6805a55838ce75f9e1f2b993f3457bc Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Thu, 24 Nov 2016 15:00:14 +0100 Subject: [PATCH 120/571] Adding spatial low, medium and high correlation matrices for 2x2 EPA channel model. -gV, -gW, -gX. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 11 +- openair1/SIMULATION/TOOLS/defs.h | 3 + openair1/SIMULATION/TOOLS/random_channel.c | 153 +++++++++++++++++++++ 3 files changed, 166 insertions(+), 1 deletion(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 178b58a755..58aae368ce 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -517,6 +517,15 @@ int main(int argc, char **argv) case 'U': channel_model = TS_SHIFT; break; + case 'V': + channel_model=EPA_low; + break; + case 'W': + channel_model=EPA_medium; + break; + case 'X': + channel_model=EPA_high; + break; default: msg("Unsupported channel model!\n"); exit(-1); @@ -618,7 +627,7 @@ int main(int argc, char **argv) printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); printf("-f step size of SNR, default value is 1.\n"); printf("-r resource block allocation (see section 7.1.6.3 in 36.213\n"); - printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T') \n"); + printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T'), EPA_low ('V'), EPA_medium ('W'), EPA_high ('X') \n"); printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); printf("-x Transmission mode (1,2,6 for the moment)\n"); printf("-y Number of TX antennas used in eNB\n"); diff --git a/openair1/SIMULATION/TOOLS/defs.h b/openair1/SIMULATION/TOOLS/defs.h index 64e8d0561c..ca2f515d20 100644 --- a/openair1/SIMULATION/TOOLS/defs.h +++ b/openair1/SIMULATION/TOOLS/defs.h @@ -183,6 +183,9 @@ typedef enum { Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT, + EPA_low, + EPA_medium, + EPA_high, } SCM_t; /** diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 8f3cc7c8bd..bb7125840d 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -224,6 +224,25 @@ struct complex R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap[16] = {{0.70711,0.0}, {0. {0.0, 0.0}, {0.0,0.70711}, {0.0, 0.0}, {-0.70711,0.0}}; struct complex *R_sqrt_22_orth_eff_ch_TM4_prec_imag[1] = {R_sqrt_22_orth_eff_ch_TM4_prec_imag_tap}; +//Correlation matrix for EPA channel +struct complex R_sqrt_22_EPA_low_tap[16] = {{1.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, + {0.0,0.0}, {1.0,0.0}, {0.0,0.0}, {0.0,0.0}, + {0.0,0.0}, {0.0,0.0}, {1.0,0.0}, {0.0,0.0}, + {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {1.0,0.0}}; +struct complex *R_sqrt_22_EPA_low[1] = {R_sqrt_22_EPA_low_tap}; + +struct complex R_sqrt_22_EPA_high_tap[16] = {{0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0}, + {0.4500,0.0}, {0.7179,0.0}, {0.2821,0.0}, {0.4500,0.0}, + {0.4500,0.0}, {0.2821,0.0}, {0.7179,0.0}, {0.4500,0.0}, + {0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0}}; +struct complex *R_sqrt_22_EPA_high[1] = {R_sqrt_22_EPA_high_tap}; + +struct complex R_sqrt_22_EPA_medium_tap[16] = {{0.8375,0.0}, {0.5249,0.0}, {0.1286,0.0}, {0.0806,0.0}, + {0.5249,0.0}, {0.8375,0.0}, {0.0806,0.0}, {0.1286,0.0}, + {0.1286,0.0}, {0.0806,0.0}, {0.8375,0.0}, {0.5249,0.0}, + {0.0806,0.0}, {0.1286,0.0}, {0.5249,0.0}, {0.8375,0.0}}; +struct complex *R_sqrt_22_EPA_medium[1] = {R_sqrt_22_EPA_medium_tap}; + //Rayleigh1_orth_eff_ch_TM4 @@ -408,6 +427,140 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } } break; + case EPA_low: + chan_desc->nb_taps = 7; + chan_desc->Td = .410; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + chan_desc->delays = epa_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex**)); + for (i = 0; inb_taps; i++) + chan_desc->R_sqrt[i] = R_sqrt_22_EPA_low[0]; + } + else { + printf("Correlation matrices are implemented for 2 x 2 only"); + } + /*else { + chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + }*/ + break; + case EPA_high: + chan_desc->nb_taps = 7; + chan_desc->Td = .410; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + chan_desc->delays = epa_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex**)); + for (i = 0; inb_taps; i++) + chan_desc->R_sqrt[i] = R_sqrt_22_EPA_high[0]; + } + else { + printf("Correlation matrices are implemented for 2 x 2 only"); + } + /*else { + chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + }*/ + break; + case EPA_medium: + chan_desc->nb_taps = 7; + chan_desc->Td = .410; + chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); + sum_amps = 0; + chan_desc->amps = (double*) malloc(chan_desc->nb_taps*sizeof(double)); + for (i = 0; inb_taps; i++) { + chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); + sum_amps += chan_desc->amps[i]; + } + for (i = 0; inb_taps; i++) + chan_desc->amps[i] /= sum_amps; + chan_desc->delays = epa_delays; + chan_desc->ricean_factor = 1; + chan_desc->aoa = 0; + chan_desc->random_aoa = 0; + chan_desc->ch = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->chF = (struct complex**) malloc(nb_tx*nb_rx*sizeof(struct complex*)); + chan_desc->a = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex*)); + for (i = 0; ich[i] = (struct complex*) malloc(chan_desc->channel_length * sizeof(struct complex)); + for (i = 0; ichF[i] = (struct complex*) malloc(1200 * sizeof(struct complex)); + for (i = 0; inb_taps; i++) + chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); + if (nb_tx==2 && nb_rx==2) { + chan_desc->R_sqrt = (struct complex**) malloc(chan_desc->nb_taps*sizeof(struct complex**)); + for (i = 0; inb_taps; i++) + chan_desc->R_sqrt[i] = R_sqrt_22_EPA_medium[0]; + } else { + printf("Correlation matrices are implemented for 2 x 2 only"); + } + /*else { + chan_desc->R_sqrt = (struct complex**) malloc(6*sizeof(struct complex**)); + for (i = 0; i<6; i++) { + chan_desc->R_sqrt[i] = (struct complex*) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); + for (j = 0; jR_sqrt[i][j].x = 1.0; + chan_desc->R_sqrt[i][j].y = 0.0; + } + LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); + } + }*/ + break; case EVA: chan_desc->nb_taps = 9; chan_desc->Td = 2.51; From bea768660b1a3d2af279359c81573aed3540b3ee Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Fri, 25 Nov 2016 16:26:30 +0100 Subject: [PATCH 121/571] Fixing bug in dlsim.c for LLR updates for SIC receiver. --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 15 ++-- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 20 ++--- openair1/SIMULATION/LTE_PHY/dlsim.c | 82 +++++++++++++++++++-- 3 files changed, 95 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index ea01148117..358e037202 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -93,11 +93,11 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) #endif for (r=0; rharq_processes[i]->c[r]); #endif - + if (dlsch->harq_processes[i]->c[r]) { free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); dlsch->harq_processes[i]->c[r] = NULL; @@ -106,17 +106,17 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144))); dlsch->harq_processes[i]->d[r] = NULL; } - + } free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); dlsch->harq_processes[i] = NULL; } } - + free16(dlsch,sizeof(LTE_eNB_DLSCH_t)); dlsch = NULL; } - + } LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag) @@ -208,7 +208,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ if (dlsch->harq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = LTE_NULL; } - + } return(dlsch); @@ -247,7 +247,7 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) for (r=0; rharq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = LTE_NULL; - + } } } @@ -408,6 +408,7 @@ int dlsch_encoding(unsigned char *a, nb_rb, m); // r stop_meas(rm_stats); + //printf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx); #ifdef DEBUG_DLSCH_CODING if (r==dlsch->harq_processes[harq_pid]->C-1) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 2e8d70102f..564262a71d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -45,7 +45,7 @@ #include "SCHED/extern.h" #include "SIMULATION/TOOLS/defs.h" //#define DEBUG_DLSCH_DECODING - + void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { @@ -338,7 +338,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, for (r=0; rC; r++) { - + // Get Turbo interleaver parameters if (rCminus) Kr = harq_process->Kminus; @@ -382,7 +382,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, harq_process->round); #endif - +//printf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx); if (lte_rate_matching_turbo_rx(harq_process->RTC[r], G, harq_process->w[r], @@ -476,7 +476,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, stop_meas(dlsch_turbo_decoding_stats); } #else - if ((harq_process->C == 1) || + if ((harq_process->C == 1) || ((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments start_meas(dlsch_turbo_decoding_stats); @@ -508,7 +508,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, } else { skipped_last=0; - + if (Kr_last == Kr) { // decode 2 code segments with AVX2 version #ifdef DEBUG_DLSCH_DECODING printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]); @@ -555,7 +555,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, exit(-1);*/ stop_meas(dlsch_turbo_decoding_stats); - } + } else { // Kr_last != Kr start_meas(dlsch_turbo_decoding_stats); ret = tc @@ -575,7 +575,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, &phy_vars_ue->dlsch_tc_intl1_stats, &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); stop_meas(dlsch_turbo_decoding_stats); - + start_meas(dlsch_turbo_decoding_stats); ret = tc (&harq_process->d[r][96], @@ -594,7 +594,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, &phy_vars_ue->dlsch_tc_intl1_stats, &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); stop_meas(dlsch_turbo_decoding_stats); - + } } } @@ -714,7 +714,7 @@ int dlsch_abstraction_EESM(double* sinr_dB, uint8_t TM, uint32_t rb_alloc[4], ui bler = interp(sinr_eff,&sinr_bler_map[mcs][0][0],&sinr_bler_map[mcs][1][0],table_length[mcs]); -#ifdef USER_MODE // need to be adapted for the emulation in the kernel space +#ifdef USER_MODE // need to be adapted for the emulation in the kernel space if (uniformrandom() < bler) { LOG_I(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f, TM %d)\n",mcs,sinr_eff,bler, TM); @@ -797,7 +797,7 @@ int dlsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint32_t rb_alloc[4], ui bler = interp(sinr_eff,&sinr_bler_map[mcs][0][0],&sinr_bler_map[mcs][1][0],table_length[mcs]); -#ifdef USER_MODE // need to be adapted for the emulation in the kernel space +#ifdef USER_MODE // need to be adapted for the emulation in the kernel space if (uniformrandom() < bler) { LOG_N(OCM,"abstraction_decoding failed (mcs=%d, sinr_eff=%f, bler=%f)\n",mcs,sinr_eff,bler); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 58aae368ce..c6b42f64c5 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -187,7 +187,7 @@ int main(int argc, char **argv) unsigned int ret[2]; unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; - unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, round_sic=0; + unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, decoded_in_sic[4]={0,0,0,0}, sic_attempt[4]={0,0,0,0}, round_sic=0; unsigned int dci_errors=0, dlsch_active=0, num_layers; int re_allocated; @@ -795,8 +795,10 @@ int main(int argc, char **argv) } if ((transmission_mode != 3) && (transmission_mode != 4)) fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); + else if (rx_type == rx_SIC_dual_stream) + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); else - fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2; trials0 r0; trials1 r0; err1_st1; err1_st2; trials0_r1; trials1_r1; err2_st1; err2_st2; trials0_r2; trials1_r2; err3_st1; err3_st2; trials0_r3; trials1_r3; th0_r0; th1_r0; th_sum_r0; th0_r1; th1_r1; th_sum_r1; th0_r2; th1_r2; th_sum_r2; th0_r3; th1_r3; th_sum_r3; tot_th\n"); + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); if (test_perf != 0) { @@ -2011,6 +2013,8 @@ int main(int argc, char **argv) for (i=0; i<4; i++) { errs[0][i]=0; //CW_0 errs[1][i]=0; //CW_1 + decoded_in_sic[i]=0; + sic_attempt[i]=0; round_trials[0][i] = 0; // CW_0 round_trials[1][i] = 0; // CW_1 @@ -3872,6 +3876,7 @@ int main(int argc, char **argv) //printf("\n CW 0 is decoded, i go for , round %d\n", round); //printf("\n ret[TB0] = %d round %d\n", ret[TB], round); + sic_attempt[round]++; for (round_sic = 0 ; round_sic < (round +1); round_sic++) { @@ -3893,6 +3898,22 @@ int main(int argc, char **argv) dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + if (round_sic == 0){ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 0; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=0; + } + else if (round_sic == 1){ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 1; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=1; + } + else if (round_sic == 2){ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 2; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=2; + } + else{ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 3; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=3; + } PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; @@ -3921,7 +3942,7 @@ int main(int argc, char **argv) dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, 0, PHY_vars_UE->dlsch_eNB[eNB_id], - coded_bits_per_codeword[TB], + coded_bits_per_codeword[0], 0, subframe<<1); @@ -4051,6 +4072,7 @@ int main(int argc, char **argv) stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); start_meas(&PHY_vars_UE->dlsch_decoding_stats); + ret[1] = dlsch_decoding(PHY_vars_UE, PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], &PHY_vars_UE->lte_frame_parms, @@ -4068,6 +4090,7 @@ int main(int argc, char **argv) //printf("ret TB 1 = %d round %d \n", ret[1], round); if (ret[1] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) { + decoded_in_sic[round]++; round_sic = round+1; // to exit round_sic #ifdef DEBUG_HARQ printf("[DLSIM] TB1 is decoded in SIC loop\n"); @@ -4378,6 +4401,8 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); printf(" one failed round 0 = %d, one failed round 1 = %d, one failed round 2 = %d, one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); + printf(" sic attempt round 0 = %d, sic attempt round 1 = %d, sic attempt round 2 = %d, sic attempt round 3 = %d\n", sic_attempt[0], sic_attempt[1], sic_attempt[2], sic_attempt[3]); + printf(" decoded in sic round 0 = %d, decoded in sic round 1 = %d, decoded in sic round 2 = %d, decoded in sic round 3 = %d\n", decoded_in_sic[0], decoded_in_sic[1], decoded_in_sic[2], decoded_in_sic[3]); #endif // round_trials[0]: number of code word : goodput the protocol double table_tx[time_vector_tx.size]; @@ -4733,7 +4758,54 @@ int main(int argc, char **argv) round_trials[0][3], dci_errors); } - else { + else if ( rx_type== rx_SIC_dual_stream) { + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", + SNR, + mcs1, + mcs2, + tbs0_init, + tbs1_init, + rate0_init, + rate1_init, + errs[0][0], + errs[1][0], + round_trials[0][0], + round_trials[1][0], + sic_attempt[0], + decoded_in_sic[0], + errs[0][1], + errs[1][1], + round_trials[0][1], + round_trials[1][1], + sic_attempt[1], + decoded_in_sic[1], + errs[0][2], + errs[1][2], + round_trials[0][2], + round_trials[1][2], + sic_attempt[2], + decoded_in_sic[2], + errs[0][3], + errs[1][3], + round_trials[0][3], + round_trials[1][3], + sic_attempt[3], + decoded_in_sic[3], + thr_cw0[0], + thr_cw1[0], + thr_cw0[0]+thr_cw1[0], + thr_cw0[1], + thr_cw1[1], + thr_cw0[1]+thr_cw1[1], + thr_cw0[2], + thr_cw1[2], + thr_cw0[2]+thr_cw1[2], + thr_cw0[3], + thr_cw1[3], + thr_cw0[3]+thr_cw1[3], + thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); + } + else{ fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", SNR, mcs1, @@ -4771,7 +4843,7 @@ int main(int argc, char **argv) thr_cw1[3], thr_cw0[3]+thr_cw1[3], thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); - } + } if(abstx){ //ABSTRACTION From afe698db10a2cd6458af7837d2e3750fb7d14cd9 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Fri, 25 Nov 2016 17:17:03 +0100 Subject: [PATCH 122/571] Adding retransmission statistics. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index c6b42f64c5..b719cd4682 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -189,6 +189,7 @@ int main(int argc, char **argv) unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, decoded_in_sic[4]={0,0,0,0}, sic_attempt[4]={0,0,0,0}, round_sic=0; unsigned int dci_errors=0, dlsch_active=0, num_layers; + unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}; int re_allocated; char fname[32],vname[32]; @@ -796,7 +797,7 @@ int main(int argc, char **argv) if ((transmission_mode != 3) && (transmission_mode != 4)) fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); else if (rx_type == rx_SIC_dual_stream) - fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); else fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); @@ -2015,6 +2016,8 @@ int main(int argc, char **argv) errs[1][i]=0; //CW_1 decoded_in_sic[i]=0; sic_attempt[i]=0; + resend_one[i]=0; + resend_both[i]=0; round_trials[0][i] = 0; // CW_0 round_trials[1][i] = 0; // CW_1 @@ -2026,7 +2029,6 @@ int main(int argc, char **argv) avg_iter[1] = 0; iter_trials[0]=0; iter_trials[1]=0; - unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}; reset_meas(&PHY_vars_eNB->phy_proc_tx); // total eNB tx reset_meas(&PHY_vars_eNB->dlsch_scrambling_stats); reset_meas(&PHY_vars_UE->dlsch_unscrambling_stats); @@ -4400,7 +4402,7 @@ int main(int argc, char **argv) } //trials #ifdef DEBUG_HARQ printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); - printf(" one failed round 0 = %d, one failed round 1 = %d, one failed round 2 = %d, one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); + printf(" only one failed round 0 = %d, only one failed round 1 = %d, only one failed round 2 = %d, only one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); printf(" sic attempt round 0 = %d, sic attempt round 1 = %d, sic attempt round 2 = %d, sic attempt round 3 = %d\n", sic_attempt[0], sic_attempt[1], sic_attempt[2], sic_attempt[3]); printf(" decoded in sic round 0 = %d, decoded in sic round 1 = %d, decoded in sic round 2 = %d, decoded in sic round 3 = %d\n", decoded_in_sic[0], decoded_in_sic[1], decoded_in_sic[2], decoded_in_sic[3]); #endif @@ -4759,7 +4761,7 @@ int main(int argc, char **argv) dci_errors); } else if ( rx_type== rx_SIC_dual_stream) { - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", SNR, mcs1, mcs2, @@ -4773,18 +4775,24 @@ int main(int argc, char **argv) round_trials[1][0], sic_attempt[0], decoded_in_sic[0], + resend_both[0], + resend_one[0], errs[0][1], errs[1][1], round_trials[0][1], round_trials[1][1], sic_attempt[1], decoded_in_sic[1], + resend_both[1], + resend_one[1], errs[0][2], errs[1][2], round_trials[0][2], round_trials[1][2], sic_attempt[2], decoded_in_sic[2], + resend_both[2], + resend_one[2], errs[0][3], errs[1][3], round_trials[0][3], From ad9a2460434b687d48c4ab3be7cdf56bffe815c6 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Sun, 27 Nov 2016 17:34:23 +0100 Subject: [PATCH 123/571] Adding HARQ support for PIA detection. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 29 ++- openair1/SIMULATION/LTE_PHY/dlsim.c | 342 +++++++++++++++++-------- 2 files changed, 258 insertions(+), 113 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 52b7d52f1e..8e53ce7170 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1558,6 +1558,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch0_harq->codeword = 0; dlsch1=NULL; dlsch1_harq = NULL; +#ifdef DEBUG_HARQ + printf("\n ENB: TB1 is deactivated, retransmit TB0 transmit in TM6\n"); +#endif } else if ((TB0_active==0) && TB1_active) { dlsch1=dlsch[1]; @@ -4945,6 +4948,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->codeword = 0; dlsch1=NULL; dlsch1_harq = NULL; +#ifdef DEBUG_HARQ + printf("[DCI UE]: TB1 is deactivated, retransmit TB0 transmit in TM6\n"); +#endif } else if ((TB0_active==0) && TB1_active) { dlsch1=dlsch[1]; @@ -5094,14 +5100,23 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = PUSCH_PRECODING0; // pmi stored from ulsch allocation routine // we need to extract the first column of precoding matrix (which was computed assuming rank==2) - dlsch0_harq->pmi_alloc = 0;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); +#ifdef DEBUG_HARQ + printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc); +#endif break; case 6: dlsch0_harq->mimo_mode = PUSCH_PRECODING1; // we need to extract the second column of precoding matrix (which was computed assuming rank==2) - dlsch0_harq->pmi_alloc = 0;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); +#ifdef DEBUG_HARQ + printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc); +#endif break; +#ifdef DEBUG_HARQ + printf("[DCI UE] harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); +#endif } } else { dlsch1_harq->dl_power_off = 1; @@ -5144,10 +5159,10 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); break; } - } #ifdef DEBUG_HARQ printf("[DCI UE] harq1 MIMO mode = %d\n", dlsch1_harq->mimo_mode); #endif + } //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); if ((frame_parms->mode1_flag == 1) && (dlsch0_harq != NULL)) dlsch0_harq->mimo_mode = SISO; @@ -5233,10 +5248,12 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch1->rnti = rnti; } #ifdef DEBUG_HARQ - if (dlsch0 != NULL) + if (dlsch0 != NULL && dlsch1 != NULL) printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status); - else - printf("[DCI UE] dlsch1_harq status = %d\n", dlsch1_harq->status); + else if (dlsch0 == NULL && dlsch1 != NULL) + printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status); + else if (dlsch0 != NULL && dlsch1 == NULL) + printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status); #endif break; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index b719cd4682..81de255e8a 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -278,6 +278,7 @@ int main(int argc, char **argv) char channel_model_input[17]="I"; int TB0_active = 1; + int TB1_active = 1; uint32_t perfect_ce = 0; @@ -2099,6 +2100,7 @@ int main(int argc, char **argv) resend_cw0_cw1=1; resend_cw1=0; TB0_active=1; + TB1_active=1; while (((transmission_mode == 3 || transmission_mode == 4) && ((round < num_rounds) && ((ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) || @@ -2123,7 +2125,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ - printf("[DLSIM] Just after while loop TB0 status %d round %d\n", TB0_active, round); + printf("[DLSIM] Just after while loop TB0 status %d TB1 status %d round %d\n", TB0_active, TB1_active, round); #endif // printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials TB0 = %d, round_trials TB1 = %d \n",trials,round, ret[0], ret[1], round_trials[0][round], round_trials[1][round]); @@ -2171,6 +2173,7 @@ int main(int argc, char **argv) if (round == 0) { // First round TB0_active = 1; + TB1_active = 1; /* PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; if (transmission_mode == 3 || transmission_mode == 4) @@ -2436,63 +2439,87 @@ int main(int argc, char **argv) case 3: switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0) { // deactivate TB0 ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); break; case 25: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0) { // deactivate TB0 ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); break; case 50: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); break; case 100: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); break; } @@ -2500,8 +2527,8 @@ int main(int argc, char **argv) case 4: switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: - if (TB0_active==1) { - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; @@ -2509,17 +2536,25 @@ int main(int argc, char **argv) ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = tpmi_retr; + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); break; case 25: - if (TB0_active==1) { + + if (TB0_active == 1 && TB1_active == 1) { ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; @@ -2528,7 +2563,7 @@ int main(int argc, char **argv) ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 #ifdef DEBUG_HARQ printf("\n[DLSIM] Requesting only TB1 from temp DCI\n"); #endif @@ -2538,6 +2573,16 @@ int main(int argc, char **argv) ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 +#ifdef DEBUG_HARQ + printf("\n[DLSIM] TDD Requesting only TB0 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -2554,7 +2599,7 @@ int main(int argc, char **argv) ); break; case 50: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; @@ -2563,17 +2608,24 @@ int main(int argc, char **argv) ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); break; case 100: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; @@ -2582,13 +2634,20 @@ int main(int argc, char **argv) ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); break; } @@ -2696,7 +2755,7 @@ int main(int argc, char **argv) case 4: switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; @@ -2705,17 +2764,24 @@ int main(int argc, char **argv) ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); break; case 25: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; @@ -2724,7 +2790,7 @@ int main(int argc, char **argv) ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 #ifdef DEBUG_HARQ printf("\n [DLSIM] Requesting only TB1 from temp DCI\n"); #endif @@ -2734,6 +2800,16 @@ int main(int argc, char **argv) ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 +#ifdef DEBUG_HARQ + printf("\n[DLSIM] FDD Requesting only TB0 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -2750,7 +2826,7 @@ int main(int argc, char **argv) ); break; case 50: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; @@ -2759,17 +2835,25 @@ int main(int argc, char **argv) ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0) { // deactivate TB0 ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); break; case 100: - if (TB0_active==1) { + if (TB0_active == 1 && TB1_active == 1) { ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; @@ -2778,13 +2862,20 @@ int main(int argc, char **argv) ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } - else { // deactivate TB0 + else if (TB0_active == 0){ // deactivate TB0 ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; } + else { // deactivate TB1 + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); break; } @@ -2822,12 +2913,18 @@ int main(int argc, char **argv) printf("[DLSIM ENC] Skip TB0 \n"); #endif TB++; - } #ifdef DEBUG_HARQ - printf("[DLSIM ENC] process TB %d \n", TB); + printf("[DLSIM ENC] process TB %d \n", TB); #endif + if (TB==1 && TB1_active == 0){ +#ifdef DEBUG_HARQ + printf("[DLSIM ENC] Skip TB1 \n"); +#endif + break; + } + coded_bits_per_codeword[TB] = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->nb_rb, PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->rb_alloc, @@ -2867,90 +2964,90 @@ int main(int argc, char **argv) */ } - //Here need to add cases for TPMI 6 and TPMI 5 and check for both TB. - if (transmission_mode == 4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) && (TB0_active == 1)){ + //if standard case when both TBs are active + if (transmission_mode == 4) { + if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) && TB0_active == 1 && TB1_active == 1){ #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 1\n"); + printf ("[DLSIM] I am calling from the eNode B 1\n"); #endif - PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 2\n"); + printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); - } + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } - if (updated_csi == 0){ + else if (updated_csi == 0){ - if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ + if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 1\n"); + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + } else if (updated_csi == 1){ + + if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] Updating CSI\n"); + printf ("[DLSIM] I quantize from ENodeB 1\n"); +#endif + + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); #endif PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 2\n"); + printf ("[DLSIM] I quantize from ENodeB 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); } - - if ((transmission_mode == 4) && (hold_rank1_precoder == 0) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ + else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 1\n"); + printf ("[DLSIM] Updating CSI\n"); + printf ("[DLSIM] I quantize from ENodeB 1\n"); +#endif + + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); #endif PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); #ifdef DEBUG_HARQ - printf ("[DLSIM] I am calling from the eNode B 2\n"); + printf ("[DLSIM] I quantize from ENodeB 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); } - } else if (updated_csi == 1){ - - if ((transmission_mode == 4) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ -#ifdef DEBUG_HARQ - printf ("[DLSIM] Updating CSI\n"); - printf ("[DLSIM] I quantize from ENodeB 1\n"); -#endif - - PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); -#ifdef DEBUG_HARQ - printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); -#endif - PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); - -#ifdef DEBUG_HARQ - printf ("[DLSIM] I quantize from ENodeB 2\n"); -#endif - PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); -#ifdef DEBUG_HARQ - printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); -#endif - PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); } - - if ((transmission_mode == 4) && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ -#ifdef DEBUG_HARQ - printf ("[DLSIM] Updating CSI\n"); - printf ("[DLSIM] I quantize from ENodeB 1\n"); -#endif - - PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); -#ifdef DEBUG_HARQ - printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); -#endif - PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); -#ifdef DEBUG_HARQ - printf ("[DLSIM] I quantize from ENodeB 2\n"); -#endif - PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); -#ifdef DEBUG_HARQ - printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); -#endif - PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); - } - - } + } start_meas(&PHY_vars_eNB->dlsch_encoding_stats); if (dlsch_encoding(((TB==0) ? input_buffer0[k] : input_buffer1[k]), @@ -2993,7 +3090,7 @@ int main(int argc, char **argv) &PHY_vars_eNB->lte_frame_parms, num_pdcch_symbols, ((TB0_active == 1)? PHY_vars_eNB->dlsch_eNB[k][0]: NULL), - PHY_vars_eNB->dlsch_eNB[k][1]); + ((TB1_active == 1)? PHY_vars_eNB->dlsch_eNB[k][1]: NULL)); stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); } //n_users @@ -3649,7 +3746,7 @@ int main(int argc, char **argv) for (TB=0; TBdlsch_ue[0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[TB] = get_G(&PHY_vars_eNB->lte_frame_parms, PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->nb_rb, @@ -4309,19 +4413,22 @@ int main(int argc, char **argv) } - if ((transmission_mode == 3 || transmission_mode == 4 ) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) && (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ - resend_both[round]++; - round++; - resend_cw0_cw1=1; //resend both cws - resend_cw1=0; - TB0_active=1; - - } - - if ((transmission_mode == 3 || transmission_mode == 4 ) && (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) && (ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ - resend_one[round]++; - resend_cw0_cw1=0; + if (transmission_mode == 3 || transmission_mode == 4 ) { + if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations && + ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + resend_both[round]++; + round++; + resend_cw0_cw1=1; //resend both cws + resend_cw1=0; + TB0_active=1; + TB1_active=1; + } + else if (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations && + ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + resend_one[round]++; + resend_cw0_cw1=0; TB0_active=0; + TB1_active=1; if(is_first_time) { hold_rank1_precoder = 0; is_first_time = false; @@ -4334,12 +4441,31 @@ int main(int argc, char **argv) printf("[DLSIM] TB0 deactivated\n"); #endif round++; + } + else if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations && + ret[1] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + resend_one[round]++; + resend_cw0_cw1=0; + TB0_active=1; + TB1_active=0; + if(is_first_time) { + hold_rank1_precoder = 0; + is_first_time = false; + } + else + hold_rank1_precoder = 1; + +#ifdef DEBUG_HARQ + printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials); + printf("[DLSIM] TB1 deactivated\n"); +#endif + round++; + } } + #ifdef DEBUG_HARQ printf("[DLSIM] Now round is %d, trial %d\n" , round, trials); #endif - - } @@ -4403,8 +4529,10 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); printf(" only one failed round 0 = %d, only one failed round 1 = %d, only one failed round 2 = %d, only one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); - printf(" sic attempt round 0 = %d, sic attempt round 1 = %d, sic attempt round 2 = %d, sic attempt round 3 = %d\n", sic_attempt[0], sic_attempt[1], sic_attempt[2], sic_attempt[3]); - printf(" decoded in sic round 0 = %d, decoded in sic round 1 = %d, decoded in sic round 2 = %d, decoded in sic round 3 = %d\n", decoded_in_sic[0], decoded_in_sic[1], decoded_in_sic[2], decoded_in_sic[3]); + if (rx_type == rx_SIC_dual_stream){ + printf(" sic attempt round 0 = %d, sic attempt round 1 = %d, sic attempt round 2 = %d, sic attempt round 3 = %d\n", sic_attempt[0], sic_attempt[1], sic_attempt[2], sic_attempt[3]); + printf(" decoded in sic round 0 = %d, decoded in sic round 1 = %d, decoded in sic round 2 = %d, decoded in sic round 3 = %d\n", decoded_in_sic[0], decoded_in_sic[1], decoded_in_sic[2], decoded_in_sic[3]); + } #endif // round_trials[0]: number of code word : goodput the protocol double table_tx[time_vector_tx.size]; From 29d640021033fc036d26d34361c9df3f33b1190c Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Sun, 27 Nov 2016 18:14:27 +0100 Subject: [PATCH 124/571] Optimizing printputs for PIA recever --- openair1/SIMULATION/LTE_PHY/dlsim.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 81de255e8a..53ab3aa56c 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -189,7 +189,7 @@ int main(int argc, char **argv) unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, decoded_in_sic[4]={0,0,0,0}, sic_attempt[4]={0,0,0,0}, round_sic=0; unsigned int dci_errors=0, dlsch_active=0, num_layers; - unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}; + unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}, TB0_deact[4]={0,0,0,0}, TB1_deact[4]={0,0,0,0}; int re_allocated; char fname[32],vname[32]; @@ -800,7 +800,7 @@ int main(int argc, char **argv) else if (rx_type == rx_SIC_dual_stream) fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); else - fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); if (test_perf != 0) { @@ -2022,6 +2022,8 @@ int main(int argc, char **argv) round_trials[0][i] = 0; // CW_0 round_trials[1][i] = 0; // CW_1 + TB0_deact[i]=0; + TB1_deact[i]=0; } dci_errors=0; @@ -4429,6 +4431,8 @@ int main(int argc, char **argv) resend_cw0_cw1=0; TB0_active=0; TB1_active=1; + if (rx_type == rx_IC_dual_stream) + TB0_deact[round]++; if(is_first_time) { hold_rank1_precoder = 0; is_first_time = false; @@ -4448,6 +4452,8 @@ int main(int argc, char **argv) resend_cw0_cw1=0; TB0_active=1; TB1_active=0; + if (rx_type == rx_IC_dual_stream) + TB1_deact[round]++; if(is_first_time) { hold_rank1_precoder = 0; is_first_time = false; @@ -4533,6 +4539,10 @@ int main(int argc, char **argv) printf(" sic attempt round 0 = %d, sic attempt round 1 = %d, sic attempt round 2 = %d, sic attempt round 3 = %d\n", sic_attempt[0], sic_attempt[1], sic_attempt[2], sic_attempt[3]); printf(" decoded in sic round 0 = %d, decoded in sic round 1 = %d, decoded in sic round 2 = %d, decoded in sic round 3 = %d\n", decoded_in_sic[0], decoded_in_sic[1], decoded_in_sic[2], decoded_in_sic[3]); } + else if (rx_type == rx_IC_dual_stream){ + printf(" TB0 deactiv round 0 = %d, TB0 deactiv round 1 = %d, TB0 deactiv round 2 = %d, TB0 deactiv round 3 = %d\n", TB0_deact[0], TB0_deact[1], TB0_deact[2], TB0_deact[3]); + printf(" TB1 deactiv round 0 = %d, TB1 deactiv round 1 = %d, TB1 deactiv round 2 = %d, TB1 deactiv round 3 = %d\n", TB1_deact[0], TB1_deact[1], TB1_deact[2], TB1_deact[3]); + } #endif // round_trials[0]: number of code word : goodput the protocol double table_tx[time_vector_tx.size]; @@ -4942,7 +4952,7 @@ int main(int argc, char **argv) thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); } else{ - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", SNR, mcs1, mcs2, @@ -4954,14 +4964,20 @@ int main(int argc, char **argv) errs[1][0], round_trials[0][0], round_trials[1][0], + TB0_deact[0], + TB1_deact[0], errs[0][1], errs[1][1], round_trials[0][1], round_trials[1][1], + TB0_deact[1], + TB1_deact[1], errs[0][2], errs[1][2], round_trials[0][2], round_trials[1][2], + TB0_deact[2], + TB1_deact[2], errs[0][3], errs[1][3], round_trials[0][3], From 3b9869187b2521d307e3ce0826b8fa3bafa669fe Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Mon, 28 Nov 2016 11:36:50 +0100 Subject: [PATCH 125/571] Adding some printouts for PIA --- openair1/SIMULATION/LTE_PHY/dlsim.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 53ab3aa56c..8e0e6ac0e7 100755 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -800,7 +800,7 @@ int main(int argc, char **argv) else if (rx_type == rx_SIC_dual_stream) fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); else - fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); if (test_perf != 0) { @@ -4952,7 +4952,7 @@ int main(int argc, char **argv) thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); } else{ - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", SNR, mcs1, mcs2, @@ -4966,18 +4966,24 @@ int main(int argc, char **argv) round_trials[1][0], TB0_deact[0], TB1_deact[0], + resend_both[0], + resend_one[0], errs[0][1], errs[1][1], round_trials[0][1], round_trials[1][1], TB0_deact[1], TB1_deact[1], + resend_both[1], + resend_one[1], errs[0][2], errs[1][2], round_trials[0][2], round_trials[1][2], TB0_deact[2], TB1_deact[2], + resend_both[2], + resend_one[2], errs[0][3], errs[1][3], round_trials[0][3], From cedde4ad1ff3a37372ffbd8df821b8d6a7f870e1 Mon Sep 17 00:00:00 2001 From: laurent Date: Mon, 26 Dec 2016 21:19:26 +0100 Subject: [PATCH 126/571] realtime for UE --- common/utils/itti/assertions.h | 2 +- openair1/PHY/defs.h | 3 + openair2/COMMON/platform_types.h | 2 +- openair2/UTIL/LOG/log.h | 20 + targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 929 +++---- targets/RT/USER/lte-ue.c | 2385 +++++++----------- 6 files changed, 1295 insertions(+), 2046 deletions(-) diff --git a/common/utils/itti/assertions.h b/common/utils/itti/assertions.h index df8251d105..a411bd5397 100644 --- a/common/utils/itti/assertions.h +++ b/common/utils/itti/assertions.h @@ -65,7 +65,7 @@ _Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX " (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3) #define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \ -_Assert_(cOND, _Assert_Exit_, #vALUE1": %"PRIdMAX"\n"#vALUE2": %"PRIdMAX"\n"#vALUE3": %"PRIdMAX"\n"#vALUE4": %"PRIdMAX"\n\n", \ +_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \ (intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4) #define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3) diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index daf560a736..9c72bc433e 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -371,6 +371,9 @@ typedef struct { pthread_mutex_t mutex_rxtx; /// scheduling parameters for RXn-TXnp4 thread struct sched_param sched_param_rxtx; + int sub_frame_start; + int sub_frame_step; + unsigned long long gotIQs; } UE_rxtx_proc_t; /// Context data structure for eNB subframe processing diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 327523f1d0..256ed45b5d 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -255,7 +255,7 @@ typedef struct protocol_ctxt_s { (Ctxt_Pp)->subframe = sUBfRAME; \ PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp) -#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %"PRIx16"]" +#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %" PRIx16 "]" #define PROTOCOL_CTXT_ARGS(CTXT_Pp) \ (CTXT_Pp)->frame, \ ((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \ diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 6a6569c1a5..171f74da41 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -53,6 +53,26 @@ extern "C" { #endif + extern double cpuf; + static inline unsigned long long rdtsc(void) { + unsigned long long a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; + } + static inline unsigned long long checkT(int timeout, char * file, int line) { + static unsigned long long __thread last=0; + unsigned long long cur=rdtsc(); + int microCycles=(int)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) + printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, + duration, timeout); + last=cur; + return cur; + } + +#define check(a) checkT(a,__FILE__,__LINE__) + /** @defgroup _LOG LOG Generator * @{*/ /* @}*/ diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 0161761d97..3185b97226 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -40,10 +40,12 @@ #include #include "UTIL/LOG/log_extern.h" #include "common_lib.h" +#include "assertions.h" + #ifdef __SSE4_1__ # include #endif - + #ifdef __AVX2__ # include #endif @@ -56,16 +58,14 @@ * @{ */ -/*! \brief USRP Configuration */ -typedef struct -{ +/*! \brief USRP Configuration */ +typedef struct { - // -------------------------------- - // variables for USRP configuration - // -------------------------------- - //! USRP device pointer - uhd::usrp::multi_usrp::sptr usrp; - //uhd::usrp::multi_usrp::sptr rx_usrp; + // -------------------------------- + // variables for USRP configuration + // -------------------------------- + //! USRP device pointer + uhd::usrp::multi_usrp::sptr usrp; //create a send streamer and a receive streamer //! USRP TX Stream @@ -78,141 +78,93 @@ typedef struct //! USRP RX Metadata uhd::rx_metadata_t rx_md; - //! USRP Timestamp Information - uhd::time_spec_t tm_spec; + //! Sampling rate + double sample_rate; - //setup variables and allocate buffer - //! USRP Metadata - uhd::async_metadata_t async_md; + //! TX forward samples. We use usrp_time_offset to get this value + int tx_forward_nsamps; //166 for 20Mhz - //! Sampling rate - double sample_rate; - - //! time offset between transmiter timestamp and receiver timestamp; - double tdiff; - - //! TX forward samples. We use usrp_time_offset to get this value - int tx_forward_nsamps; //166 for 20Mhz - - - // -------------------------------- - // Debug and output control - // -------------------------------- - //! Number of underflows - int num_underflows; - //! Number of overflows - int num_overflows; - - //! Number of sequential errors - int num_seq_errors; - //! tx count - int64_t tx_count; - //! rx count - int64_t rx_count; - //! timestamp of RX packet - openair0_timestamp rx_timestamp; + // -------------------------------- + // Debug and output control + // -------------------------------- + int num_underflows; + int num_overflows; + int num_seq_errors; + int64_t tx_count; + int64_t rx_count; + //! timestamp of RX packet + openair0_timestamp rx_timestamp; } usrp_state_t; + + /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target */ -static int trx_usrp_start(openair0_device *device) -{ - usrp_state_t *s = (usrp_state_t*)device->priv; +static int trx_usrp_start(openair0_device *device) { - // init recv and send streaming - uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); - cmd.stream_now = false; // start at constant delay - s->rx_stream->issue_stream_cmd(cmd); + usrp_state_t *s = (usrp_state_t*)device->priv; - s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); - s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; + // init recv and send streaming + uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); + cmd.stream_now = true; + s->rx_stream->issue_stream_cmd(cmd); + s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); + s->tx_md.has_time_spec = true; + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; - s->rx_count = 0; - s->tx_count = 0; - s->rx_timestamp = 0; - - return 0; + s->rx_count = 0; + s->tx_count = 0; + s->rx_timestamp = 0; + return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ -static void trx_usrp_end(openair0_device *device) -{ - usrp_state_t *s = (usrp_state_t*)device->priv; +static void trx_usrp_end(openair0_device *device) { + usrp_state_t *s = (usrp_state_t*)device->priv; - s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + //send a mini EOB packet + s->tx_md.end_of_burst = true; + s->tx_stream->send("", 0, s->tx_md); + s->tx_md.end_of_burst = false; - //send a mini EOB packet - s->tx_md.end_of_burst = true; - s->tx_stream->send("", 0, s->tx_md); - s->tx_md.end_of_burst = false; - } /*! \brief Called to send samples to the USRP RF target @param device pointer to the device structure specific to the RF hardware target - @param timestamp The timestamp at whicch the first sample MUST be sent + @param timestamp The timestamp at whicch the first sample MUST be sent @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas @param flags flags must be set to TRUE if timestamp parameter needs to be applied -*/ -static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) -{ - static long long int loop=0; - static long time_min=0, time_max=0, time_avg=0; - struct timespec tp_start, tp_end; - long time_diff; - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start); +*/ +static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + int ret=0; + usrp_state_t *s = (usrp_state_t*)device->priv; - int ret=0, ret_i=0; - usrp_state_t *s = (usrp_state_t*)device->priv; + s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + s->tx_md.has_time_spec = flags; - s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + if (cc>1) { + std::vector buff_ptrs; + for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); + } else + ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); - - if(flags) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; - - if (cc>1) { - std::vector buff_ptrs; - for (int i=0;itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); - } - else - ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); + s->tx_md.start_of_burst = false; - s->tx_md.start_of_burst = false; + if (ret != nsamps) + LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); - if (ret != nsamps) { - printf("[xmit] tx samples %d != %d\n",ret,nsamps); - } - - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_end); - time_diff = (tp_end.tv_sec - tp_start.tv_sec) *1E09 + (tp_end.tv_nsec - tp_start.tv_nsec); - if (time_min==0 ||loop==1 || time_min > time_diff) - time_min=time_diff; - if (time_max==0 ||loop==1 || time_max < time_diff) - time_max=time_diff; - if (time_avg ==0 ||loop==1) - time_avg= time_diff; - else - time_avg=(time_diff+time_avg) /2.0; - - /* //prints statics of uhd every 10 seconds - if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0) - LOG_I(HW,"usrp_write: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg); - */ - loop++; - return ret; + return ret; } /*! \brief Receive samples from hardware. @@ -226,45 +178,42 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, * \param antenna_id Index of antenna for which to receive samples * \returns the number of sample read */ -static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) -{ - static long long int loop=0; - static long time_min=0, time_max=0, time_avg=0; - struct timespec tp_start, tp_end; - long time_diff; - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_start); - usrp_state_t *s = (usrp_state_t*)device->priv; - int samples_received=0,i,j; - int nsamps2; // aligned to upper 32 or 16 byte boundary +static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + usrp_state_t *s = (usrp_state_t*)device->priv; + int samples_received=0,i,j; + int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+7)>>3; + __m256i buff_tmp[2][nsamps2]; #else - nsamps2 = (nsamps+3)>>2; - __m128i buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + __m128i buff_tmp[2][nsamps2]; #endif #elif defined(__arm__) - nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tmp[2][nsamps2]; + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tmp[2][nsamps2]; #endif - - if (device->type == USRP_B200_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; - - for (int i=0;irx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff_tmp[0], nsamps, s->rx_md); - } - - // bring RX data into 12 LSBs for softmodem RX - for (int i=0;itype == USRP_B200_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; + for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received=0; + while (samples_received != nsamps) { + samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + nsamps-samples_received, s->rx_md); + if (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE) + break; + } + } + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; irx_stream->recv(buff[0], nsamps, s->rx_md); } } + if (samples_received < nsamps) + LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); - if (samples_received < nsamps) { - printf("[recv] received %d samples out of %d\n",samples_received,nsamps); - - } + if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) + LOG_E(PHY,s->rx_md.to_pp_string(true).c_str()); - //handle the error code - switch(s->rx_md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_NONE: - break; - case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: - printf("[recv] USRP RX OVERFLOW!\n"); - s->num_overflows++; - break; - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - printf("[recv] USRP RX TIMEOUT!\n"); - break; - default: - printf("[recv] Unexpected error on RX, Error code: 0x%x\n",s->rx_md.error_code); - break; - } - s->rx_count += nsamps; - s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); - *ptimestamp = s->rx_timestamp; - - clock_gettime(CLOCK_MONOTONIC_RAW, &tp_end); - time_diff = (tp_end.tv_sec - tp_start.tv_sec) *1E09 + (tp_end.tv_nsec - tp_start.tv_nsec); - if (time_min==0 ||loop==1 || time_min > time_diff) - time_min=time_diff; - if (time_max==0 ||loop==1 || time_max < time_diff) - time_max=time_diff; - if (time_avg ==0 ||loop==1) - time_avg= time_diff; - else - time_avg=(time_diff+time_avg) /2.0; - /* - //prints statics of uhd every 10 seconds - if ( loop % (10 * ((int)device->openair0_cfg[0].sample_rate /(int)nsamps )) ==0) - LOG_I(HW,"usrp_read: min(ns)=%d, max(ns)=%d, avg(ns)=%d\n", (int)time_min, (int)time_max,(int)time_avg); - - loop++;*/ - return samples_received; + s->rx_count += nsamps; + s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); + *ptimestamp = s->rx_timestamp; +#ifdef DEBUG_USRP + check(50); +#endif + return samples_received; } -/*! \brief Get current timestamp of USRP - * \param device the hardware to use -*/ -openair0_timestamp get_usrp_time(openair0_device *device) -{ - - usrp_state_t *s = (usrp_state_t*)device->priv; - - return s->usrp->get_time_now().to_ticks(s->sample_rate); -} - /*! \brief Compares two variables within precision * \param a first variable * \param b second variable */ -static bool is_equal(double a, double b) -{ +static bool is_equal(double a, double b) { return std::fabs(a-b) < std::numeric_limits::epsilon(); } @@ -360,59 +268,60 @@ static bool is_equal(double a, double b) */ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) { - usrp_state_t *s = (usrp_state_t*)device->priv; + usrp_state_t *s = (usrp_state_t*)device->priv; - printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[0]); + LOG_I(PHY,"Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); + s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[0]); + + return(0); - return(0); - } -/*! \brief Set RX frequencies +/*! \brief Set RX frequencies * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg) { - usrp_state_t *s = (usrp_state_t*)device->priv; - static int first_call=1; - static double rf_freq,diff; + usrp_state_t *s = (usrp_state_t*)device->priv; + static int first_call=1; + static double rf_freq,diff; - uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); + uhd::tune_request_t rx_tune_req(openair0_cfg[0].rx_freq[0]); - rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; - rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; - rf_freq=openair0_cfg[0].rx_freq[0]; - s->usrp->set_rx_freq(rx_tune_req); + rx_tune_req.rf_freq_policy = uhd::tune_request_t::POLICY_MANUAL; + rx_tune_req.rf_freq = openair0_cfg[0].rx_freq[0]; + rf_freq=openair0_cfg[0].rx_freq[0]; + s->usrp->set_rx_freq(rx_tune_req); + + return(0); - return(0); - } /*! \brief Set Gains (TX/RX) * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ -int trx_usrp_set_gains(openair0_device* device, - openair0_config_t *openair0_cfg) { +int trx_usrp_set_gains(openair0_device* device, + openair0_config_t *openair0_cfg) { - usrp_state_t *s = (usrp_state_t*)device->priv; + usrp_state_t *s = (usrp_state_t*)device->priv; - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[0]); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { - - printf("RX Gain 0 too high, reduce by %f dB\n", - openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); - printf("Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0],openair0_cfg[0].rx_gain[0],gain_range.stop()); + s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[0]); + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); + // limit to maximum gain + if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { + LOG_E(PHY,"RX Gain 0 too high, reduce by %f dB\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] - gain_range.stop()); + exit(-1); + } + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); + LOG_I(PHY,"Setting USRP RX gain to %f (rx_gain %f,gain_range.stop() %f)\n", + openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], + openair0_cfg[0].rx_gain[0],gain_range.stop()); return(0); } @@ -426,376 +335,310 @@ int trx_usrp_stop(openair0_device* device) { /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210[] = { - {3500000000.0,44.0}, - {2660000000.0,49.0}, - {2300000000.0,50.0}, - {1880000000.0,53.0}, - {816000000.0,58.0}, - {-1,0}}; + {3500000000.0,44.0}, + {2660000000.0,49.0}, + {2300000000.0,50.0}, + {1880000000.0,53.0}, + {816000000.0,58.0}, + {-1,0} +}; /*! \brief USRPB210 RX calibration table */ rx_gain_calib_table_t calib_table_b210_38[] = { - {3500000000.0,44.0}, - {2660000000.0,49.8}, - {2300000000.0,51.0}, - {1880000000.0,53.0}, - {816000000.0,57.0}, - {-1,0}}; + {3500000000.0,44.0}, + {2660000000.0,49.8}, + {2300000000.0,51.0}, + {1880000000.0,53.0}, + {816000000.0,57.0}, + {-1,0} +}; /*! \brief USRPx310 RX calibration table */ rx_gain_calib_table_t calib_table_x310[] = { - {3500000000.0,77.0}, - {2660000000.0,81.0}, - {2300000000.0,81.0}, - {1880000000.0,82.0}, - {816000000.0,85.0}, - {-1,0}}; + {3500000000.0,77.0}, + {2660000000.0,81.0}, + {2300000000.0,81.0}, + {1880000000.0,82.0}, + {816000000.0,85.0}, + {-1,0} +}; -/*! \brief Set RX gain offset +/*! \brief Set RX gain offset * \param openair0_cfg RF frontend parameters set by application * \param chain_index RF chain to apply settings to - * \returns 0 in success + * \returns 0 in success */ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_gain_adjust) { - int i=0; - // loop through calibration table to find best adjustment factor for RX frequency - double min_diff = 6e9,diff,gain_adj=0.0; - if (bw_gain_adjust==1) { - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - break; - case 23040000: - gain_adj=1.25; - break; - case 15360000: - gain_adj=3.0; - break; - case 7680000: - gain_adj=6.0; - break; - case 3840000: - gain_adj=9.0; - break; - case 1920000: - gain_adj=12.0; - break; - default: - printf("unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); - exit(-1); - break; + int i=0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9,diff,gain_adj=0.0; + if (bw_gain_adjust==1) { + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + break; + case 23040000: + gain_adj=1.25; + break; + case 15360000: + gain_adj=3.0; + break; + case 7680000: + gain_adj=6.0; + break; + case 3840000: + gain_adj=9.0; + break; + case 1920000: + gain_adj=12.0; + break; + default: + LOG_E(PHY,"unknown sampling rate %d\n",(int)openair0_cfg[0].sample_rate); + exit(-1); + break; + } } - } - while (openair0_cfg->rx_gain_calib_table[i].freq>0) { - diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); - printf("cal %d: freq %f, offset %f, diff %f\n", - i, - openair0_cfg->rx_gain_calib_table[i].freq, + while (openair0_cfg->rx_gain_calib_table[i].freq>0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, openair0_cfg->rx_gain_calib_table[i].offset,diff); if (min_diff > diff) { min_diff = diff; openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; } i++; - } - + } } -/*! \brief print the USRP statistics +/*! \brief print the USRP statistics * \param device the hardware to use * \returns 0 on success */ int trx_usrp_get_stats(openair0_device* device) { - - return(0); - + return(0); } -/*! \brief Reset the USRP statistics -* \param device the hardware to use -* \returns 0 on success -*/ +/*! \brief Reset the USRP statistics + * \param device the hardware to use + * \returns 0 on success + */ int trx_usrp_reset_stats(openair0_device* device) { - - return(0); - + return(0); } - - extern "C" { -/*! \brief Initialize Openair USRP target. It returns 0 if OK -* \param device the hardware to use -* \param openair0_cfg RF frontend parameters set by application -*/ - int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { - - uhd::set_thread_priority_safe(1.0); - usrp_state_t *s = (usrp_state_t*)malloc(sizeof(usrp_state_t)); - memset(s, 0, sizeof(usrp_state_t)); - - // Initialize USRP device + /*! \brief Initialize Openair USRP target. It returns 0 if OK + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + */ + int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { + //uhd::set_thread_priority_safe(1.0); + usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); + // Initialize USRP device + device->openair0_cfg = openair0_cfg; - device->openair0_cfg = openair0_cfg; + std::string args = "type=b200"; + uhd::device_addrs_t device_adds = uhd::device::find(args); - std::string args = "type=b200"; + int vers=0,subvers=0,subsubvers=0; + int bw_gain_adjust=0; + sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); + LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", + uhd::get_version_string().c_str(),vers,subvers,subsubvers); - uhd::device_addrs_t device_adds = uhd::device::find(args); - size_t i; - - int vers=0,subvers=0,subsubvers=0; - int bw_gain_adjust=0; + if(device_adds.size() == 0) { + double usrp_master_clock = 184.32e6; + std::string args = "type=x300"; - sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); - - printf("Checking for USRPs : UHD %s (%d.%d.%d)\n",uhd::get_version_string().c_str(),vers,subvers,subsubvers); - - if(device_adds.size() == 0) - { - double usrp_master_clock = 184.32e6; - - std::string args = "type=x300"; - // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - -// args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - - uhd::device_addrs_t device_adds = uhd::device::find(args); - if(device_adds.size() == 0) - { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; + uhd::device_addrs_t device_adds = uhd::device::find(args); - } + if(device_adds.size() == 0) { + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } + LOG_I(PHY,"Found USRP X300\n"); + s->usrp = uhd::usrp::multi_usrp::make(args); + // lock mboard clocks + s->usrp->set_clock_source("internal"); + //Setting device type to USRP X300/X310 + device->type=USRP_X300_DEV; - printf("Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); + // this is not working yet, master clock has to be set via constructor + // set master clock rate and sample rate for tx & rx for streaming + //s->usrp->set_master_clock_rate(usrp_master_clock); - // lock mboard clocks - s->usrp->set_clock_source("internal"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + // from usrp_time_offset + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + case 7680000: + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + case 1920000: + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 1.25e6; + openair0_cfg[0].rx_bw = 1.25e6; + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + } else { + LOG_I(PHY,"Found USRP B200\n"); + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + s->usrp = uhd::usrp::multi_usrp::make(args); + device->type = USRP_B200_DEV; + if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210; + bw_gain_adjust=0; + } else { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + } - } else { - printf("Found USRP B200"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + s->usrp->set_master_clock_rate(30.72e6); + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 23040000: + s->usrp->set_master_clock_rate(23.04e6); //to be checked + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + s->usrp->set_master_clock_rate(30.72e06); + openair0_cfg[0].tx_sample_advance = 103; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 7680000: + s->usrp->set_master_clock_rate(30.72e6); + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 1920000: + s->usrp->set_master_clock_rate(30.72e6); + openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + openair0_cfg[0].iq_txshift = 4;//shift + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // do not explicitly set the clock to "internal", because this will disable the gpsdo - // // lock mboard clocks - // s->usrp->set_clock_source("internal"); - // set master clock rate and sample rate for tx & rx for streaming + for(int i=0; iusrp->get_rx_num_channels(); i++) { + if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); + set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); - device->type = USRP_B200_DEV; + ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); + // limit to maximum gain + AssertFatal( openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] <= gain_range.stop(), + "RX Gain too high, lower by %f dB\n", + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); + s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); + LOG_I(PHY,"RX Gain %d %f (%f) => %f (max %f)\n",i, + openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], + openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); + } + } + for(int i=0; iusrp->get_tx_num_channels(); i++) { + if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); + s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); + s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); + } + } + //s->usrp->set_clock_source("external"); + //s->usrp->set_time_source("external"); - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - } - else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - } + // display USRP settings + LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } + // create tx & rx streamer + uhd::stream_args_t stream_args_rx("sc16", "sc16"); + int samples=openair0_cfg[0].sample_rate; + //while ( samples > s->rx_stream->get_max_num_samps()) + samples/=24000; + stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); + LOG_I(PHY,"rx_max_num_samps %u\n",s->rx_stream->get_max_num_samps()); - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - //printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); + uhd::stream_args_t stream_args_tx("sc16", "sc16"); + for (int i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] > gain_range.stop()) { - - printf("RX Gain %lu too high, lower by %f dB\n",i,openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); - printf("RX Gain %lu %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); - } - } - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - //printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); - } - } + /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ + for(int i=0; iusrp->get_tx_num_channels() && iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); + for(int i=0; iusrp->get_rx_num_channels() && iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - // display USRP settings - std::cout << boost::format("Actual master clock: %fMHz...") % (s->usrp->get_master_clock_rate()/1e6) << std::endl; - - sleep(1); + s->usrp->set_time_now(uhd::time_spec_t(0.0)); - // create tx & rx streamer - uhd::stream_args_t stream_args_rx("sc16", "sc16"); - //stream_args_rx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].rx_num_channels*openair0_cfg[0].samples_per_packet)); - for (i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - std::cout << boost::format("rx_max_num_samps %u") % (s->rx_stream->get_max_num_samps()) << std::endl; - //openair0_cfg[0].samples_per_packet = s->rx_stream->get_max_num_samps(); + for (int i=0; iusrp->get_rx_rate(i)/1e6); + LOG_I(PHY," Actual RX frequency: %fGHz...\n", s->usrp->get_rx_freq(i)/1e9); + LOG_I(PHY," Actual RX gain: %f...\n", s->usrp->get_rx_gain(i)); + LOG_I(PHY," Actual RX bandwidth: %fM...\n", s->usrp->get_rx_bandwidth(i)/1e6); + LOG_I(PHY," Actual RX antenna: %s...\n", s->usrp->get_rx_antenna(i).c_str()); + } - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - //stream_args_tx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].tx_num_channels*openair0_cfg[0].samples_per_packet)); - for (i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - std::cout << boost::format("tx_max_num_samps %u") % (s->tx_stream->get_max_num_samps()) << std::endl; + for (int i=0; iusrp->get_tx_rate(i)/1e6); + LOG_I(PHY," Actual TX frequency: %fGHz...\n", s->usrp->get_tx_freq(i)/1e9); + LOG_I(PHY," Actual TX gain: %f...\n", s->usrp->get_tx_gain(i)); + LOG_I(PHY," Actual TX bandwidth: %fM...\n", s->usrp->get_tx_bandwidth(i)/1e6); + LOG_I(PHY," Actual TX antenna: %s...\n", s->usrp->get_tx_antenna(i).c_str()); + } + LOG_I(PHY,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs()); - /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - } - } - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - } - } - - s->usrp->set_time_now(uhd::time_spec_t(0.0)); - - - for (i=0;iusrp->get_rx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX frequency: %fGHz...") % (s->usrp->get_rx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual RX gain: %f...") % (s->usrp->get_rx_gain(i)) << std::endl; - std::cout << boost::format("Actual RX bandwidth: %fM...") % (s->usrp->get_rx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX antenna: %s...") % (s->usrp->get_rx_antenna(i)) << std::endl; - } - } - - for (i=0;iusrp->get_tx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX frequency: %fGHz...") % (s->usrp->get_tx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual TX gain: %f...") % (s->usrp->get_tx_gain(i)) << std::endl; - std::cout << boost::format("Actual TX bandwidth: %fM...") % (s->usrp->get_tx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX antenna: %s...") % (s->usrp->get_tx_antenna(i)) << std::endl; - } - } - - std::cout << boost::format("Device timestamp: %f...") % (s->usrp->get_time_now().get_real_secs()) << std::endl; - - device->priv = s; - device->trx_start_func = trx_usrp_start; - device->trx_write_func = trx_usrp_write; - device->trx_read_func = trx_usrp_read; + device->priv = s; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; device->trx_get_stats_func = trx_usrp_get_stats; device->trx_reset_stats_func = trx_usrp_reset_stats; device->trx_end_func = trx_usrp_end; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5ab6b7cddf..6e588f7f3c 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -75,15 +75,113 @@ #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" + +#define DEBUG_REALTIME 1 +#if DEBUG_REALTIME + +typedef struct latency_stat { + uint64_t counter; + uint64_t stat1100; + uint64_t stat1200; + uint64_t stat1500; + uint64_t stat2000; + uint64_t stat3000; +} latency_stat_t; + +static inline void saif_meas(int frame_rx) { + static latency_stat_t __thread latency_stat; + static struct timespec __thread last= {0}; + struct timespec now; + clock_gettime(CLOCK_MONOTONIC_RAW, &now); + if ( last.tv_sec ) { + uint64_t diffTime = ((uint64_t)now.tv_sec *1000 *1000 *1000 + now.tv_nsec) - + ((uint64_t)last.tv_sec *1000 *1000 *1000 + last.tv_nsec); + diffTime/=1000; + latency_stat.counter++; + if ( diffTime >= 1100 ) { + if (diffTime < 1200 ) + latency_stat.stat1100++; + else if ( diffTime < 1500 ) + latency_stat.stat1200++; + else if ( diffTime < 2000 ) + latency_stat.stat1500++; + else if ( diffTime < 3000 ) + latency_stat.stat2000++; + else + latency_stat.stat3000++; + } + if ( diffTime>=1100 || latency_stat.counter%20000==0 ) { + time_t current=time(NULL); + LOG_W(HW, + "%.2f delay=%llu Period stats %2.6f%% below 100µs\ncumul of events: 1100=%ld 1200=%ld 1500=%ld 2000=%ld >3000=%ld - (frame_rx=%d) - %s", + now.tv_sec+(double)now.tv_nsec/1e9, + diffTime, + (latency_stat.counter-latency_stat.stat1100-latency_stat.stat1200- + latency_stat.stat1500-latency_stat.stat2000-latency_stat.stat3000)/ + (float)latency_stat.counter *100, + latency_stat.stat1100, latency_stat.stat1200, + latency_stat.stat1500, latency_stat.stat2000, + latency_stat.stat3000, + frame_rx, ctime(¤t)); + fflush(stdout); + } + + } + last=now; +} + +typedef struct m { + unsigned long long iterations; + unsigned long long sum; + unsigned long long maxArray[11]; +} Meas; + + +void printMeas(char * txt, Meas *M, int period) { + if (M->iterations%period == 0 ) { + char txt2[512]; + sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", + txt, M->sum/M->iterations,M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], + M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); + LOG_W(PHY,txt2); + } +} + +int cmpint(const void* a, const void* b) { + unsigned long long* aa=(unsigned long long*)a; + unsigned long long* bb=(unsigned long long*)b; + return (int)(*aa-*bb); +} + +void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { + unsigned long long end=rdtsc(); + long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); + printMeas(txt,M,period); +} + +#else +#define check(a) do {} while (0) +#define saif_meas(a) do {} while (0) +#define update_max_times(a,b) do {} while (0) +#define print_meas(a,b) do {} while (0) +#endif +/* End of Changed by SYRTEM */ + #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL typedef enum { - pss=0, - pbch=1, - si=2 + pss=0, + pbch=1, + si=2 } sync_mode_t; + void init_UE_threads(int nb_inst); void *UE_thread(void *arg); void init_UE(int nb_inst); @@ -92,7 +190,6 @@ extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; - extern openair0_config_t openair0_cfg[MAX_CARDS]; extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -114,96 +211,122 @@ extern void exit_fun(const char* s); #define MHz (1000 * KHz) typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; } eutra_band_t; typedef struct band_info_s { - int nbands; - eutra_band_t band_info[100]; + int nbands; + eutra_band_t band_info[100]; } band_info_t; band_info_t bands_to_scan; static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {22, 3510 * MHz, 3590 * MHz, 3410 * MHz, 3490 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, }; pthread_t main_ue_thread; pthread_attr_t attr_UE_thread; struct sched_param sched_param_UE_thread; +void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { + +#ifdef DEADLINE_SCHEDULER + if (sched_runtime!=0) { + struct sched_attr attr= {0}; + attr.size = sizeof(attr); + // This creates a .5 ms reservation + attr.sched_policy = SCHED_DEADLINE; + attr.sched_runtime = sched_runtime; + attr.sched_deadline = sched_deadline; + attr.sched_period = 0; + AssertFatal(sched_setattr(0, &attr, 0) == 0, + "[SCHED] main eNB thread: sched_setattr failed %s \n",perror(errno)); + LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", + (unsigned long)gettid(), sched_getcpu()); + } + +#else + if (cpuset!=NULL) + AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); + struct sched_param sp; + sp.sched_priority = sched_fifo; + AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, + "Can't set thread priority, Are you root?\n"); +#endif + + // Lock memory from swapping. This is a process wide call (not constraint to this thread). + mlockall(MCL_CURRENT | MCL_FUTURE); + pthread_setname_np( pthread_self(), name ); + + // LTS: this sync stuff should be wrong + printf("waiting for sync (%s)\n",name); + pthread_mutex_lock(&sync_mutex); + printf("Locked sync_mutex, waiting (%s)\n",name); + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + pthread_mutex_unlock(&sync_mutex); + printf("starting %s\n",name); +} + void init_UE(int nb_inst) { - int error_code; - int inst; - PHY_VARS_UE *UE; - int ret; + PHY_VARS_UE *UE; - for (inst=0;instrfdevice), &openair0_cfg[0]); - if (ret !=0){ - exit_fun("Error loading device library"); + AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); + + UE->rfdevice.host_type = BBU_HOST; + // UE->rfdevice.type = NONE_DEV; + AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL), ""); + pthread_setname_np( UE->proc.pthread_ue, "main UE" ); } - UE->rfdevice.host_type = BBU_HOST; - // UE->rfdevice.type = NONE_DEV; - error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL); - - if (error_code!= 0) { - LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); - return; - } else { - LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); - pthread_setname_np( UE->proc.pthread_ue, "main UE" ); - } - } - printf("UE threads created\n"); + printf("UE threads created\n"); #ifdef USE_MME - - while (start_UE == 0) { - sleep(1); - } - + while (start_UE == 0) { + sleep(1); + } #endif - + } /*! @@ -212,388 +335,374 @@ void init_UE(int nb_inst) { * \param arg is a pointer to a \ref PHY_VARS_UE structure. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *UE_thread_synch(void *arg) -{ - static int UE_thread_synch_retval; - int i, hw_slot_offset; - PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; - int current_band = 0; - int current_offset = 0; - sync_mode_t sync_mode = pbch; - int CC_id = UE->CC_id; - int ind; - int found; - int freq_offset=0; +static void *UE_thread_synch(void *arg) { + static int __thread UE_thread_synch_retval; + int i, hw_slot_offset; + PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; + int current_band = 0; + int current_offset = 0; + sync_mode_t sync_mode = pbch; + int CC_id = UE->CC_id; + int ind; + int found; + int freq_offset=0; - UE->is_synchronized = 0; - printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); - printf("waiting for sync (UE_thread_synch) \n"); + UE->is_synchronized = 0; + printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); + printf("waiting for sync (UE_thread_synch) \n"); #ifndef DEADLINE_SCHEDULER - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; + int policy, s, j; + struct sched_param sparam; + char cpu_affinity[1024]; + cpu_set_t cpuset; - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ - CPU_ZERO(&cpuset); + /* Set affinity mask to include CPUs 1 to MAX_CPUS */ + /* CPU 0 is reserved for UHD threads */ + CPU_ZERO(&cpuset); - #ifdef CPU_AFFINITY - if (get_nprocs() >2) - { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); +#ifdef CPU_AFFINITY + if (get_nprocs() >2) { + for (j = 1; j < get_nprocs(); j++) + CPU_SET(j, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } } - } - #endif +#endif - /* Check the actual affinity mask assigned to the thread */ + /* Check the actual affinity mask assigned to the thread */ - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_getaffinity_np"); + exit_fun("Error getting processor affinity "); + } + memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + for (j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET(j, &cpuset)) { + char temp[1024]; + sprintf(temp, " CPU_%d ", j); + strcat(cpu_affinity, temp); + } - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) - { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) - { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); + memset(&sparam, 0 , sizeof (sparam)); + sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; + policy = SCHED_FIFO ; - } + s = pthread_setschedparam(pthread_self(), policy, &sparam); + if (s != 0) { + perror("pthread_setschedparam : "); + exit_fun("Error setting thread priority"); + } + s = pthread_getschedparam(pthread_self(), &policy, &sparam); + if (s != 0) { + perror("pthread_getschedparam : "); + exit_fun("Error getting thread priority"); - LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); + } + + LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), + (policy == SCHED_FIFO) ? "SCHED_FIFO" : + (policy == SCHED_RR) ? "SCHED_RR" : + (policy == SCHED_OTHER) ? "SCHED_OTHER" : + "???", + (int) sparam.sched_priority, cpu_affinity); #endif + printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); + ind = 0; + found = 0; + if (UE->UE_scan == 0) { + do { + current_band = eutra_bands[ind].band; + printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); - printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); - ind = 0; - found = 0; + if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) { + for (i=0; i<4; i++) + uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; + found = 1; + break; + } - if (UE->UE_scan == 0) { - do { - current_band = eutra_bands[ind].band; - printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); + ind++; + } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) { - for (i=0; i<4; i++) - uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; - - found = 1; - break; - } - - ind++; - } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - - if (found == 0) { - exit_fun("Can't find EUTRA band for frequency"); - return &UE_thread_synch_retval; - } + if (found == 0) { + exit_fun("Can't find EUTRA band for frequency"); + return &UE_thread_synch_retval; + } - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels); + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels); - for (i=0;irf_map.card].rx_num_channels;i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - if (uplink_frequency_offset[CC_id][i] != 0) // - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; - else //FDD - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; - } + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + if (uplink_frequency_offset[CC_id][i] != 0) // + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; + else //FDD + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + } - sync_mode = pbch; + sync_mode = pbch; - } else if (UE->UE_scan == 1) { - current_band=0; - - for (i=0; irf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; - - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - } - } - - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_sync_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); - - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } - - while (oai_exit==0) { - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } - - - while (UE->proc.instance_cnt_synch < 0) { - // the thread waits here most of the time - pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); - } - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_synch_retval; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 ); - - switch (sync_mode) { - case pss: - LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - current_offset += 20000000; // increase by 20 MHz - - if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { - current_band++; - current_offset=0; - } - - if (current_band==bands_to_scan.nbands) { + } else if (UE->UE_scan == 1) { current_band=0; + + for (i=0; irf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; + + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + } + } + + + pthread_mutex_lock(&sync_mutex); + printf("Locked sync_mutex, waiting (UE_sync_thread)\n"); + + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + + pthread_mutex_unlock(&sync_mutex); + printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); + + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); oai_exit=1; - } - - for (i=0; irf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; - - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - if (UE->UE_scan_carrier) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - - } - - break; - - case pbch: - - LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - if (initial_sync( UE, UE->mode ) == 0) { - - hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; - LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", - hw_slot_offset, - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, - UE->UE_scan_carrier ); - - if (UE->UE_scan_carrier == 1) { - - UE->UE_scan_carrier = 0; - // rerun with new cell parameters and frequency-offset - for (i=0;irf_map.card].rx_num_channels;i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; - downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; - freq_offset=0; - } - - // reconfigure for potentially different bandwidth - switch(UE->frame_parms.N_RB_DL) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; - // openair0_cfg[0].rx_gain[0] -= 0; - break; - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); - UE->rfdevice.trx_stop_func(&UE->rfdevice); - sleep(1); - init_frame_parms(&UE->frame_parms,1); - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } - } - else { - UE->is_synchronized = 1; - - if( UE->mode == rx_dump_frame ){ - FILE *fd; - if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present - if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - else { - LOG_E(PHY,"Cannot open file for writing\n"); - exit(0); - } - } - else { - UE->is_synchronized = 0; - } - } - } - } else { - // initial sync failed - // calculate new offset and try again - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) { - freq_offset += 100; - freq_offset *= -1; - } else { - freq_offset *= -1; - } - - if (abs(freq_offset) > 7500) { - LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); - FILE *fd; - if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - mac_xface->macphy_exit("No cell synchronization found, abandoning"); - return &UE_thread_synch_retval; // not reached - } - } - else { - - } - LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); - - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - - if (UE->UE_scan_carrier==1) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - - }// initial_sync=0 - - break; - - case si: - default: - break; } + while (oai_exit==0) { - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); + exit_fun("noting to add"); + return &UE_thread_synch_retval; + } - // indicate readiness - UE->proc.instance_cnt_synch--; - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + while (UE->proc.instance_cnt_synch < 0) { + // the thread waits here most of the time + pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); + } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); - } // while !oai_exit + if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" ); + exit_fun("nothing to add"); + return &UE_thread_synch_retval; + } - return &UE_thread_synch_retval; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 ); + + switch (sync_mode) { + case pss: + LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + current_offset += 20000000; // increase by 20 MHz + + if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { + current_band++; + current_offset=0; + } + + if (current_band==bands_to_scan.nbands) { + current_band=0; + oai_exit=1; + } + + for (i=0; irf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; + if (UE->UE_scan_carrier) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + + } + + break; + + case pbch: + + LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + if (initial_sync( UE, UE->mode ) == 0) { + + hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti; + LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", + hw_slot_offset, + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, + UE->UE_scan_carrier ); + + if (UE->UE_scan_carrier == 1) { + + UE->UE_scan_carrier = 0; + // rerun with new cell parameters and frequency-offset + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; + freq_offset=0; + } + + // reconfigure for potentially different bandwidth + switch(UE->frame_parms.N_RB_DL) { + case 6: + openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; + openair0_cfg[UE->rf_map.card].rx_bw =.96e6; + openair0_cfg[UE->rf_map.card].tx_bw =.96e6; + // openair0_cfg[0].rx_gain[0] -= 12; + break; + case 25: + openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; + openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; + openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; + // openair0_cfg[0].rx_gain[0] -= 6; + break; + case 50: + openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; + openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; + openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; + // openair0_cfg[0].rx_gain[0] -= 3; + break; + case 100: + openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; + openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; + openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; + // openair0_cfg[0].rx_gain[0] -= 0; + break; + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + UE->rfdevice.trx_stop_func(&UE->rfdevice); + sleep(1); + init_frame_parms(&UE->frame_parms,1); + if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + } + } else { + UE->is_synchronized = 1; + + if( UE->mode == rx_dump_frame ) { + FILE *fd; + if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } else { + LOG_E(PHY,"Cannot open file for writing\n"); + exit(0); + } + } else { + UE->is_synchronized = 0; + } + } + } + } else { + // initial sync failed + // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) { + freq_offset += 100; + freq_offset *= -1; + } else { + freq_offset *= -1; + } + + if (abs(freq_offset) > 7500) { + LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); + FILE *fd; + if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { + fwrite((void*)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } + mac_xface->macphy_exit("No cell synchronization found, abandoning"); + return &UE_thread_synch_retval; // not reached + } + } else { + + } + LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + + for (i=0; irf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; + + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + if (UE->UE_scan_carrier==1) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + + }// initial_sync=0 + + break; + + case si: + default: + break; + } + + + if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" ); + exit_fun("noting to add"); + return &UE_thread_synch_retval; + } + + // indicate readiness + UE->proc.instance_cnt_synch--; + + if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" ); + exit_fun("noting to add"); + return &UE_thread_synch_retval; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); + } // while !oai_exit + + return &UE_thread_synch_retval; } @@ -601,259 +710,116 @@ static void *UE_thread_synch(void *arg) /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. * This thread performs the phy_procedures_UE_RX() on every received slot. - * then, if TX is enabled it performs TX for n+4. + * then, if TX is enabled it performs TX for n+4. * \param arg is a pointer to a \ref PHY_VARS_UE structure. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *UE_thread_rxn_txnp4(void *arg) -{ - static int UE_thread_rxtx_retval; - UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; - int ret; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; - proc->instance_cnt_rxtx=-1; +static void *UE_thread_rxn_txnp4(void *arg) { + static __thread int UE_thread_rxtx_retval; + UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; + int ret; + PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; + + static long long __thread instance_cnt_rxtx=-1; + proc->subframe_rx=proc->sub_frame_start; + + char threadName[256]= {0}; + sprintf(threadName,"UE_thread_rxn_txnp4_%d",proc->sub_frame_start); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(proc->sub_frame_start+1, &cpuset); + init_thread(900000,1000000 , 40, &cpuset,//sched_get_priority_max(SCHED_FIFO)-1, + threadName); + + while (!oai_exit) { + // Wait Rx data to process are available + AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + if ( (instance_cnt_rxtx+proc->sub_frame_step)%10 != proc->subframe_rx && instance_cnt_rxtx!=-1 ) + LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %d, got %d\n", + (instance_cnt_rxtx+proc->sub_frame_step)%10, proc->subframe_rx); + instance_cnt_rxtx=proc->subframe_rx; + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + + static __thread Meas t2= {0}, t3= {0}; + unsigned long long current=rdtsc(); + updateTimes(proc->gotIQs, &t2, 10000, "saif: Delay to wake up UE_Thread_Rx (case 2)"); + + // Process Rx data for one sub-frame + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadName, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadName, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } + phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); + } + + if (UE->mac_enabled==1) { + + ret = mac_xface->ue_scheduler(UE->Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + if ( ret != CONNECTION_OK) { + char *txt; + switch (ret) { + case CONNECTION_LOST: + txt="RRC Connection lost, returning to PRACH"; + break; + case PHY_RESYNCH: + txt="RRC Connection lost, trying to resynch"; + break; + case RESYNCH: + txt="return to PRACH and perform a contention-free access"; + break; + default: + txt="UNKNOWN RETURN CODE"; + }; + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); + } + } + // Prepare the future Tx data + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) + phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); -#ifdef DEADLINE_SCHEDULER + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && + (UE->frame_parms.frame_type == TDD)) + if (UE->mode != loop_through_memory) + phy_procedures_UE_S_TX(UE,0,0,no_relay); + updateTimes(current, &t3, 10000, "saif: Delay to process sub-frame (case 3)"); - struct sched_attr attr; - unsigned int flags = 0; + } - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0; - - // This creates a .5ms reservation every 1ms period - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 900000; // each rx thread requires 1ms to finish its job - attr.sched_deadline = 1000000; // each rx thread will finish within 1ms - attr.sched_period = 1000000; // each rx thread has a period of 1ms from the starting point - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] UE_thread_rxtx : sched_setattr failed\n"); +// thread finished return &UE_thread_rxtx_retval; - } - -#else - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; - cpu_set_t cpuset; - - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ - CPU_ZERO(&cpuset); - - #ifdef CPU_AFFINITY - if (get_nprocs() >2) - { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - } - #endif - - /* Check the actual affinity mask assigned to the thread */ - - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) - { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) - { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) - { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) - { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - - } - - LOG_I( HW, "[SCHED][UE] Started UE RX thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); - - -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread_rxn_txnp4)\n"); - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread_rxn_txnp4)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - -#define THREAD_NAME_LEN 16 - char threadname[THREAD_NAME_LEN]; - ret = pthread_getname_np(proc->pthread_rxtx, threadname, THREAD_NAME_LEN); - if (ret != 0) - { - perror("pthread_getname_np : "); - exit_fun("Error getting thread name"); - } - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread_rxtx)\n"); - - printf("Starting UE RXN_TXNP4 thread (%s)\n", threadname); - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->subframe_rx&1), 1 ); - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("nothing to add"); - return &UE_thread_rxtx_retval; - } - - while (proc->instance_cnt_rxtx < 0) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->subframe_rx&1), 1 ); - // most of the time, the thread is waiting here - pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_WAIT_COND_RXTX0+(proc->subframe_rx&1), 0 ); - - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - return &UE_thread_rxtx_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_COND_WAIT0+(proc->subframe_rx&1), 0 ); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->subframe_rx&1), 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_UE+(proc->subframe_rx&1), proc->subframe_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_UE+(proc->subframe_tx&1), proc->subframe_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE+(proc->subframe_rx&1), proc->frame_rx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE+(proc->subframe_tx&1), proc->frame_tx ); - - lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { - - if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", - threadname, - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } else { - LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", - threadname, - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } - phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); - } - - if (UE->mac_enabled==1) { - - ret = mac_xface->ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); - - if (ret == CONNECTION_LOST) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, returning to PRACH\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = PRACH; - } else if (ret == PHY_RESYNCH) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u RRC Connection lost, trying to resynch\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = RESYNCH; - } else if (ret == PHY_HO_PRACH) { - LOG_I( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u, return to PRACH and perform a contention-free access\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx ); - UE->UE_mode[0] = PRACH; - } - } - - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) { - - if (UE->mode != loop_through_memory) { - phy_procedures_UE_TX(UE,proc,0,0,UE->mode,no_relay); - } - } - - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && - (UE->frame_parms.frame_type == TDD)) { - - if (UE->mode != loop_through_memory) { - phy_procedures_UE_S_TX(UE,0,0,no_relay); - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->subframe_rx&1), 0 ); - - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->subframe_rx&1), 1 ); - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - return &UE_thread_rxtx_retval; - } - - proc->instance_cnt_rxtx--; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, proc->instance_cnt_rxtx); - - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - return &UE_thread_rxtx_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_DECREMENT0+(proc->subframe_rx&1), 0 ); - } - - // thread finished - return &UE_thread_rxtx_retval; } - - - - #define RX_OFF_MAX 10 #define RX_OFF_MIN 5 #define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2) @@ -870,764 +836,208 @@ static void *UE_thread_rxn_txnp4(void *arg) void *UE_thread(void *arg) { - static int UE_thread_retval; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; - // int tx_enabled = 0; - unsigned int rxs,txs; - int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); - openair0_timestamp timestamp,timestamp1; - void* rxp[2], *txp[2]; + PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; + // int tx_enabled = 0; + int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); + openair0_timestamp timestamp,timestamp1; + void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + int start_rx_stream = 0; + int i; + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(3, &cpuset); + init_thread(100000, 500000, 40, &cpuset, //sched_get_priority_max(SCHED_FIFO), + "main UE"); #ifdef NAS_UE - MessageDef *message_p; + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); #endif - int start_rx_stream = 0; - int rx_off_diff = 0; - int rx_correction_timer = 0; - int i; - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE); - - // This creates a .5 ms reservation - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 100000; - attr.sched_deadline = 500000; - attr.sched_period = 500000; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] main eNB thread: sched_setattr failed\n"); - exit_fun("Nothing to add"); - return &UE_thread_retval; - } - LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", - (unsigned long)gettid(), sched_getcpu()); - -#else - struct sched_param sp; - sp.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread)\n"); - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread)\n"); - - printf("starting UE thread\n"); - -#ifdef NAS_UE - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); -#endif - - while (!oai_exit) { - - if (UE->is_synchronized == 0) { - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] verror locking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - int instance_cnt_synch = UE->proc.instance_cnt_synch; - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - if (instance_cnt_synch < 0) { // we can invoke the synch - // grab 10 ms of signal and wakeup synch thread - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&rxdata[i][0]; - - if (UE->mode != loop_through_memory) { - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx); - - - if (rxs!=UE->frame_parms.samples_per_tti*10) { - LOG_E(PHY, "problem in rx 1! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti*10, rxs); - exit_fun("problem in rx 1"); - return &UE_thread_retval; - } - } - - instance_cnt_synch = ++UE->proc.instance_cnt_synch; - if (instance_cnt_synch == 0) { - if (pthread_cond_signal(&UE->proc.cond_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } // - else { - // grab 10 ms of signal into dummy buffer - - if (UE->mode != loop_through_memory) { - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0;sf<10;sf++) { - // printf("Reading dummy sf %d\n",sf); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - - if (rxs!=UE->frame_parms.samples_per_tti){ - LOG_E(PHY, "problem in rx 2! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs); - exit_fun("problem in rx 2"); - return &UE_thread_retval; - } - - } - } - } - - } // UE->is_synchronized==0 - else { - if (start_rx_stream==0) { - start_rx_stream=1; - if (UE->mode != loop_through_memory) { - - if (UE->no_timing_correction==0) { - LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx); - if (rxs != UE->rx_offset) { - LOG_E(PHY, "problem in rx 3! want #samples=%d but got only %d!\n", UE->rx_offset, rxs); - exit_fun("problem in rx 3!"); - return &UE_thread_retval; - } - } - UE->rx_offset=0; - UE->proc.proc_rxtx[0].frame_rx++; - UE->proc.proc_rxtx[1].frame_rx++; - - // read in first symbol - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)rxdata, - UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); - if (rxs != (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0)) { - LOG_E(PHY, "problem in rx 4! want #samples=%d but got only %d!\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, rxs); - exit_fun("problem in rx 4!"); - return &UE_thread_retval; - } - slot_fep(UE, - 0, - 0, - 0, - 0, - 0); - if (rxs != UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - } //UE->mode != loop_through_memory - else - rt_sleep_ns(1000000); - - }// start_rx_stream==0 - else { - //UE->proc.proc_rxtx[0].frame_rx++; - //UE->proc.proc_rxtx[1].frame_rx++; - - for (int sf=0;sf<10;sf++) { - for (i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&rxdata[i][UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti)]; - // grab signal for subframe - if (UE->mode != loop_through_memory) { - if (sf<9) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - if (rxs != UE->frame_parms.samples_per_tti) { - LOG_E(PHY, "problem in rx 5! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti, rxs); - exit_fun("problem in rx 5!"); - return &UE_thread_retval; - } - - // prepare tx buffer pointers - for (i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - txs = UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_tx, - 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, rxs ); - if (txs != UE->frame_parms.samples_per_tti) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti); - exit_fun( "problem transmitting samples" ); - } - } - - else { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 ); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - if (rxs != (UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0)) { - LOG_E(PHY, "problem in rx 6! want #samples=%d but got only %d!\n", UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0, rxs); - exit_fun("problem in rx 6!"); - return &UE_thread_retval; - } - - // prepare tx buffer pointers - for (i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sf+2)%10)*UE->frame_parms.samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 1 ); - txs = UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - UE->frame_parms.samples_per_tti - rx_off_diff, - UE->frame_parms.nb_antennas_tx, - 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS, rxs ); - if (txs != UE->frame_parms.samples_per_tti - rx_off_diff) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, UE->frame_parms.samples_per_tti-rx_off_diff); - exit_fun( "problem transmitting samples" ); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 1 ); - // read in first symbol of next frame and adjust for timing drift - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp1, - (void**)rxdata, - UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 - rx_off_diff, - UE->frame_parms.nb_antennas_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_SF9, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, rxs ); - if (rxs != (UE->frame_parms.ofdm_symbol_size + UE->frame_parms.nb_prefix_samples0 - rx_off_diff)) { - LOG_E(PHY, "problem in rx 7! want #samples=%d but got only %d! rx_off_diff=%d\n", UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 - rx_off_diff, rxs, rx_off_diff); - exit_fun("problem in rx 7!"); - return &UE_thread_retval; - } - rx_off_diff = 0; - } - } - // operate on thread sf mod 2 - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sf&1]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+(proc->subframe_rx&1), 1 ); - // lock mutex - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - // increment instance count and change proc subframe/frame variables - int instance_cnt_rxtx = ++proc->instance_cnt_rxtx; - if(sf == 0) - { - UE->proc.proc_rxtx[0].frame_rx++; - UE->proc.proc_rxtx[1].frame_rx++; - } - proc->subframe_rx=sf; - proc->subframe_tx=(sf+4)%10; - proc->frame_tx = proc->frame_rx + ((proc->subframe_rx>5)?1:0); - proc->timestamp_tx = timestamp+(4*UE->frame_parms.samples_per_tti)-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; - - /* - if (sf != (timestamp/UE->frame_parms.samples_per_tti)%10) { - LOG_E(PHY,"steady-state UE_thread error : frame_rx %d, subframe_rx %d, frame_tx %d, subframe_tx %d, rx subframe %d\n",proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,(timestamp/UE->frame_parms.samples_per_tti)%10); - exit(-1); - } - */ - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_LOCK_MUTEX_RXTX_FOR_CNT_INCREMENT0+(proc->subframe_rx&1), 0 ); - - - if (instance_cnt_rxtx == 0) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX, 1 ); - if (pthread_cond_signal(&proc->cond_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - LOG_D(PHY, "firing up rxtx_thread[%d] at subframe %d\n", sf&1, sf); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SIGNAL_COND_RXTX, 0 ); - - } else { - LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rxtx); - if (instance_cnt_rxtx > 2) { - sleep(1); - exit_fun("instance_cnt_rxtx > 2"); - return &UE_thread_retval; - } - } - if (UE->mode == loop_through_memory) { - printf("Processing subframe %d",proc->subframe_rx); - getchar(); - } - }// for sf=0..10 - if ((UE->rx_offset<(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset > RX_OFF_MIN) && - (rx_correction_timer == 0)) { - rx_off_diff = -UE->rx_offset + RX_OFF_MIN; - LOG_D(PHY,"UE->rx_offset %d > %d, diff %d\n",UE->rx_offset,RX_OFF_MIN,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset < ((10*UE->frame_parms.samples_per_tti)-RX_OFF_MIN)) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = 10*UE->frame_parms.samples_per_tti - RX_OFF_MIN - UE->rx_offset; - LOG_D(PHY,"UE->rx_offset %d < %d, diff %d\n",UE->rx_offset,10*UE->frame_parms.samples_per_tti-RX_OFF_MIN,rx_off_diff); - - rx_correction_timer = 5; - } - - if (rx_correction_timer>0) - rx_correction_timer--; - } // start_rx_stream==1 - } // UE->is_synchronized==1 - - } // while !oai_exit - return NULL; -} // UE_thread - -/* -void *UE_thread_old(void *arg) -{ - UNUSED(arg) - static int UE_thread_retval; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; - int spp = openair0_cfg[0].samples_per_packet; - int slot=1, frame=0, hw_subframe=0, rxpos=0, txpos=openair0_cfg[0].tx_scheduling_advance; -#ifdef __AVX2__ - int dummy[2][spp] __attribute__((aligned(32))); -#else - int dummy[2][spp] __attribute__((aligned(16))); -#endif - int dummy_dump = 0; - int tx_enabled = 0; - int start_rx_stream = 0; - int rx_off_diff = 0; - int rx_correction_timer = 0; - int first_rx = 0; - RTIME T0; - unsigned int rxs; - void* rxp[2]; - - openair0_timestamp timestamp; - -#ifdef NAS_UE - MessageDef *message_p; -#endif - -#ifdef DEADLINE_SCHEDULER - - struct sched_attr attr; - unsigned int flags = 0; - - attr.size = sizeof(attr); - attr.sched_flags = 0; - attr.sched_nice = 0; - attr.sched_priority = 0;//sched_get_priority_max(SCHED_DEADLINE); - - // This creates a .5 ms reservation - attr.sched_policy = SCHED_DEADLINE; - attr.sched_runtime = 100000; - attr.sched_deadline = 500000; - attr.sched_period = 500000; - - if (sched_setattr(0, &attr, flags) < 0 ) { - perror("[SCHED] main eNB thread: sched_setattr failed\n"); - exit_fun("Nothing to add"); - return &UE_thread_retval; - } - LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n", - (unsigned long)gettid(), sched_getcpu()); - -#else - struct sched_param sp; - sp.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); -#endif - - // Lock memory from swapping. This is a process wide call (not constraint to this thread). - mlockall(MCL_CURRENT | MCL_FUTURE); - - printf("waiting for sync (UE_thread)\n"); - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("unlocked sync_mutex, waiting (UE_thread)\n"); - - printf("starting UE thread\n"); - -#ifdef NAS_UE - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); -#endif - - T0 = rt_get_time_ns(); - first_rx = 1; - rxpos=0; - - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME, hw_subframe ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, frame ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP, dummy_dump ); - - - while (rxpos < (1+hw_subframe)*UE->frame_parms.samples_per_tti) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - -#ifndef USRP_DEBUG - - DevAssert( UE->frame_parms.nb_antennas_rx <= 2 ); - void* rxp[2]; - - for (int i=0; iframe_parms.nb_antennas_rx; i++) - rxp[i] = (dummy_dump==0) ? (void*)&rxdata[i][rxpos] : (void*)dummy[i]; - - - if (UE->mode != loop_through_memory) { - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - spp - ((first_rx==1) ? rx_off_diff : 0), - UE->frame_parms.nb_antennas_rx); - - if (rxs != (spp- ((first_rx==1) ? rx_off_diff : 0))) { - printf("rx error: asked %d got %d ",spp - ((first_rx==1) ? rx_off_diff : 0),rxs); - if (UE->is_synchronized == 1) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - } - } - - if (rx_off_diff !=0) - LOG_D(PHY,"frame %d, rx_offset %d, rx_off_diff %d\n",UE->frame_rx,UE->rx_offset,rx_off_diff); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - // Transmit TX buffer based on timestamp from RX - if ((tx_enabled==1) && (UE->mode!=loop_through_memory)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - - DevAssert( UE->frame_parms.nb_antennas_tx <= 2 ); - void* txp[2]; - - for (int i=0; iframe_parms.nb_antennas_tx; i++) - txp[i] = (void*)&txdata[i][txpos]; - - UE->rfdevice.trx_write_func(&openair0, - (timestamp+openair0_cfg[0].tx_scheduling_advance-openair0_cfg[0].tx_sample_advance), - txp, - spp - ((first_rx==1) ? rx_off_diff : 0), - UE->frame_parms.nb_antennas_tx, - 1); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - } - else if (UE->mode == loop_through_memory) - rt_sleep_ns(1000000); -#else - // define USRP_DEBUG is active - rt_sleep_ns(1000000); -#endif - - rx_off_diff = 0; - first_rx = 0; - - rxpos += spp; - txpos += spp; - - if (txpos >= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti) - txpos -= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti; - } - - if (rxpos >= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti) - rxpos -= 10*PHY_vars_UE_g[0][0]->frame_parms.samples_per_tti; - - if (UE->is_synchronized == 1) { - LOG_D( HW, "UE_thread: hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - - if (start_rx_stream == 1) { - LOG_D(PHY,"Locking mutex_rx (IC %d)\n",UE->instance_cnt_rx); - if (pthread_mutex_lock(&UE->mutex_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - int instance_cnt_rx = ++UE->instance_cnt_rx; - - LOG_D(PHY,"Unlocking mutex_rx (IC %d)\n",instance_cnt_rx); - if (pthread_mutex_unlock(&UE->mutex_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, instance_cnt_rx); - - - if (instance_cnt_rx == 0) { - LOG_D(HW,"signalling rx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - if (pthread_cond_signal(&UE->proc.cond_rx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - LOG_D(HW,"signalled rx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); - if (UE->mode == loop_through_memory) { - printf("Processing subframe %d",UE->slot_rx>>1); - getchar(); - } - - if (UE->mode == rx_calib_ue) { - if (frame == 10) { - LOG_D(PHY, - "[SCHED][UE] Found cell with N_RB_DL %"PRIu8", PHICH CONFIG (%d,%d), Nid_cell %"PRIu16", NB_ANTENNAS_TX %"PRIu8", frequency offset "PRIi32" Hz, RSSI (digital) %hu dB, measured Gain %d dB, total_rx_gain %"PRIu32" dB, USRP rx gain %f dB\n", - UE->frame_parms.N_RB_DL, - UE->frame_parms.phich_config_common.phich_duration, - UE->frame_parms.phich_config_common.phich_resource, - UE->frame_parms.Nid_cell, - UE->frame_parms.nb_antennas_tx_eNB, - UE->common_vars.freq_offset, - UE->measurements.rx_power_avg_dB[0], - UE->measurements.rx_power_avg_dB[0] - rx_input_level_dBm, - UE->rx_total_gain_dB, - openair0_cfg[0].rx_gain[0] - ); - exit_fun("[HW][UE] UE in RX calibration mode, exiting"); - return &UE_thread_retval; + int sub_frame=-1; + int cumulated_shift=0; + while (!oai_exit) { + + if (UE->is_synchronized == 0) { + + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + int instance_cnt_synch = UE->proc.instance_cnt_synch; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + if (instance_cnt_synch < 0) { // we can invoke the synch + // grab 10 ms of signal and wakeup synch thread + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&rxdata[i][0]; + + if (UE->mode != loop_through_memory) + AssertFatal( UE->frame_parms.samples_per_tti*10 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx), ""); + instance_cnt_synch = ++UE->proc.instance_cnt_synch; + if (instance_cnt_synch == 0) { + AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); + } else { + LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); + exit_fun("nothing to add"); + } + } // + else { + // grab 10 ms of signal into dummy buffer + + if (UE->mode != loop_through_memory) { + for (int i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&dummy_rx[i][0]; + for (int sf=0; sf<10; sf++) { + // printf("Reading dummy sf %d\n",sf); + AssertFatal ( UE->frame_parms.samples_per_tti == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx), ""); + + } + } } - } - } else { - LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rx); - if (instance_cnt_rx > 2) { - exit_fun("instance_cnt_rx > 1"); - return &UE_thread_retval; - } - } - - if ((tx_enabled==1)&&(UE->mode != loop_through_memory)) { + } // UE->is_synchronized==0 + else { + if (start_rx_stream==0) { + start_rx_stream=1; + if (UE->mode != loop_through_memory) { + if (UE->no_timing_correction==0) { + LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); + AssertFatal(UE->rx_offset == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)rxdata, + UE->rx_offset, + UE->frame_parms.nb_antennas_rx),""); + } + UE->rx_offset=0; + UE->proc.proc_rxtx[0].frame_rx++; + UE->proc.proc_rxtx[1].frame_rx++; - if (pthread_mutex_lock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } + // read in first symbol + AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void**)rxdata, + UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx),""); + slot_fep(UE,0, 0, 0, 0, 0); + } //UE->mode != loop_through_memory + else + rt_sleep_ns(1000*1000); + } else { + sub_frame++; + sub_frame%=10; + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame&1]; - int instance_cnt_tx = ++UE->instance_cnt_tx; + if (UE->mode != loop_through_memory) { + for (i=0; iframe_parms.nb_antennas_rx; i++) + rxp[i] = (void*)&rxdata[i][UE->frame_parms.ofdm_symbol_size+ + UE->frame_parms.nb_prefix_samples0+ + sub_frame*UE->frame_parms.samples_per_tti]; + for (i=0; iframe_parms.nb_antennas_tx; i++) + txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti]; - if (pthread_mutex_unlock(&UE->mutex_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX, instance_cnt_tx); + int readBlockSize, writeBlockSize; + if (sub_frame<9) { + readBlockSize=UE->frame_parms.samples_per_tti; + writeBlockSize=UE->frame_parms.samples_per_tti; + } else { + int rx_off_diff; + if ( UE->rx_offset< 5*UE->frame_parms.samples_per_tti ) + rx_off_diff = -UE->rx_offset; + else // moving to the left so drop rx_off_diff samples + rx_off_diff = 10*UE->frame_parms.samples_per_tti - RX_OFF_MIN - UE->rx_offset; + cumulated_shift+=rx_off_diff; + if ( rx_off_diff > 10 ) + LOG_E (PHY,"HUGE shift %d, cumul %d\n", rx_off_diff, cumulated_shift); + static __thread int printed_cumul=0; + if ( abs(cumulated_shift/1000) > printed_cumul ) { + LOG_W(PHY,"Shifted for 1000 samples: cumul %d\n", cumulated_shift); + printed_cumul=abs(cumulated_shift/1000); + } + readBlockSize=UE->frame_parms.samples_per_tti- + UE->frame_parms.ofdm_symbol_size- + UE->frame_parms.nb_prefix_samples0; + writeBlockSize=UE->frame_parms.samples_per_tti - rx_off_diff; + } - if (instance_cnt_tx == 0) { - if (pthread_cond_signal(&UE->cond_tx) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE TX thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - LOG_D(HW,"signalled tx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 ); + AssertFatal(readBlockSize == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + readBlockSize, + UE->frame_parms.nb_antennas_rx),""); + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + (2*UE->frame_parms.samples_per_tti) - + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - + openair0_cfg[0].tx_sample_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1),""); + if( sub_frame==9) { + // read in first symbol of next frame and adjust for timing drift + int first_symbols=writeBlockSize-readBlockSize; + if ( first_symbols > 0 ) + AssertFatal(first_symbols == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp1, + (void**)rxdata, + first_symbols, + UE->frame_parms.nb_antennas_rx),""); + if ( first_symbols <0 ) + LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); + } + unsigned long long gotIQs=rdtsc(); + // operate on thread sf mod 2 + AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); + if(sub_frame == 0) { + UE->proc.proc_rxtx[0].frame_rx++; + UE->proc.proc_rxtx[1].frame_rx++; + } + UE->proc.proc_rxtx[0].gotIQs=gotIQs; + UE->proc.proc_rxtx[1].gotIQs=gotIQs; + proc->subframe_rx=sub_frame; + proc->subframe_tx=(sub_frame+4)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + proc->timestamp_tx = timestamp+ + (4*UE->frame_parms.samples_per_tti)- + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; - } else { - LOG_E( PHY, "[SCHED][UE] UE TX thread busy (IC %d)!!\n" ); - if (instance_cnt_tx>2) { - exit_fun("instance_cnt_tx > 1"); - return &UE_thread_retval; - } - } - } + AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + static __thread Meas t1= {0}; + static unsigned long long lastTime=0; + if ( lastTime != 0 ) + updateTimes(lastTime, &t1, 20000, "saif: Delay between two IQ acquisitions (case 1)"); + lastTime=rdtsc(); + saif_meas(proc->frame_rx); - } - } else { - // we are not yet synchronized - if ((hw_subframe == 9) && (dummy_dump == 0)) { - // Wake up initial synch thread - if (pthread_mutex_lock(&UE->mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } + } else { + printf("Processing subframe %d",proc->subframe_rx); + getchar(); + } + } // start_rx_stream==1 + } // UE->is_synchronized==1 - int instance_cnt_synch = ++UE->instance_cnt_synch; - - if (pthread_mutex_unlock(&UE->mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - - dummy_dump = 1; - - if (instance_cnt_synch == 0) { - if (pthread_cond_signal(&UE->cond_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - return &UE_thread_retval; - } - } - } - - hw_subframe++; - slot+=2; - - if (hw_subframe==10) { - hw_subframe = 0; - first_rx = 1; - frame++; - slot = 1; - - int fail = pthread_mutex_lock(&UE->mutex_synch); - int instance_cnt_synch = UE->instance_cnt_synch; - fail = fail || pthread_mutex_unlock(&UE->mutex_synch); - - if (fail) { - LOG_E( PHY, "[SCHED][UE] error (un-)locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_retval; - } - - if (instance_cnt_synch < 0) { - // the UE_thread_synch is ready - if (UE->is_synchronized == 1) { - rx_off_diff = 0; - LTE_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; // for macro FRAME_LENGTH_COMPLEX_SAMPLES - - // LOG_I(PHY,"UE->rx_offset %d\n",UE->rx_offset); - if ((UE->rx_offset > RX_OFF_MAX) && (start_rx_stream == 0)) { - start_rx_stream=1; - frame=0; - // dump ahead in time to start of frame - -#ifndef USRP_DEBUG - if (UE->mode != loop_through_memory) { - LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset); - rxs = UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx); - if (rxs != UE->rx_offset) { - exit_fun("problem in rx"); - return &UE_thread_retval; - } - UE->rx_offset=0; - tx_enabled = 1; - } - else - rt_sleep_ns(1000000); -#else - rt_sleep_ns(10000000); -#endif - - } else if ((UE->rx_offset<(FRAME_LENGTH_COMPLEX_SAMPLES/2)) && - (UE->rx_offset > RX_OFF_MIN) && - (start_rx_stream==1) && - (rx_correction_timer == 0)) { - rx_off_diff = -UE->rx_offset + RX_OFF_MIN; - LOG_D(PHY,"UE->rx_offset %d > %d, diff %d\n",UE->rx_offset,RX_OFF_MIN,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(FRAME_LENGTH_COMPLEX_SAMPLES/2)) && - (UE->rx_offset < (FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MIN)) && - (start_rx_stream==1) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = FRAME_LENGTH_COMPLEX_SAMPLES - RX_OFF_MIN - UE->rx_offset; - LOG_D(PHY,"UE->rx_offset %d < %d, diff %d\n",UE->rx_offset,FRAME_LENGTH_COMPLEX_SAMPLES-RX_OFF_MIN,rx_off_diff); - - rx_correction_timer = 5; - } - - if (rx_correction_timer>0) - rx_correction_timer--; - } - - dummy_dump=0; - } - } - -#if defined(ENABLE_ITTI) - itti_update_lte_time(frame, slot); -#endif - } - - return &UE_thread_retval; + } // while !oai_exit + return NULL; } -*/ - /*! * \brief Initialize the UE theads. * Creates the UE threads: @@ -1636,124 +1046,97 @@ void *UE_thread_old(void *arg) * - UE_thread_synch * and the locking between them. */ -void init_UE_threads(int inst) -{ - PHY_VARS_UE *UE; - - UE = PHY_vars_UE_g[inst][0]; +void init_UE_threads(int inst) { + PHY_VARS_UE *UE; - pthread_attr_init (&UE->proc.attr_ue); - pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - -#ifndef LOWLATENCY - UE->proc.sched_param_ue.sched_priority = sched_get_priority_max(SCHED_FIFO); - pthread_attr_setschedparam(&UE->proc.attr_ue,&sched_param_UE_thread); -#endif + UE = PHY_vars_UE_g[inst][0]; + + pthread_attr_init (&UE->proc.attr_ue); + pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); + + + // the threads are not yet active, therefore access is allowed without locking + int nb_threads=2; + for (int i=0; iproc.proc_rxtx[i].mutex_rxtx,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].sub_frame_start=i; + UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[i]); + } + pthread_mutex_init(&UE->proc.mutex_synch,NULL); + pthread_cond_init(&UE->proc.cond_synch,NULL); + pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - // the threads are not yet active, therefore access is allowed without locking - UE->proc.proc_rxtx[0].instance_cnt_rxtx = -1; - UE->proc.proc_rxtx[1].instance_cnt_rxtx = -1; - UE->proc.instance_cnt_synch = -1; - pthread_mutex_init(&UE->proc.proc_rxtx[0].mutex_rxtx,NULL); - pthread_mutex_init(&UE->proc.proc_rxtx[1].mutex_rxtx,NULL); - pthread_mutex_init(&UE->proc.mutex_synch,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[0].cond_rxtx,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[1].cond_rxtx,NULL); - pthread_cond_init(&UE->proc.cond_synch,NULL); - pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[0]); - pthread_setname_np( UE->proc.proc_rxtx[0].pthread_rxtx, "UE_thread_rxn_txnp4_even" ); - pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[1]); - pthread_setname_np( UE->proc.proc_rxtx[1].pthread_rxtx, "UE_thread_rxn_txnp4_odd" ); - pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - pthread_setname_np( UE->proc.pthread_synch, "UE_thread_synch" ); } #ifdef OPENAIR2 -void fill_ue_band_info(void) -{ +void fill_ue_band_info(void) { - UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; - int i,j; + UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; + int i,j; - bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; + bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; - for (i=0; irf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { - memcpy(&bands_to_scan.band_info[i], - &eutra_bands[j], - sizeof(eutra_band_t)); + for (j=0; jrf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { + memcpy(&bands_to_scan.band_info[i], + &eutra_bands[j], + sizeof(eutra_band_t)); - printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", - bands_to_scan.band_info[i].band, - UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, - bands_to_scan.band_info[i].dl_min, - bands_to_scan.band_info[i].dl_max, - bands_to_scan.band_info[i].ul_min, - bands_to_scan.band_info[i].ul_max, - (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); - break; - } - } + printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", + bands_to_scan.band_info[i].band, + UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, + bands_to_scan.band_info[i].dl_min, + bands_to_scan.band_info[i].dl_max, + bands_to_scan.band_info[i].ul_min, + bands_to_scan.band_info[i].ul_max, + (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); + break; + } + } } #endif -int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) -{ +int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) { - int i, CC_id; - LTE_DL_FRAME_PARMS *frame_parms; - openair0_rf_map *rf_map; + int i, CC_id; + LTE_DL_FRAME_PARMS *frame_parms; + openair0_rf_map *rf_map; - for (CC_id=0; CC_idrf_map; - - if (phy_vars_ue[CC_id]) { - frame_parms = &(phy_vars_ue[CC_id]->frame_parms); - } else { - printf("phy_vars_UE[%d] not initialized\n", CC_id); - return(-1); - } - - /* - if (frame_parms->frame_type == TDD) { - if (frame_parms->N_RB_DL == 100) - N_TA_offset = 624; - else if (frame_parms->N_RB_DL == 50) - N_TA_offset = 624/2; - else if (frame_parms->N_RB_DL == 25) - N_TA_offset = 624/4; - } - */ - - // replace RX signal buffers with mmaped HW versions - rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); - txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); - - for (i=0; inb_antennas_rx; i++) { - printf( "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); - rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD - printf("rxdata[%d] : %p\n",i,rxdata[i]); - } - - for (i=0; inb_antennas_tx; i++) { - printf( "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); - free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); - txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); - phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; - printf("txdata[%d] : %p\n",i,txdata[i]); - } - - // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] - // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] - // be careful when releasing memory! - // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) - - } + for (CC_id=0; CC_idrf_map; - return 0; + AssertFatal( phy_vars_ue[CC_id] !=0, ""); + frame_parms = &(phy_vars_ue[CC_id]->frame_parms); + + // replace RX signal buffers with mmaped HW versions + rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); + txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); + + for (i=0; inb_antennas_rx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); + rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD + } + + for (i=0; inb_antennas_tx; i++) { + LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", + CC_id, i, downlink_frequency[CC_id][i], rf_map->card, rf_map->chain+i ); + free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); + txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; + } + + // rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x] + // txdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.txdata[x] + // be careful when releasing memory! + // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) + } + return 0; } From 3b44919d0b03f8f0a1033ac2d4b89f51c1718a63 Mon Sep 17 00:00:00 2001 From: laurent Date: Tue, 27 Dec 2016 15:48:56 +0100 Subject: [PATCH 127/571] better performance measurements --- openair2/UTIL/LOG/log.h | 433 +++++++++++++++++++++---------------- openair2/UTIL/LOG/log_if.h | 59 +---- targets/RT/USER/lte-ue.c | 120 +--------- 3 files changed, 257 insertions(+), 355 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 171f74da41..b15f7064ac 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -53,26 +53,6 @@ extern "C" { #endif - extern double cpuf; - static inline unsigned long long rdtsc(void) { - unsigned long long a, d; - __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); - return (d<<32) | a; - } - static inline unsigned long long checkT(int timeout, char * file, int line) { - static unsigned long long __thread last=0; - unsigned long long cur=rdtsc(); - int microCycles=(int)(cpuf*1000); - int duration=(int)((cur-last)/microCycles); - if ( last!=0 && duration > timeout ) - printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, - duration, timeout); - last=cur; - return cur; - } - -#define check(a) checkT(a,__FILE__,__LINE__) - /** @defgroup _LOG LOG Generator * @{*/ /* @}*/ @@ -96,41 +76,197 @@ extern "C" { * @ingroup _macro * @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8 * @{*/ -#ifndef LOG_EMERG # define LOG_EMERG 0 /*!< \brief system is unusable */ -#endif -#ifndef LOG_ALERT # define LOG_ALERT 1 /*!< \brief action must be taken immediately */ -#endif -#ifndef LOG_CRIT # define LOG_CRIT 2 /*!< \brief critical conditions */ -#endif -#ifndef LOG_ERR # define LOG_ERR 3 /*!< \brief error conditions */ -#endif -#ifndef LOG_WARNING # define LOG_WARNING 4 /*!< \brief warning conditions */ -#endif -#ifndef LOG_NOTICE # define LOG_NOTICE 5 /*!< \brief normal but significant condition */ -#endif -#ifndef LOG_INFO # define LOG_INFO 6 /*!< \brief informational */ -#endif -#ifndef LOG_DEBUG # define LOG_DEBUG 7 /*!< \brief debug-level messages */ -#endif -#ifndef LOG_FILE # define LOG_FILE 8 /*!< \brief message sequence chart -level */ -#endif -#ifndef LOG_TRACE # define LOG_TRACE 9 /*!< \brief trace-level messages */ -#endif - #define NUM_LOG_LEVEL 10 /*!< \brief the number of message levels users have with LOG */ /* @}*/ +/** @defgroup _log_format Defined log format + * @ingroup _macro + * @brief Macro of log formats defined by LOG + * @{*/ + +/* .log_format = 0x13 uncolored standard messages + * .log_format = 0x93 colored standard messages */ + +#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */ +#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */ +#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */ +#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */ +#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */ +#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */ +/* @}*/ + + +/** @defgroup _syslog_conf Macros for write in syslog.conf + * @ingroup _macro + * @brief Macros used to write lines (local/remote) in syslog.conf + * @{*/ +#define LOG_LOCAL 0x01 +#define LOG_REMOTE 0x02 + +#define FLAG_COLOR 0x001 /*!< \brief defaults */ +#define FLAG_PID 0x002 /*!< \brief defaults */ +#define FLAG_COMP 0x004 +#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */ +#define FLAG_LEVEL 0x010 +#define FLAG_FUNCT 0x020 +#define FLAG_FILE_LINE 0x040 +#define FLAG_TIME 0x100 + +#define LOG_NONE 0x00 +#define LOG_LOW 0x5 +#define LOG_MED 0x15 +#define LOG_HIGH 0x35 +#define LOG_FULL 0x75 + +#define OAI_OK 0 /*!< \brief all ok */ +#define OAI_ERR 1 /*!< \brief generic error */ +#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */ +#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */ +/* @}*/ + + +//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */ + +//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ + +typedef enum { + MIN_LOG_COMPONENTS = 0, + PHY = MIN_LOG_COMPONENTS, + MAC, + EMU, + OCG, + OMG, + OPT, + OTG, + OTG_LATENCY, + OTG_LATENCY_BG, + OTG_GP, + OTG_GP_BG, + OTG_JITTER, + RLC, + PDCP, + RRC, + NAS, + PERF, + OIP, + CLI, + MSC, + OCM, + UDP_, + GTPU, + SPGW, + S1AP, + SCTP, + HW, + OSA, + RAL_ENB, + RAL_UE, + ENB_APP, + FLEXRAN_AGENT, + TMR, + USIM, + LOCALIZE, + RRH, + X2AP, + MAX_LOG_COMPONENTS, +} +comp_name_t; + +//#define msg printf + +typedef struct { + char *name; /*!< \brief string name of item */ + int value; /*!< \brief integer value of mapping */ +} mapping; + + +typedef struct { + const char *name; + int level; + int flag; + int interval; + int fd; + int filelog; + char *filelog_name; + + /* SR: make the log buffer component relative */ + char log_buffer[MAX_LOG_TOTAL]; +} log_component_t; + +typedef struct { + unsigned int remote_ip; + unsigned int audit_ip; + int remote_level; + int facility; + int audit_facility; + int format; +} log_config_t; + + +typedef struct { + log_component_t log_component[MAX_LOG_COMPONENTS]; + log_config_t config; + char* level2string[NUM_LOG_LEVEL]; + int level; + int onlinelog; + int flag; + int syslog; + int filelog; + char* filelog_name; +} log_t; + +typedef struct LOG_params { + const char *file; + const char *func; + int line; + int comp; + int level; + const char *format; + char l_buff_info [MAX_LOG_INFO]; + int len; +} LOG_params; + +#if defined(ENABLE_ITTI) +typedef enum log_instance_type_e { + LOG_INSTANCE_UNKNOWN, + LOG_INSTANCE_ENB, + LOG_INSTANCE_UE, +} log_instance_type_t; + +void log_set_instance_type (log_instance_type_t instance); +#endif + + +/*--- INCLUDES ---------------------------------------------------------------*/ +# include "log_if.h" +/*----------------------------------------------------------------------------*/ +int logInit (void); +void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...); +void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...); +int set_comp_log(int component, int level, int verbosity, int interval); +int set_log(int component, int level, int interval); +void set_glog(int level, int verbosity); +void set_log_syslog(int enable); +void set_log_onlinelog(int enable); +void set_log_filelog(int enable); +void set_component_filelog(int comp); +int map_str_to_int(mapping *map, const char *str); +char *map_int_to_str(mapping *map, int val); +void logClean (void); +int is_newline( char *str, int size); +void *log_thread_function(void * list); + /** @defgroup _logIt logIt function * @ingroup _macro * @brief Macro used to call tr_log_full_ex with file, function and line information @@ -206,169 +342,82 @@ extern "C" { #define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */ /* @}*/ - -/** @defgroup _log_format Defined log format - * @ingroup _macro - * @brief Macro of log formats defined by LOG - * @{*/ - -/* .log_format = 0x13 uncolored standard messages - * .log_format = 0x93 colored standard messages */ - -#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */ -#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */ -#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */ -#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */ -#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */ -#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */ -/* @}*/ - - -/** @defgroup _syslog_conf Macros for write in syslog.conf - * @ingroup _macro - * @brief Macros used to write lines (local/remote) in syslog.conf - * @{*/ -#define LOG_LOCAL 0x01 -#define LOG_REMOTE 0x02 - -#define FLAG_COLOR 0x001 /*!< \brief defaults */ -#define FLAG_PID 0x002 /*!< \brief defaults */ -#define FLAG_COMP 0x004 -#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */ -#define FLAG_LEVEL 0x010 -#define FLAG_FUNCT 0x020 -#define FLAG_FILE_LINE 0x040 -#define FLAG_TIME 0x100 - -#define LOG_NONE 0x00 -#define LOG_LOW 0x5 -#define LOG_MED 0x15 -#define LOG_HIGH 0x35 -#define LOG_FULL 0x75 - -#define OAI_OK 0 /*!< \brief all ok */ -#define OAI_ERR 1 /*!< \brief generic error */ -#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */ -#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */ -/* @}*/ - - -//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */ - -//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ - -typedef enum { - MIN_LOG_COMPONENTS = 0, - PHY = MIN_LOG_COMPONENTS, - MAC, - EMU, - OCG, - OMG, - OPT, - OTG, - OTG_LATENCY, - OTG_LATENCY_BG, - OTG_GP, - OTG_GP_BG, - OTG_JITTER, - RLC, - PDCP, - RRC, - NAS, - PERF, - OIP, - CLI, - MSC, - OCM, - UDP_, - GTPU, - SPGW, - S1AP, - SCTP, - HW, - OSA, - RAL_ENB, - RAL_UE, - ENB_APP, - FLEXRAN_AGENT, - TMR, - USIM, - LOCALIZE, - RRH, - X2AP, - MAX_LOG_COMPONENTS, +static inline unsigned long long rdtsc(void) { + unsigned long long a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; } -comp_name_t; -//#define msg printf +#define DEBUG_REALTIME 1 +#if DEBUG_REALTIME -typedef struct { - char *name; /*!< \brief string name of item */ - int value; /*!< \brief integer value of mapping */ -} mapping; +extern double cpuf; +static inline unsigned long long checkT(int timeout, char * file, int line) { + static unsigned long long __thread last=0; + unsigned long long cur=rdtsc(); + int microCycles=(int)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) + printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, + duration, timeout); + last=cur; + return cur; +} -typedef struct { - const char *name; - int level; - int flag; - int interval; - int fd; - int filelog; - char *filelog_name; +typedef struct m { + unsigned long long iterations; + unsigned long long sum; + unsigned long long maxArray[11]; +} Meas; - /* SR: make the log buffer component relative */ - char log_buffer[MAX_LOG_TOTAL]; -} log_component_t; +static inline void printMeas(char * txt, Meas *M, int period) { + if (M->iterations%period == 0 ) { + char txt2[512]; + sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", + txt, M->sum/M->iterations,M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], + M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); + LOG_W(PHY,txt2); + } +} -typedef struct { - unsigned int remote_ip; - unsigned int audit_ip; - int remote_level; - int facility; - int audit_facility; - int format; -} log_config_t; +static inline int cmpint(const void* a, const void* b) { + unsigned long long* aa=(unsigned long long*)a; + unsigned long long* bb=(unsigned long long*)b; + return (int)(*aa-*bb); +} +static inline void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { + if (start!=0) { + unsigned long long end=rdtsc(); + long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); + printMeas(txt,M,period); + } +} -typedef struct { - log_component_t log_component[MAX_LOG_COMPONENTS]; - log_config_t config; - char* level2string[NUM_LOG_LEVEL]; - int level; - int onlinelog; - int flag; - int syslog; - int filelog; - char* filelog_name; -} log_t; +#define check(a) checkT(a,__FILE__,__LINE__) +#define initRefTimes(a) static __thread Meas a= {0} +#define pickTime(a) unsigned long long a=rdtsc() +#define readTime(a) a +#define initStaticTime(a) static __thread unsigned long long a={0} +#define pickStaticTime(a) a=rdtsc() -typedef struct LOG_params { - const char *file; - const char *func; - int line; - int comp; - int level; - const char *format; - char l_buff_info [MAX_LOG_INFO]; - int len; -} LOG_params; - - -#if defined(ENABLE_ITTI) -typedef enum log_instance_type_e { - LOG_INSTANCE_UNKNOWN, - LOG_INSTANCE_ENB, - LOG_INSTANCE_UE, -} log_instance_type_t; - -void log_set_instance_type (log_instance_type_t instance); +#else +#define check(a) do {} while (0) +#define initRefTimes(a) do {} while (0) +#define initStaticTime(a) do {} while (0) +#define pickTime(a) do {} while (0) +#define readTime(a) 0 +#define pickStaticTime(a) do {} while (0) +#define updateTimes(a,b,c,d) do {} while (0) +#define printMeas(a,b,c) do {} while (0) #endif -int logInit (void); -/*--- INCLUDES ---------------------------------------------------------------*/ -# include "log_if.h" -/*----------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif diff --git a/openair2/UTIL/LOG/log_if.h b/openair2/UTIL/LOG/log_if.h index 1b447a7f60..6338fab829 100644 --- a/openair2/UTIL/LOG/log_if.h +++ b/openair2/UTIL/LOG/log_if.h @@ -27,59 +27,8 @@ * \warning This component can be runned only in user-space * @ingroup routing */ -#ifndef __LOG_IF_H__ -# define __LOG_IF_H__ - - -/*--- INCLUDES ---------------------------------------------------------------*/ -# include "log.h" -/*----------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef COMPONENT_LOG -# ifdef COMPONENT_LOG_IF -# define private_log_if(x) x -# define friend_log_if(x) x -# define public_log_if(x) x -# else -# define private_log_if(x) -# define friend_log_if(x) extern x -# define public_log_if(x) extern x -# endif -# else -# define private_log_if(x) -# define friend_log_if(x) -# define public_log_if(x) extern x -# endif - -/** @defgroup _log_if Interfaces of LOG - * @{*/ - -//public_log_if( log_t *g_log;) - -public_log_if( int logInit (void);) -public_log_if( void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...);) -public_log_if( void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...);) -public_log_if( int set_comp_log(int component, int level, int verbosity, int interval);) -public_log_if( int set_log(int component, int level, int interval);) -public_log_if( void set_glog(int level, int verbosity);) -public_log_if( void set_log_syslog(int enable);) -public_log_if( void set_log_onlinelog(int enable);) -public_log_if( void set_log_filelog(int enable);) -public_log_if( void set_component_filelog(int comp);) -public_log_if( int map_str_to_int(mapping *map, const char *str);) -public_log_if( char *map_int_to_str(mapping *map, int val);) -public_log_if( void logClean (void); ) -public_log_if( int is_newline( char *str, int size);) -public_log_if( void *log_thread_function(void * list);) - -/* @}*/ - -#ifdef __cplusplus -} -#endif - -#endif +// LTS: kept this file for compatibility +// this file was probably a trial to separate internal functions and external ones +// but it has never been finished, most source code include directly log.h (not log_if.h) +#include "log.h" diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 6e588f7f3c..b398d5127e 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -75,101 +75,6 @@ #include "UTIL/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" - -#define DEBUG_REALTIME 1 -#if DEBUG_REALTIME - -typedef struct latency_stat { - uint64_t counter; - uint64_t stat1100; - uint64_t stat1200; - uint64_t stat1500; - uint64_t stat2000; - uint64_t stat3000; -} latency_stat_t; - -static inline void saif_meas(int frame_rx) { - static latency_stat_t __thread latency_stat; - static struct timespec __thread last= {0}; - struct timespec now; - clock_gettime(CLOCK_MONOTONIC_RAW, &now); - if ( last.tv_sec ) { - uint64_t diffTime = ((uint64_t)now.tv_sec *1000 *1000 *1000 + now.tv_nsec) - - ((uint64_t)last.tv_sec *1000 *1000 *1000 + last.tv_nsec); - diffTime/=1000; - latency_stat.counter++; - if ( diffTime >= 1100 ) { - if (diffTime < 1200 ) - latency_stat.stat1100++; - else if ( diffTime < 1500 ) - latency_stat.stat1200++; - else if ( diffTime < 2000 ) - latency_stat.stat1500++; - else if ( diffTime < 3000 ) - latency_stat.stat2000++; - else - latency_stat.stat3000++; - } - if ( diffTime>=1100 || latency_stat.counter%20000==0 ) { - time_t current=time(NULL); - LOG_W(HW, - "%.2f delay=%llu Period stats %2.6f%% below 100µs\ncumul of events: 1100=%ld 1200=%ld 1500=%ld 2000=%ld >3000=%ld - (frame_rx=%d) - %s", - now.tv_sec+(double)now.tv_nsec/1e9, - diffTime, - (latency_stat.counter-latency_stat.stat1100-latency_stat.stat1200- - latency_stat.stat1500-latency_stat.stat2000-latency_stat.stat3000)/ - (float)latency_stat.counter *100, - latency_stat.stat1100, latency_stat.stat1200, - latency_stat.stat1500, latency_stat.stat2000, - latency_stat.stat3000, - frame_rx, ctime(¤t)); - fflush(stdout); - } - - } - last=now; -} - -typedef struct m { - unsigned long long iterations; - unsigned long long sum; - unsigned long long maxArray[11]; -} Meas; - - -void printMeas(char * txt, Meas *M, int period) { - if (M->iterations%period == 0 ) { - char txt2[512]; - sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", - txt, M->sum/M->iterations,M->iterations, - M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], - M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); - LOG_W(PHY,txt2); - } -} - -int cmpint(const void* a, const void* b) { - unsigned long long* aa=(unsigned long long*)a; - unsigned long long* bb=(unsigned long long*)b; - return (int)(*aa-*bb); -} - -void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { - unsigned long long end=rdtsc(); - long long diff=(end-start)/(cpuf*1000); - M->maxArray[0]=diff; - M->sum+=diff; - M->iterations++; - qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); - printMeas(txt,M,period); -} - -#else -#define check(a) do {} while (0) -#define saif_meas(a) do {} while (0) -#define update_max_times(a,b) do {} while (0) -#define print_meas(a,b) do {} while (0) -#endif /* End of Changed by SYRTEM */ #define FRAME_PERIOD 100000000ULL @@ -742,9 +647,10 @@ static void *UE_thread_rxn_txnp4(void *arg) { instance_cnt_rxtx=proc->subframe_rx; AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); - static __thread Meas t2= {0}, t3= {0}; - unsigned long long current=rdtsc(); - updateTimes(proc->gotIQs, &t2, 10000, "saif: Delay to wake up UE_Thread_Rx (case 2)"); + initRefTimes(t2); + initRefTimes(t3); + pickTime(current); + updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); @@ -812,7 +718,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { (UE->frame_parms.frame_type == TDD)) if (UE->mode != loop_through_memory) phy_procedures_UE_S_TX(UE,0,0,no_relay); - updateTimes(current, &t3, 10000, "saif: Delay to process sub-frame (case 3)"); + updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); } @@ -1002,15 +908,15 @@ void *UE_thread(void *arg) { if ( first_symbols <0 ) LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); } - unsigned long long gotIQs=rdtsc(); + pickTime(gotIQs); // operate on thread sf mod 2 AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); if(sub_frame == 0) { UE->proc.proc_rxtx[0].frame_rx++; UE->proc.proc_rxtx[1].frame_rx++; } - UE->proc.proc_rxtx[0].gotIQs=gotIQs; - UE->proc.proc_rxtx[1].gotIQs=gotIQs; + UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); + UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); proc->subframe_rx=sub_frame; proc->subframe_tx=(sub_frame+4)%10; proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); @@ -1020,12 +926,10 @@ void *UE_thread(void *arg) { AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); - static __thread Meas t1= {0}; - static unsigned long long lastTime=0; - if ( lastTime != 0 ) - updateTimes(lastTime, &t1, 20000, "saif: Delay between two IQ acquisitions (case 1)"); - lastTime=rdtsc(); - saif_meas(proc->frame_rx); + initRefTimes(t1); + initStaticTime(lastTime); + updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); + pickStaticTime(lastTime); } else { printf("Processing subframe %d",proc->subframe_rx); From 2612df9ef24a1cc5240f9d3aa08d85b2736bd69a Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 29 Dec 2016 10:09:13 +0100 Subject: [PATCH 128/571] after tests --- openair2/UTIL/LOG/log.h | 68 +++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index b15f7064ac..9a7dac4de5 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -43,6 +43,9 @@ #include #include #include +#include +#include +#include #else #include "rtai_fifos.h" #endif @@ -342,10 +345,10 @@ void *log_thread_function(void * list); #define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */ /* @}*/ -static inline unsigned long long rdtsc(void) { - unsigned long long a, d; - __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); - return (d<<32) | a; +static __inline__ uint64_t rdtsc(void) { + uint64_t a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; } #define DEBUG_REALTIME 1 @@ -353,6 +356,26 @@ static inline unsigned long long rdtsc(void) { extern double cpuf; +static inline uint64_t checkTCPU(int timeout, char * file, int line) { + static uint64_t __thread lastCPUTime=0; + static uint64_t __thread last=0; + uint64_t cur=rdtsc(); + struct timespec CPUt; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt); + uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000; + double microCycles=(double)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + if ( last!=0 && duration > timeout ) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%.3f %s:%d lte-ue delay %d (exceed %d), CPU for this period: %.2f\n", ts.tv_sec+ts.tv_nsec/(1000*1000*1000.0), file, line, + duration, timeout, (CPUTime-lastCPUTime)/1000.0 ); + } + last=cur; + lastCPUTime=CPUTime; + return cur; +} + static inline unsigned long long checkT(int timeout, char * file, int line) { static unsigned long long __thread last=0; unsigned long long cur=rdtsc(); @@ -366,49 +389,54 @@ static inline unsigned long long checkT(int timeout, char * file, int line) { } typedef struct m { - unsigned long long iterations; - unsigned long long sum; - unsigned long long maxArray[11]; + uint64_t iterations; + uint64_t sum; + uint64_t maxArray[11]; } Meas; static inline void printMeas(char * txt, Meas *M, int period) { if (M->iterations%period == 0 ) { char txt2[512]; - sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n", - txt, M->sum/M->iterations,M->iterations, - M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], - M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); + sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%" + PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", + txt, + M->sum/M->iterations, + M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], + M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); LOG_W(PHY,txt2); } } static inline int cmpint(const void* a, const void* b) { - unsigned long long* aa=(unsigned long long*)a; - unsigned long long* bb=(unsigned long long*)b; + uint64_t* aa=(uint64_t*)a; + uint64_t* bb=(uint64_t*)b; return (int)(*aa-*bb); } -static inline void updateTimes(unsigned long long start, Meas *M, int period, char * txt) { +static inline void updateTimes(uint64_t start, Meas *M, int period, char * txt) { if (start!=0) { - unsigned long long end=rdtsc(); + uint64_t end=rdtsc(); long long diff=(end-start)/(cpuf*1000); M->maxArray[0]=diff; M->sum+=diff; M->iterations++; - qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint); + qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); printMeas(txt,M,period); } } -#define check(a) checkT(a,__FILE__,__LINE__) +#define check(a) do { checkT(a,__FILE__,__LINE__); } while (0) +#define checkcpu(a) do { checkTCPU(a,__FILE__,__LINE__); } while (0) #define initRefTimes(a) static __thread Meas a= {0} -#define pickTime(a) unsigned long long a=rdtsc() +#define pickTime(a) uint64_t a=rdtsc() #define readTime(a) a -#define initStaticTime(a) static __thread unsigned long long a={0} -#define pickStaticTime(a) a=rdtsc() +#define initStaticTime(a) static __thread uint64_t a={0} +#define pickStaticTime(a) do { a=rdtsc(); } while (0) #else #define check(a) do {} while (0) +#define checkcpu(a) do {} while (0) #define initRefTimes(a) do {} while (0) #define initStaticTime(a) do {} while (0) #define pickTime(a) do {} while (0) From 59d0cf1c5477bb6cc5d2b2d9094e52e60b3bc8d9 Mon Sep 17 00:00:00 2001 From: LTS Date: Tue, 3 Jan 2017 14:26:17 +0100 Subject: [PATCH 129/571] fix T macro calls --- common/utils/T/T.h | 12 ------------ targets/RT/USER/lte-ue.c | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 819615131e..bd090ac221 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -188,12 +188,6 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ - if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ - printf("%s:%d:%s: " \ - "bad use of T, pass a message ID as first parameter\n", \ - __FILE__, __LINE__, __FUNCTION__); \ - abort(); \ - } \ struct timespec T_HEADER_time; \ if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \ memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \ @@ -205,12 +199,6 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ - if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ - printf("%s:%d:%s: " \ - "bad use of T, pass a message ID as first parameter\n", \ - __FILE__, __LINE__, __FUNCTION__); \ - abort(); \ - } \ T_PUT_int(1, (int)(uintptr_t)(x)); \ } while (0) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index b398d5127e..cfd4296755 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -642,7 +642,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); if ( (instance_cnt_rxtx+proc->sub_frame_step)%10 != proc->subframe_rx && instance_cnt_rxtx!=-1 ) - LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %d, got %d\n", + LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %lld, got %d\n", (instance_cnt_rxtx+proc->sub_frame_step)%10, proc->subframe_rx); instance_cnt_rxtx=proc->subframe_rx; AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); From d31634c358f35548f14daf1645268a741d21b371 Mon Sep 17 00:00:00 2001 From: laurent Date: Sat, 7 Jan 2017 08:23:50 +0100 Subject: [PATCH 130/571] fix nettle --- cmake_targets/CMakeLists.txt | 12 ------------ openair2/UTIL/OSA/osa_stream_eea.c | 3 ++- openair3/SECU/nas_stream_eea2.c | 3 ++- openair3/TEST/test_aes128_ctr_decrypt.c | 3 ++- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 81ddf37503..4f40486801 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1669,18 +1669,6 @@ endif() message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - pkg_search_module(XPM xpm) if(NOT ${XPM_FOUND}) message("PACKAGE xpm not found: some targets will fail") diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c index 6aef6d2588..9e8a3a88b3 100644 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ b/openair2/UTIL/OSA/osa_stream_eea.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "UTIL/LOG/log.h" @@ -191,7 +192,7 @@ int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) } #endif -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index 37f2e298fb..e9f2e7c41a 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "assertions.h" #include "conversions.h" @@ -78,7 +79,7 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) } #endif -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/TEST/test_aes128_ctr_decrypt.c b/openair3/TEST/test_aes128_ctr_decrypt.c index a30dc6c2f2..98987a8d97 100644 --- a/openair3/TEST/test_aes128_ctr_decrypt.c +++ b/openair3/TEST/test_aes128_ctr_decrypt.c @@ -31,6 +31,7 @@ #include #include #include +#include static void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, @@ -41,7 +42,7 @@ void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, uint8_t *data = malloc(length); uint8_t *ctr = malloc(cipher->block_size); -#if NETTLE_VERSION_MAJOR < 3 +#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 cipher->set_encrypt_key(ctx, key_length, key); #else cipher->set_encrypt_key(ctx, key); From b77694e89c78497343631b64902614528c3adba9 Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 19 Jan 2017 11:40:03 +0100 Subject: [PATCH 131/571] main AM RX process PDU changes --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h | 36 ++++- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h | 3 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c | 7 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c | 136 +++++++++++++----- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 4 + .../RLC/AM_v9.3.0/rlc_am_status_report.c | 2 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h | 22 +++ openair2/LAYER2/RLC/rlc_def.h | 1 + 8 files changed, 165 insertions(+), 46 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h index dcc5f2de8f..b63c7e3132 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h @@ -51,7 +51,7 @@ # define RLC_AM_SDU_CONTROL_BUFFER_SIZE 128 /** Size of the retransmission buffer (number of PDUs). */ -# define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_SN_MODULO +# define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_WINDOW_SIZE /** PDU minimal header size in bytes. */ # define RLC_AM_HEADER_MIN_SIZE 2 @@ -69,6 +69,36 @@ # define RLC_AM_MAX_NACK_IN_STATUS_PDU 1023 /** Max holes created by NACK_SN with segment offsets for a PDU in the retransmission buffer. */ -# define RLC_AM_MAX_HOLES_REPORT_PER_PDU 32 +# define RLC_AM_MAX_HOLES_REPORT_PER_PDU 16 /** @} */ -# endif + + +/* MACRO DEFINITIONS */ +#define RLC_AM_NEXT_SN(sn) (((sn)+1) & ((RLC_AM_SN_MODULO)-1)) +#define RLC_AM_PREV_SN(sn) (((sn)+(RLC_AM_SN_MODULO)-1) & ((RLC_AM_SN_MODULO)-1)) + +#define RLC_DIFF_SN(sn,snref,modulus) ((sn+(modulus)-snref) & ((modulus)-1)) +#define RLC_SN_IN_WINDOW(sn,snref,modulus) ((RLC_DIFF_SN(sn,snref,modulus)) < ((modulus) >> 1)) + +#define RLC_AM_DIFF_SN(sn,snref) (RLC_DIFF_SN(sn,snref,RLC_AM_SN_MODULO)) +#define RLC_AM_SN_IN_WINDOW(sn,snref) (RLC_SN_IN_WINDOW(sn,snref,RLC_AM_SN_MODULO)) + +#define RLC_SET_EVENT(x,event) ((x) |= (event)) +#define RLC_GET_EVENT(x,event) ((x) & (event)) +#define RLC_CLEAR_EVENT(x,event) ((x) &= (~(event))) + +/* Uplink STATUS PDU trigger events */ +#define RLC_AM_STATUS_NOT_TRIGGERED 0 +#define RLC_AM_STATUS_TRIGGERED_POLL 0x01 /* Status Report is triggered by a received poll */ +#define RLC_AM_STATUS_TRIGGERED_T_REORDERING 0x02 /* Status Report is triggered by Timer Reordering Expiry */ +#define RLC_AM_STATUS_TRIGGERED_DELAYED 0x10 /* Status is delayed until SN(receivedPoll) < VR(MS) */ +#define RLC_AM_STATUS_PROHIBIT 0x20 /* TimerStatusProhibit still running */ + +/* Status triggered (bit 5-7) will be concatenated with Poll triggered (bit 0-4) for RLCdec. RLC_AM_STATUS_TRIGGERED_DELAYED is not recorded. */ +#define RLC_AM_SET_STATUS(x,event) (RLC_SET_EVENT(x,event)) +#define RLC_AM_GET_STATUS(x,event) (RLC_GET_EVENT(x,event)) +#define RLC_AM_CLEAR_STATUS(x,event) (RLC_CLEAR_EVENT(x,event)) +#define RLC_AM_CLEAR_ALL_STATUS(x) ((x) = (RLC_AM_STATUS_NOT_TRIGGERED)) + + +#endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h index 42114d4269..581c4969e0 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h @@ -182,7 +182,8 @@ typedef struct rlc_am_entity_s { rlc_sn_t first_retrans_pdu_sn; /*!< \brief Lowest sequence number of PDU to be retransmitted. */ list_t segmentation_pdu_list; /*!< \brief List of "freshly" segmented PDUs. */ - boolean_t status_requested; /*!< \brief Status requested by peer. */ + uint8_t status_requested; /*!< \brief Status bitmap requested by peer. */ + rlc_sn_t sn_status_triggered_delayed; /*!< \brief SN of the last received poll for which Status is delayed until SN is out of Rx Window. */ frame_t last_frame_status_indication; /*!< \brief The last frame number a MAC status indication has been received by RLC. */ //----------------------------- // buffer occupancy measurements sent to MAC diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index cb03e28c4b..d08d010468 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -74,9 +74,10 @@ rlc_am_init( // RX state variables //rlc_pP->vr_r = 0; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; - //rlc_pP->vr_x = 0; + rlc_pP->vr_x = RLC_SN_UNDEFINED; //rlc_pP->vr_ms = 0; //rlc_pP->vr_h = 0; + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->first_retrans_pdu_sn = -1; @@ -128,9 +129,11 @@ rlc_am_reestablish( // RX state variables rlc_pP->vr_r = 0; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; - rlc_pP->vr_x = 0; + rlc_pP->vr_x = RLC_SN_UNDEFINED; rlc_pP->vr_ms = 0; rlc_pP->vr_h = 0; + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + rlc_pP->status_requested = RLC_AM_STATUS_NOT_TRIGGERED; rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->first_retrans_pdu_sn = -1; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c index d783684893..f2246e45f8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c @@ -40,14 +40,15 @@ rlc_am_get_data_pdu_infos( int16_t total_sizeP, rlc_am_pdu_info_t* pdu_info_pP) { - memset(pdu_info_pP, 0, sizeof (rlc_am_pdu_info_t)); + memset(pdu_info_pP, 0, sizeof (rlc_am_pdu_info_t)); - int16_t sum_li = 0; - pdu_info_pP->d_c = header_pP->b1 >> 7; - pdu_info_pP->num_li = 0; + int16_t sum_li = 0; + pdu_info_pP->d_c = header_pP->b1 >> 7; + pdu_info_pP->num_li = 0; - if (pdu_info_pP->d_c) { + AssertFatal (pdu_info_pP->d_c != 0, "RLC AM Rx PDU Data D/C Header Error LcId=%d\n", rlc_pP->channel_id); + pdu_info_pP->rf = (header_pP->b1 >> 6) & 0x01; pdu_info_pP->p = (header_pP->b1 >> 5) & 0x01; pdu_info_pP->fi = (header_pP->b1 >> 3) & 0x03; @@ -117,12 +118,6 @@ rlc_am_get_data_pdu_infos( } return 0; - } else { - LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[GET DATA PDU INFO] SN %04d ERROR CONTROL PDU ", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - pdu_info_pP->sn); - return -1; - } } //----------------------------------------------------------------------------- void @@ -181,26 +176,22 @@ rlc_am_rx_update_vr_ms( do { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - if (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received == 0) { + if ((((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received == 0) || + (rlc_pP->vr_ms != pdu_info_cursor_p->sn)) { + #if TRACE_RLC_AM_RX LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[UPDATE VR(MS)] UPDATED VR(MS) %04d -> %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->vr_ms, pdu_info_cursor_p->sn); #endif - rlc_pP->vr_ms = pdu_info_cursor_p->sn; + return; } + rlc_pP->vr_ms = RLC_AM_NEXT_SN(pdu_info_cursor_p->sn); cursor_p = cursor_p->next; - } while (cursor_p != NULL); + } while ((cursor_p != NULL) && (rlc_pP->vr_ms != rlc_pP->vr_h)); -#if TRACE_RLC_AM_RX - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[UPDATE VR(MS)] UPDATED VR(MS) %04d -> %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->vr_ms, - (pdu_info_cursor_p->sn + 1) & RLC_AM_SN_MASK); -#endif - rlc_pP->vr_ms = (pdu_info_cursor_p->sn + 1) & RLC_AM_SN_MASK; } } // assumed the sn of the tb_p is equal to VR(R) @@ -322,18 +313,14 @@ rlc_am_receive_process_data_pdu ( // - discard the duplicate byte segments. rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)first_byte_pP; + rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; + boolean_t reassemble = false; if (rlc_am_get_data_pdu_infos(ctxt_pP,rlc_pP, rlc_am_pdu_sn_10_p, tb_size_in_bytesP, pdu_info_p) >= 0) { ((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received = 0; - if (rlc_am_in_rx_window(ctxt_pP, rlc_pP, pdu_info_p->sn)) { - - if (pdu_info_p->p) { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] POLL BIT SET, STATUS REQUESTED:\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); - rlc_pP->status_requested = 1; - } + if (RLC_AM_SN_IN_WINDOW(pdu_info_p->sn, rlc_pP->vr_r)) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] VR(R) %04d VR(H) %04d VR(MR) %04d VR(MS) %04d VR(X) %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -346,10 +333,8 @@ rlc_am_receive_process_data_pdu ( if (rlc_am_rx_list_insert_pdu(ctxt_pP, rlc_pP,tb_pP) < 0) { rlc_pP->stat_rx_data_pdu_dropped += 1; rlc_pP->stat_rx_data_bytes_dropped += tb_size_in_bytesP; - free_mem_block (tb_pP, __func__); LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED, STATUS REQUESTED:\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); - rlc_pP->status_requested = 1; #if RLC_STOP_ON_LOST_PDU AssertFatal( 0 == 1, PROTOCOL_RLC_AM_CTXT_FMT" LOST PDU DETECTED\n", @@ -394,12 +379,15 @@ rlc_am_receive_process_data_pdu ( rlc_am_rx_list_display(rlc_pP, "rlc_am_receive_process_data_pdu AFTER INSERTION "); #endif - if (rlc_am_sn_gte_vr_h(ctxt_pP, rlc_pP, pdu_info_p->sn) > 0) { - rlc_pP->vr_h = (pdu_info_p->sn + 1) & RLC_AM_SN_MASK; + /* 1) Update vrH if sn >= vrH */ + if (RLC_AM_DIFF_SN(pdu_info_p->sn,rlc_pP->vr_r) >= RLC_AM_DIFF_SN(rlc_pP->vr_h,rlc_pP->vr_r)) + { + rlc_pP->vr_h = RLC_AM_NEXT_SN(pdu_info_p->sn); } rlc_am_rx_check_all_byte_segments(ctxt_pP, rlc_pP, tb_pP); + /* 2) Reordering Window Processing: Update vr_ms if sn = vr_ms and all bytes received for sn */ if ((pdu_info_p->sn == rlc_pP->vr_ms) && (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received)) { rlc_am_rx_update_vr_ms(ctxt_pP, rlc_pP, tb_pP); } @@ -410,20 +398,35 @@ rlc_am_receive_process_data_pdu ( rlc_pP->vr_mr = (rlc_pP->vr_r + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; } - rlc_am_rx_list_reassemble_rlc_sdus(ctxt_pP, rlc_pP); + reassemble = true; + //TODO : optimization : check whether a reassembly is needed by looking at LI, FI, SO, etc... + } //FNA: fix check VrX out of receiving window - if (rlc_pP->t_reordering.running) { - if ((rlc_pP->vr_x == rlc_pP->vr_r) || ((rlc_am_in_rx_window(ctxt_pP, rlc_pP, rlc_pP->vr_x) == 0) && (rlc_pP->vr_x != rlc_pP->vr_mr))) { + if ((rlc_pP->t_reordering.running) || ((rlc_pP->t_reordering.ms_duration == 0) && (rlc_pP->vr_x != RLC_SN_UNDEFINED))) { + if ((rlc_pP->vr_x == rlc_pP->vr_r) || (!(RLC_AM_SN_IN_WINDOW(rlc_pP->vr_x, rlc_pP->vr_r)) && (rlc_pP->vr_x != rlc_pP->vr_mr))) { rlc_am_stop_and_reset_timer_reordering(ctxt_pP, rlc_pP); + rlc_pP->vr_x = RLC_SN_UNDEFINED; } } if (!(rlc_pP->t_reordering.running)) { if (rlc_pP->vr_h != rlc_pP->vr_r) { // - if VR (H) > VR(R) translated to - if VR (H) != VR(R) - rlc_am_start_timer_reordering(ctxt_pP, rlc_pP); rlc_pP->vr_x = rlc_pP->vr_h; + if (rlc_pP->t_reordering.ms_duration != 0) { + rlc_am_start_timer_reordering(ctxt_pP, rlc_pP); + } + else { + /* specific case for no timer reordering configured */ + /* reordering window directly advances with vrH */ + rlc_pP->vr_ms = rlc_pP->vr_h; + + /* Trigger a Status and clear any existing Delay Flag */ + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_T_REORDERING); + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + } } } } @@ -437,12 +440,67 @@ rlc_am_receive_process_data_pdu ( } else { rlc_pP->stat_rx_data_pdu_out_of_window += 1; rlc_pP->stat_rx_data_bytes_out_of_window += tb_size_in_bytesP; - free_mem_block (tb_pP, __func__); + pdu_status = RLC_AM_DATA_PDU_STATUS_SN_OUTSIDE_WINDOW; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU OUT OF RX WINDOW, DISCARDED, STATUS REQUESTED:\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); - rlc_pP->status_requested = 1; } + + /* 3) Check for triggering a Tx Status PDU if a poll is received or if a pending status was delayed */ + if (pdu_info_p->p) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] POLL BIT SET, STATUS REQUESTED:\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + + /* Polling Info Saving for In and Out of Window PDU */ + /* avoid multi status trigger */ + if ((RLC_AM_GET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED)) || + !(RLC_AM_GET_STATUS(rlc_pP->status_requested,(RLC_AM_STATUS_TRIGGERED_POLL | RLC_AM_STATUS_TRIGGERED_T_REORDERING)))) + { + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_POLL); + + if ((pdu_status != RLC_AM_DATA_PDU_STATUS_OK) || ((pdu_status == RLC_AM_DATA_PDU_STATUS_OK) && + (!(RLC_AM_SN_IN_WINDOW(pdu_info_p->sn,rlc_pP->vr_r)) || + (RLC_AM_DIFF_SN(pdu_info_p->sn,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))) + ) + ) + { + /* Conditions are met for sending a Status Report */ + /* Then clear Delay Flag and reset its corresponding sn */ + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + } + else if (rlc_pP->sn_status_triggered_delayed == RLC_SN_UNDEFINED) + { + /* Delay status trigger if pdustatus OK and sn>= vr_ms */ + /* Note: vr_r and vr_ms have been updated */ + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = pdu_info_p->sn; + } + } + } + + /* ReEnable a previously delayed Status Trigger if PDU discarded or */ + /* sn no more in RxWindow due to RxWindow advance or sn < vr_ms */ + if ((RLC_AM_GET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED)) && + (pdu_status == RLC_AM_DATA_PDU_STATUS_OK) && + (!(RLC_AM_SN_IN_WINDOW(rlc_pP->sn_status_triggered_delayed,rlc_pP->vr_r)) || + (RLC_AM_DIFF_SN(rlc_pP->sn_status_triggered_delayed,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))) + ) + { + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + } + + } else { - free_mem_block (tb_pP, __func__); + pdu_status = RLC_AM_DATA_PDU_STATUS_HEADER_ERROR; + } + + if (pdu_status != RLC_AM_DATA_PDU_STATUS_OK) { + /* Discard received block if out of window, duplicate or header error */ + free_mem_block (tb_pP, __func__); + } + else if (reassemble) { + /* Reassemble SDUs */ + rlc_am_rx_list_reassemble_rlc_sdus(ctxt_pP, rlc_pP); } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index a9f0bdbf7e..8e055406a1 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -49,6 +49,10 @@ rlc_am_rx_list_insert_pdu( cursor_p = rlc_pP->receiver_buffer.head; // it is assumed this pdu is in rx window + //TODO : check for duplicate + // should be rewrite + /* look for previous SN */ + if (cursor_p) { if (rlc_pP->vr_mr < rlc_pP->vr_r) { if (pdu_info_p->sn >= rlc_pP->vr_r) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index d687bf8606..cab0a5340a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -474,7 +474,7 @@ rlc_am_send_status_pdu( pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; sn_cursor = pdu_info_cursor_p->sn; - while (rlc_am_in_rx_window(ctxt_pP, rlc_pP, sn_cursor) == 0) { + while (!(RLC_AM_SN_IN_WINDOW(sn_cursor, rlc_pP->vr_r))) { cursor_p = cursor_p->next; previous_sn_cursor = sn_cursor; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h index 02112fe736..4892090716 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h @@ -236,6 +236,28 @@ typedef struct rlc_am_rx_pdu_management { uint8_t all_segments_received; /*!< \brief Is all segments of PDU SN have been received. */ } rlc_am_rx_pdu_management_t; /** @} */ + +typedef enum rlc_am_rx_pdu_status +{ + /** PDU okay. */ + RLC_AM_DATA_PDU_STATUS_OK = 0, + /** SN outside RX window */ + RLC_AM_DATA_PDU_STATUS_SN_OUTSIDE_WINDOW = 1, + /** SN already available */ + RLC_AM_DATA_PDU_STATUS_SN_DUPLICATE = 2, + /** SN already available */ + RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE = 3, + /** Buffer full */ + RLC_AM_DATA_PDU_STATUS_BUFFER_FULL = 4, + /** Header Error (LI,SO...) */ + RLC_AM_DATA_PDU_STATUS_HEADER_ERROR = 5, + /** Unknown bearer */ + RLC_AM_DATA_PDU_STATUS_INVALID_BEARER = 6, + /** RLC in wrong state */ + RLC_AM_DATA_PDU_STATUS_WRONG_STATE = 7 + +} rlc_am_rx_pdu_status_t; + /*! \cond PRIVATE */ //----------------------------------------------------------------------------- // interlayers optimizations diff --git a/openair2/LAYER2/RLC/rlc_def.h b/openair2/LAYER2/RLC/rlc_def.h index 124ba509b5..929d66b70b 100644 --- a/openair2/LAYER2/RLC/rlc_def.h +++ b/openair2/LAYER2/RLC/rlc_def.h @@ -64,6 +64,7 @@ enum RLC_OPERATION_MODE { TRANSMITTER_ONLY = 0x00, // dimensions # define SN_12BITS_MASK 0x0FFF # define RLC_SN_OVERFLOW 0xFFFF +# define RLC_SN_UNDEFINED RLC_SN_OVERFLOW //---------------------------------------------------------- // DISCARD //---------------------------------------------------------- From 3df061b540dc2716fa026f97c7db8916106124a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 1 Jul 2016 11:25:49 +0200 Subject: [PATCH 132/571] UE/EMM: move emm_indication_callback_t from openair2 to emm_main.h --- openair2/COMMON/commonDef.h | 9 --------- openair3/NAS/UE/EMM/emm_main.h | 9 +++++++++ openair3/NAS/UE/nas_proc.h | 1 + openair3/NAS/UE/nas_user.h | 1 + 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/openair2/COMMON/commonDef.h b/openair2/COMMON/commonDef.h index b1ec47449a..37d05f3fda 100644 --- a/openair2/COMMON/commonDef.h +++ b/openair2/COMMON/commonDef.h @@ -316,15 +316,6 @@ typedef struct { */ #define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];} -/* - * User notification callback, executed whenever a change of data with - * respect of network information (e.g. network registration and/or - * location change, new PLMN becomes available) is notified by the - * EPS Mobility Management sublayer - */ -typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, - const char*, size_t); - typedef enum eps_protocol_discriminator_e { /* Protocol discriminator identifier for EPS Mobility Management */ EPS_MOBILITY_MANAGEMENT_MESSAGE = 0x7, diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index 1ce584210e..c41dc0b664 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -50,6 +50,15 @@ Description Defines the EPS Mobility Management procedure call manager, /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * User notification callback, executed whenever a change of data with + * respect of network information (e.g. network registration and/or + * location change, new PLMN becomes available) is notified by the + * EPS Mobility Management sublayer + */ +typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, + const char*, size_t); + /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index 4514983df8..c66f2177fe 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -40,6 +40,7 @@ Description NAS procedure call manager #include "commonDef.h" #include "networkDef.h" +#include "emm_main.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ diff --git a/openair3/NAS/UE/nas_user.h b/openair3/NAS/UE/nas_user.h index 93b1cc8961..584c7532f0 100644 --- a/openair3/NAS/UE/nas_user.h +++ b/openair3/NAS/UE/nas_user.h @@ -40,6 +40,7 @@ Description NAS procedure functions triggered by the user #include "commonDef.h" #include "networkDef.h" +#include "emm_main.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ From 3835f106592247d4564400267ebb2859e122b2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Thu, 21 Jul 2016 15:49:32 +0200 Subject: [PATCH 133/571] UE/ESM: move esm_indication_callback_t from openair2 to esm_ebr.h --- openair2/COMMON/networkDef.h | 7 ------- openair3/NAS/UE/API/USER/user_api.c | 1 + openair3/NAS/UE/ESM/esm_ebr.h | 8 ++++++++ openair3/NAS/UE/ESM/esm_main.h | 1 + openair3/NAS/UE/nas_proc.h | 1 + openair3/NAS/UE/nas_user.h | 1 + 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/openair2/COMMON/networkDef.h b/openair2/COMMON/networkDef.h index c52a58a527..42c812baad 100644 --- a/openair2/COMMON/networkDef.h +++ b/openair2/COMMON/networkDef.h @@ -252,13 +252,6 @@ typedef struct { network_pkf_t* pkf[NET_PACKET_FILTER_MAX]; } network_tft_t; -/* - * User notification callback, executed whenever a change of status with - * respect of PDN connection or EPS bearer context is notified by the EPS - * Session Management sublayer - */ -typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/API/USER/user_api.c b/openair3/NAS/UE/API/USER/user_api.c index 9c23646292..dd5b5758f1 100644 --- a/openair3/NAS/UE/API/USER/user_api.c +++ b/openair3/NAS/UE/API/USER/user_api.c @@ -48,6 +48,7 @@ Description Implements the API used by the NAS layer running in the UE #include "at_command.h" #include "at_response.h" #include "at_error.h" +#include "esm_ebr.h" #include "user_indication.h" diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h index dd58631956..af31e95676 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.h +++ b/openair3/NAS/UE/ESM/esm_ebr.h @@ -42,6 +42,7 @@ Description Defines functions used to handle state of EPS bearer contexts #include "OctetString.h" #include "networkDef.h" +#include "esmData.h" #include "nas_timer.h" @@ -56,6 +57,13 @@ Description Defines functions used to handle state of EPS bearer contexts /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * User notification callback, executed whenever a change of status with + * respect of PDN connection or EPS bearer context is notified by the EPS + * Session Management sublayer + */ +typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); + /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h index d7346fdb08..d6fed970f0 100644 --- a/openair3/NAS/UE/ESM/esm_main.h +++ b/openair3/NAS/UE/ESM/esm_main.h @@ -41,6 +41,7 @@ Description Defines the EPS Session Management procedure call manager, #define __ESM_MAIN_H__ #include "networkDef.h" +#include "esm_ebr.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index c66f2177fe..bf8e286cc7 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -41,6 +41,7 @@ Description NAS procedure call manager #include "commonDef.h" #include "networkDef.h" #include "emm_main.h" +#include "esm_ebr.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ diff --git a/openair3/NAS/UE/nas_user.h b/openair3/NAS/UE/nas_user.h index 584c7532f0..9cb7561816 100644 --- a/openair3/NAS/UE/nas_user.h +++ b/openair3/NAS/UE/nas_user.h @@ -41,6 +41,7 @@ Description NAS procedure functions triggered by the user #include "commonDef.h" #include "networkDef.h" #include "emm_main.h" +#include "esm_ebr.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ From b4cbddb97079e7abcd31e4380031b75613254e8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 1 Jul 2016 11:29:27 +0200 Subject: [PATCH 134/571] UE: move nas_ue_task.h from openair2 to openair3/NAS/UE --- {openair2/NAS => openair3/NAS/UE}/nas_ue_task.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {openair2/NAS => openair3/NAS/UE}/nas_ue_task.h (100%) diff --git a/openair2/NAS/nas_ue_task.h b/openair3/NAS/UE/nas_ue_task.h similarity index 100% rename from openair2/NAS/nas_ue_task.h rename to openair3/NAS/UE/nas_ue_task.h From 2d8cf88884131f304ed45f059f1d8c46c2fb0f5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 27 Jul 2016 07:16:16 -0500 Subject: [PATCH 135/571] openair2/RRC/LITE: remove fixed ue_mod_id = 0 --- openair2/RRC/LITE/rrc_UE.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index a6290f1f3c..9c5eaef6e3 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -4391,7 +4391,6 @@ void *rrc_ue_task( void *args_p ) /* NAS messages */ case NAS_CELL_SELECTION_REQ: - ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */ LOG_D(RRC, "[UE %d] Received %s: state %d, plmnID (%d%d%d.%d%d%d), rat %x\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id), NAS_CELL_SELECTION_REQ (msg_p).plmnID.MCCdigit1, @@ -4692,7 +4691,6 @@ void *rrc_ue_task( void *args_p ) break; case RRC_RAL_CONNECTION_RELEASE_REQ: - ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */ LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, msg_name); break; #endif From 7c8dbbdb25a9195d73dc26bd149cb99979934593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 1 Jul 2016 13:48:34 +0200 Subject: [PATCH 136/571] UE: introduce the nas_user_t type in user_defs.h --- openair3/NAS/UE/user_defs.h | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 openair3/NAS/UE/user_defs.h diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h new file mode 100644 index 0000000000..80607124d2 --- /dev/null +++ b/openair3/NAS/UE/user_defs.h @@ -0,0 +1,51 @@ +/******************************************************************************* + 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 . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ +/***************************************************************************** +Source user_defs.h + +Version 0.1 + +Date 2016/07/01 + +Product NAS stack + +Subsystem NAS main process + +Author Frederic Leroy + +Description NAS type definition to manage a user equipment + +*****************************************************************************/ +#ifndef __USER_DEFS_H__ +#define __USER_DEFS_H__ + +typedef struct { +} nas_user_t; + +#endif From 2ee6ae11df4cd5bc42157aa2c5e0c79dab9ef7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 1 Jul 2016 15:00:35 +0200 Subject: [PATCH 137/571] UE: create a user and move user_fd into the nas_user_t struct --- openair3/NAS/UE/nas_ue_task.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 9d097fc389..9b17ab8778 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -25,20 +25,20 @@ # include "nas_ue_task.h" # include "UTIL/LOG/log.h" -# include "nas_user.h" +# include "user_defs.h" # include "user_api.h" # include "nas_parser.h" # include "nas_proc.h" # include "msc.h" +#include "nas_user.h" + # define NAS_UE_AUTOSTART 1 extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; -static int user_fd; - -static int nas_ue_process_events(struct epoll_event *events, int nb_events) +static int nas_ue_process_events(nas_user_t *user, struct epoll_event *events, int nb_events) { int event; int exit_loop = FALSE; @@ -48,8 +48,8 @@ static int nas_ue_process_events(struct epoll_event *events, int nb_events) for (event = 0; event < nb_events; event++) { if (events[event].events != 0) { /* If the event has not been yet been processed (not an itti message) */ - if (events[event].data.fd == user_fd) { - exit_loop = nas_user_receive_and_process(&user_fd, NULL); + if (events[event].data.fd == user->fd) { + exit_loop = nas_user_receive_and_process(&user->fd, NULL); } else { LOG_E(NAS, "[UE] Received an event from an unknown fd %d!\n", events[event].data.fd); } @@ -68,6 +68,9 @@ void *nas_ue_task(void *args_p) instance_t instance; unsigned int Mod_id; int result; + nas_user_t user_value = {}; + nas_user_t *user = &user_value; + itti_mark_task_ready (TASK_NAS_UE); MSC_START_USE(); @@ -81,8 +84,8 @@ void *nas_ue_task(void *args_p) exit (EXIT_FAILURE); } - user_fd = user_api_get_fd (); - itti_subscribe_event_fd (TASK_NAS_UE, user_fd); + user->fd = user_api_get_fd (); + itti_subscribe_event_fd (TASK_NAS_UE, user->fd); } /* Initialize NAS user */ @@ -114,7 +117,7 @@ void *nas_ue_task(void *args_p) /* Send an activate modem command to NAS like UserProcess should do it */ char *user_data = "at+cfun=1\r"; - nas_user_receive_and_process (&user_fd, user_data); + nas_user_receive_and_process (&user->fd, user_data); } #endif break; @@ -215,7 +218,7 @@ void *nas_ue_task(void *args_p) nb_events = itti_get_events(TASK_NAS_UE, &events); if ((nb_events > 0) && (events != NULL)) { - if (nas_ue_process_events(events, nb_events) == TRUE) { + if (nas_ue_process_events(user, events, nb_events) == TRUE) { LOG_E(NAS, "[UE] Received exit loop\n"); } } From ee82aed18240e284fcdd50dce7b8be1ac4fa79b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 4 Jul 2016 11:38:13 +0200 Subject: [PATCH 138/571] UE: move _nas_proc_data to nas_user_t struct --- openair3/NAS/UE/UEprocess.c | 9 ++- openair3/NAS/UE/nas_network.c | 5 +- openair3/NAS/UE/nas_network.h | 4 +- openair3/NAS/UE/nas_proc.c | 60 ++++++++--------- openair3/NAS/UE/nas_proc.h | 13 ++-- openair3/NAS/UE/nas_proc_defs.h | 16 +++++ openair3/NAS/UE/nas_ue_task.c | 8 +-- openair3/NAS/UE/nas_user.c | 110 ++++++++++++++++---------------- openair3/NAS/UE/nas_user.h | 7 +- openair3/NAS/UE/user_defs.h | 4 ++ 10 files changed, 127 insertions(+), 109 deletions(-) create mode 100644 openair3/NAS/UE/nas_proc_defs.h diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 20af58dac6..a0eaf2f9c2 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -46,6 +46,7 @@ #include "nas_user.h" #include "nas_network.h" #include "nas_parser.h" +#include "user_defs.h" #include // exit #include // poll @@ -72,6 +73,8 @@ static void _nas_signal_handler(int signal); static void _nas_clean(int usr_fd, int net_fd); uint8_t usim_test = 0; +// FIXME user must be set up with right itti message instance +nas_user_t *user = NULL; /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -129,7 +132,7 @@ int main(int argc, const char *argv[]) /* * Initialize the NAS contexts */ - nas_user_initialize (&user_api_emm_callback, &user_api_esm_callback, + nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); nas_network_initialize (); @@ -226,7 +229,7 @@ static void *_nas_user_mngr(void *args) /* User receiving loop */ while (!exit_loop) { - exit_loop = nas_user_receive_and_process(fd, NULL); + exit_loop = nas_user_receive_and_process(user, NULL); } /* Close the connection to the user application layer */ @@ -291,7 +294,7 @@ static void *_nas_network_mngr(void *args) } /* Process the network data message */ - ret_code = nas_network_process_data (network_message_id, + ret_code = nas_network_process_data (user, network_message_id, network_api_get_data ()); if (ret_code != RETURNok) { diff --git a/openair3/NAS/UE/nas_network.c b/openair3/NAS/UE/nas_network.c index f3ee3d2955..2962585ede 100644 --- a/openair3/NAS/UE/nas_network.c +++ b/openair3/NAS/UE/nas_network.c @@ -43,6 +43,7 @@ Description NAS procedure functions triggered by the network #include "as_message.h" #include "nas_proc.h" +#include "user_defs.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -118,7 +119,7 @@ void nas_network_cleanup(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_network_process_data(int msg_id, const void *data) +int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) { LOG_FUNC_IN; @@ -142,7 +143,7 @@ int nas_network_process_data(int msg_id, const void *data) /* Received cell information confirm */ const cell_info_cnf_t *info = &msg->msg.cell_info_cnf; int cell_found = (info->errCode == AS_SUCCESS); - rc = nas_proc_cell_info(cell_found, info->tac, + rc = nas_proc_cell_info(user, cell_found, info->tac, info->cellID, info->rat, info->rsrp, info->rsrq); break; diff --git a/openair3/NAS/UE/nas_network.h b/openair3/NAS/UE/nas_network.h index 363f63c5ab..31716a2276 100644 --- a/openair3/NAS/UE/nas_network.h +++ b/openair3/NAS/UE/nas_network.h @@ -40,6 +40,8 @@ Description NAS procedure functions triggered by the network #ifndef __NAS_NETWORK_H__ #define __NAS_NETWORK_H__ +#include "user_defs.h" + /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ @@ -61,7 +63,7 @@ void nas_network_initialize(void); void nas_network_cleanup(void); -int nas_network_process_data(int command_id, const void *data); +int nas_network_process_data(nas_user_t *user, int command_id, const void *data); const void *nas_network_get_data(void); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 79b6626995..352fae6e09 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -38,6 +38,7 @@ Description NAS procedure call manager #include "nas_proc.h" #include "nas_log.h" +#include "nas_user.h" #include "emm_main.h" #include "emm_sap.h" @@ -62,17 +63,6 @@ Description NAS procedure call manager #define NAS_PROC_RSRQ_UNKNOWN 255 #define NAS_PROC_RSRP_UNKNOWN 255 -/* - * Local NAS data - */ -static struct { - /* EPS capibility status */ - int EPS_capability_status; - /* Reference signal received quality */ - int rsrq; - /* Reference signal received power */ - int rsrp; -} _nas_proc_data; static int _nas_proc_activate(int cid, int apply_to_all); static int _nas_proc_deactivate(int cid, int apply_to_all); @@ -97,15 +87,15 @@ static int _nas_proc_deactivate(int cid, int apply_to_all); ** Others: _nas_proc_data ** ** ** ***************************************************************************/ -void nas_proc_initialize(emm_indication_callback_t emm_cb, +void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *imei) { LOG_FUNC_IN; /* Initialize local NAS data */ - _nas_proc_data.EPS_capability_status = FALSE; - _nas_proc_data.rsrq = NAS_PROC_RSRQ_UNKNOWN; - _nas_proc_data.rsrp = NAS_PROC_RSRP_UNKNOWN; + user->proc.EPS_capability_status = FALSE; + user->proc.rsrq = NAS_PROC_RSRQ_UNKNOWN; + user->proc.rsrp = NAS_PROC_RSRP_UNKNOWN; /* Initialize the EMM procedure manager */ emm_main_initialize(emm_cb, imei); @@ -131,7 +121,7 @@ void nas_proc_initialize(emm_indication_callback_t emm_cb, ** Others: None ** ** ** ***************************************************************************/ -void nas_proc_cleanup(void) +void nas_proc_cleanup() { LOG_FUNC_IN; @@ -172,7 +162,7 @@ void nas_proc_cleanup(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_enable_s1_mode(void) +int nas_proc_enable_s1_mode(nas_user_t *user) { LOG_FUNC_IN; @@ -183,7 +173,7 @@ int nas_proc_enable_s1_mode(void) * Notify the EMM procedure call manager that EPS capability * of the UE is enabled */ - _nas_proc_data.EPS_capability_status = TRUE; + user->proc.EPS_capability_status = TRUE; emm_sap.primitive = EMMREG_S1_ENABLED; rc = emm_sap_send(&emm_sap); @@ -205,7 +195,7 @@ int nas_proc_enable_s1_mode(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_disable_s1_mode(void) +int nas_proc_disable_s1_mode(nas_user_t *user) { LOG_FUNC_IN; @@ -216,7 +206,7 @@ int nas_proc_disable_s1_mode(void) * Notify the EMM procedure call manager that EPS capability * of the UE is disabled */ - _nas_proc_data.EPS_capability_status = FALSE; + user->proc.EPS_capability_status = FALSE; emm_sap.primitive = EMMREG_S1_DISABLED; rc = emm_sap_send(&emm_sap); @@ -238,11 +228,11 @@ int nas_proc_disable_s1_mode(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_eps(int *stat) +int nas_proc_get_eps(nas_user_t *user, int *stat) { LOG_FUNC_IN; - *stat = _nas_proc_data.EPS_capability_status; + *stat = user->proc.EPS_capability_status; LOG_FUNC_RETURN (RETURNok); } @@ -358,12 +348,12 @@ int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_signal_quality(int *rsrq, int *rsrp) +int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp) { LOG_FUNC_IN; - *rsrq = _nas_proc_data.rsrq; - *rsrp = _nas_proc_data.rsrp; + *rsrq = user->proc.rsrq; + *rsrp = user->proc.rsrp; LOG_FUNC_RETURN (RETURNok); } @@ -426,7 +416,7 @@ int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_deregister(void) +int nas_proc_deregister() { LOG_FUNC_IN; @@ -604,7 +594,7 @@ int nas_proc_detach(int switch_off) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_attach(void) +int nas_proc_attach() { LOG_FUNC_IN; @@ -636,7 +626,7 @@ int nas_proc_attach(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_attach_status(void) +int nas_proc_get_attach_status() { LOG_FUNC_IN; @@ -659,7 +649,7 @@ int nas_proc_get_attach_status(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_range(void) +int nas_proc_get_pdn_range() { LOG_FUNC_IN; @@ -1021,7 +1011,7 @@ int nas_proc_activate_pdn(int cid) ** Others: _nas_proc_data ** ** ** ***************************************************************************/ -int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t AcT, +int nas_proc_cell_info(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t AcT, uint8_t rsrq, uint8_t rsrp) { LOG_FUNC_IN; @@ -1030,8 +1020,8 @@ int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t AcT, int rc; /* Store LTE signal strength/quality measurement data */ - _nas_proc_data.rsrq = rsrq; - _nas_proc_data.rsrp = rsrp; + user->proc.rsrq = rsrq; + user->proc.rsrp = rsrp; /* * Notify the EMM procedure call manager that cell information @@ -1103,7 +1093,7 @@ int nas_proc_establish_cnf(const Byte_t *data, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_establish_rej(void) +int nas_proc_establish_rej() { LOG_FUNC_IN; @@ -1170,7 +1160,7 @@ int nas_proc_release_ind(int cause) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_ul_transfer_cnf(void) +int nas_proc_ul_transfer_cnf() { LOG_FUNC_IN; @@ -1207,7 +1197,7 @@ int nas_proc_ul_transfer_cnf(void) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_ul_transfer_rej(void) +int nas_proc_ul_transfer_rej() { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index bf8e286cc7..aaefe6f046 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -40,6 +40,7 @@ Description NAS procedure call manager #include "commonDef.h" #include "networkDef.h" +#include "user_defs.h" #include "emm_main.h" #include "esm_ebr.h" @@ -59,7 +60,7 @@ Description NAS procedure call manager /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void nas_proc_initialize(emm_indication_callback_t emm_cb, +void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *imei); void nas_proc_cleanup(void); @@ -70,14 +71,14 @@ void nas_proc_cleanup(void); * -------------------------------------------------------------------------- */ -int nas_proc_enable_s1_mode(void); -int nas_proc_disable_s1_mode(void); -int nas_proc_get_eps(int *stat); +int nas_proc_enable_s1_mode(nas_user_t *user); +int nas_proc_disable_s1_mode(nas_user_t *user); +int nas_proc_get_eps(nas_user_t *user, int *stat); int nas_proc_get_imsi(char *imsi_str); int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi); -int nas_proc_get_signal_quality(int *rsrq, int *rsrp); +int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp); int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT); int nas_proc_deregister(void); @@ -110,7 +111,7 @@ int nas_proc_activate_pdn(int cid); * -------------------------------------------------------------------------- */ -int nas_proc_cell_info(int found, tac_t tac, ci_t ci, AcT_t rat, uint8_t rsrp, +int nas_proc_cell_info(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat, uint8_t rsrp, uint8_t rsrq); int nas_proc_establish_cnf(const Byte_t *data, uint32_t len); diff --git a/openair3/NAS/UE/nas_proc_defs.h b/openair3/NAS/UE/nas_proc_defs.h new file mode 100644 index 0000000000..d3868526eb --- /dev/null +++ b/openair3/NAS/UE/nas_proc_defs.h @@ -0,0 +1,16 @@ +#ifndef _NAS_PROC_DEFS_H +#define _NAS_PROC_DEFS_H + +/* + * Local NAS data + */ +typedef struct { + /* EPS capibility status */ + int EPS_capability_status; + /* Reference signal received quality */ + int rsrq; + /* Reference signal received power */ + int rsrp; +} proc_data_t; + +#endif diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 9b17ab8778..85606d2a4c 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -49,7 +49,7 @@ static int nas_ue_process_events(nas_user_t *user, struct epoll_event *events, i if (events[event].events != 0) { /* If the event has not been yet been processed (not an itti message) */ if (events[event].data.fd == user->fd) { - exit_loop = nas_user_receive_and_process(&user->fd, NULL); + exit_loop = nas_user_receive_and_process(user, NULL); } else { LOG_E(NAS, "[UE] Received an event from an unknown fd %d!\n", events[event].data.fd); } @@ -89,7 +89,7 @@ void *nas_ue_task(void *args_p) } /* Initialize NAS user */ - nas_user_initialize (&user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); + nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); } /* Set UE activation state */ @@ -117,7 +117,7 @@ void *nas_ue_task(void *args_p) /* Send an activate modem command to NAS like UserProcess should do it */ char *user_data = "at+cfun=1\r"; - nas_user_receive_and_process (&user->fd, user_data); + nas_user_receive_and_process (user, user_data); } #endif break; @@ -137,7 +137,7 @@ void *nas_ue_task(void *args_p) { int cell_found = (NAS_CELL_SELECTION_CNF (msg_p).errCode == AS_SUCCESS); - nas_proc_cell_info (cell_found, NAS_CELL_SELECTION_CNF (msg_p).tac, + nas_proc_cell_info (user, cell_found, NAS_CELL_SELECTION_CNF (msg_p).tac, NAS_CELL_SELECTION_CNF (msg_p).cellID, NAS_CELL_SELECTION_CNF (msg_p).rat, NAS_CELL_SELECTION_CNF (msg_p).rsrq, NAS_CELL_SELECTION_CNF (msg_p).rsrp); } diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 7616a48c05..0b7b6627a8 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -37,8 +37,7 @@ Description NAS procedure functions triggered by the user *****************************************************************************/ -#include "nas_user.h" -#include "userDef.h" +#include "user_defs.h" #include "nas_log.h" #include "memory.h" @@ -47,6 +46,7 @@ Description NAS procedure functions triggered by the user #include "at_error.h" #include "user_indication.h" #include "nas_proc.h" +#include "nas_user.h" #include "user_api.h" #include // memset, strncpy, strncmp @@ -65,30 +65,30 @@ Description NAS procedure functions triggered by the user * Functions executed upon receiving AT command from the user * --------------------------------------------------------------------- */ -static int _nas_user_proc_cgsn (const at_command_t *data); -static int _nas_user_proc_cgmi (const at_command_t *data); -static int _nas_user_proc_cgmm (const at_command_t *data); -static int _nas_user_proc_cgmr (const at_command_t *data); -static int _nas_user_proc_cimi (const at_command_t *data); -static int _nas_user_proc_cfun (const at_command_t *data); -static int _nas_user_proc_cpin (const at_command_t *data); -static int _nas_user_proc_csq (const at_command_t *data); -static int _nas_user_proc_cesq (const at_command_t *data); -static int _nas_user_proc_cops (const at_command_t *data); -static int _nas_user_proc_cgatt (const at_command_t *data); -static int _nas_user_proc_creg (const at_command_t *data); -static int _nas_user_proc_cgreg (const at_command_t *data); -static int _nas_user_proc_cereg (const at_command_t *data); -static int _nas_user_proc_cgdcont (const at_command_t *data); -static int _nas_user_proc_cgact (const at_command_t *data); -static int _nas_user_proc_cmee (const at_command_t *data); -static int _nas_user_proc_clck (const at_command_t *data); -static int _nas_user_proc_cgpaddr (const at_command_t *data); -static int _nas_user_proc_cnum (const at_command_t *data); -static int _nas_user_proc_clac (const at_command_t *data); +static int _nas_user_proc_cgsn (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgmi (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgmm (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgmr (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cimi (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cfun (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cpin (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_csq (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cesq (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cops (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgatt (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_creg (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgreg (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cereg (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgdcont (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgact (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cmee (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_clck (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cgpaddr (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_cnum (nas_user_t *user, const at_command_t *data); +static int _nas_user_proc_clac (nas_user_t *user, const at_command_t *data); /* NAS procedures applicable to AT commands */ -typedef int (*_nas_user_procedure_t) (const at_command_t *); +typedef int (*_nas_user_procedure_t) (nas_user_t *, const at_command_t *); static _nas_user_procedure_t _nas_user_procedure[AT_COMMAND_ID_MAX] = { NULL, @@ -186,7 +186,7 @@ static user_nvdata_t _nas_user_nvdata; ** Others: _nas_user_nvdata, _nas_user_context ** ** ** ***************************************************************************/ -void nas_user_initialize(emm_indication_callback_t emm_cb, +void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *version) { LOG_FUNC_IN; @@ -214,7 +214,7 @@ void nas_user_initialize(emm_indication_callback_t emm_cb, _nas_user_context.fun = AT_CFUN_FUN_DEFAULT; /* Initialize the internal NAS processing data */ - nas_proc_initialize(emm_cb, esm_cb, _nas_user_nvdata.IMEI); + nas_proc_initialize(user, emm_cb, esm_cb, _nas_user_nvdata.IMEI); LOG_FUNC_OUT; } @@ -232,7 +232,7 @@ void nas_user_initialize(emm_indication_callback_t emm_cb, ** Outputs: Return: FALSE, TRUE ** ** ** ***************************************************************************/ -int nas_user_receive_and_process(int *fd, char *message) +int nas_user_receive_and_process(nas_user_t *user, char *message) { LOG_FUNC_IN; @@ -246,7 +246,7 @@ int nas_user_receive_and_process(int *fd, char *message) bytes = user_api_set_data(message); } else { /* Read the user data message */ - bytes = user_api_read_data (*fd); + bytes = user_api_read_data (user->fd); if (bytes == RETURNerror) { /* Failed to read data from the user application layer; @@ -279,7 +279,7 @@ int nas_user_receive_and_process(int *fd, char *message) } /* Process the user data message */ - ret_code = nas_user_process_data (data); + ret_code = nas_user_process_data (user, data); if (ret_code != RETURNok) { /* The user data message has not been successfully @@ -302,7 +302,7 @@ int nas_user_receive_and_process(int *fd, char *message) } /* Send the data message to the user */ - bytes = user_api_send_data (*fd, bytes); + bytes = user_api_send_data (user->fd, bytes); if (bytes == RETURNerror) { /* Failed to send data to the user application layer; @@ -334,7 +334,7 @@ int nas_user_receive_and_process(int *fd, char *message) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -int nas_user_process_data(const void *data) +int nas_user_process_data(nas_user_t *user, const void *data) { LOG_FUNC_IN; @@ -355,7 +355,7 @@ int nas_user_process_data(const void *data) nas_procedure = _nas_user_procedure[user_data->id]; if (nas_procedure != NULL) { - ret_code = (*nas_procedure)(user_data); + ret_code = (*nas_procedure)(user, user_data); } else { /* AT command related to result format only */ _nas_user_data.id = user_data->id; @@ -418,7 +418,7 @@ const void *nas_user_get_data(void) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgsn(const at_command_t *data) +static int _nas_user_proc_cgsn(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -470,7 +470,7 @@ static int _nas_user_proc_cgsn(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgmi(const at_command_t *data) +static int _nas_user_proc_cgmi(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -522,7 +522,7 @@ static int _nas_user_proc_cgmi(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgmm(const at_command_t *data) +static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -575,7 +575,7 @@ static int _nas_user_proc_cgmm(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgmr(const at_command_t *data) +static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -631,7 +631,7 @@ static int _nas_user_proc_cgmr(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cimi(const at_command_t *data) +static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -692,7 +692,7 @@ static int _nas_user_proc_cimi(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cfun(const at_command_t *data) +static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -751,7 +751,7 @@ static int _nas_user_proc_cfun(const at_command_t *data) case AT_CFUN_FULL: /* Notify the NAS procedure call manager that the UE is * operational */ - ret_code = nas_proc_enable_s1_mode(); + ret_code = nas_proc_enable_s1_mode(user); break; default: @@ -805,7 +805,7 @@ static int _nas_user_proc_cfun(const at_command_t *data) ** Others: _nas_user_context, _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cpin(const at_command_t *data) +static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -891,7 +891,7 @@ static int _nas_user_proc_cpin(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_csq(const at_command_t *data) +static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -952,7 +952,7 @@ static int _nas_user_proc_csq(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cesq(const at_command_t *data) +static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -979,7 +979,7 @@ static int _nas_user_proc_cesq(const at_command_t *data) cesq->ber = AT_CESQ_BER_UNKNOWN; cesq->rscp = AT_CESQ_RSCP_UNKNOWN; cesq->ecno = AT_CESQ_ECNO_UNKNOWN; - ret_code = nas_proc_get_signal_quality(&cesq->rsrq, &cesq->rsrp); + ret_code = nas_proc_get_signal_quality(user, &cesq->rsrq, &cesq->rsrp); break; case AT_COMMAND_TST: @@ -1017,7 +1017,7 @@ static int _nas_user_proc_cesq(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cops(const at_command_t *data) +static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -1266,7 +1266,7 @@ static int _nas_user_proc_cops(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgatt(const at_command_t *data) +static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -1371,7 +1371,7 @@ static int _nas_user_proc_cgatt(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_creg(const at_command_t *data) +static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -1520,7 +1520,7 @@ static int _nas_user_proc_creg(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgreg(const at_command_t *data) +static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -1669,7 +1669,7 @@ static int _nas_user_proc_cgreg(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cereg(const at_command_t *data) +static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -1850,7 +1850,7 @@ static int _nas_user_proc_cereg(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgdcont(const at_command_t *data) +static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -2102,7 +2102,7 @@ static int _nas_user_proc_cgdcont(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgact(const at_command_t *data) +static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -2229,7 +2229,7 @@ static int _nas_user_proc_cgact(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cmee(const at_command_t *data) +static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -2342,7 +2342,7 @@ static int _nas_user_proc_cmee(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_clck(const at_command_t *data) +static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -2474,7 +2474,7 @@ static int _nas_user_proc_clck(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cgpaddr(const at_command_t *data) +static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -2566,7 +2566,7 @@ static int _nas_user_proc_cgpaddr(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_cnum(const at_command_t *data) +static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; @@ -2627,7 +2627,7 @@ static int _nas_user_proc_cnum(const at_command_t *data) ** Others: _nas_user_data ** ** ** ***************************************************************************/ -static int _nas_user_proc_clac(const at_command_t *data) +static int _nas_user_proc_clac(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/nas_user.h b/openair3/NAS/UE/nas_user.h index 9cb7561816..c78759ef42 100644 --- a/openair3/NAS/UE/nas_user.h +++ b/openair3/NAS/UE/nas_user.h @@ -42,6 +42,7 @@ Description NAS procedure functions triggered by the user #include "networkDef.h" #include "emm_main.h" #include "esm_ebr.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -59,12 +60,12 @@ Description NAS procedure functions triggered by the user /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void nas_user_initialize(emm_indication_callback_t emm_cb, +void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *version); -int nas_user_receive_and_process(int * fd, char *message); +int nas_user_receive_and_process(nas_user_t *user, char *message); -int nas_user_process_data(const void *data); +int nas_user_process_data(nas_user_t *user, const void *data); const void *nas_user_get_data(void); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 80607124d2..b448a38f7f 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -45,7 +45,11 @@ Description NAS type definition to manage a user equipment #ifndef __USER_DEFS_H__ #define __USER_DEFS_H__ +#include "nas_proc_defs.h" + typedef struct { + int fd; + proc_data_t proc; } nas_user_t; #endif From d4de8aaf0f7baa89876cc3940659c6d977e02652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 5 Jul 2016 10:46:43 +0200 Subject: [PATCH 139/571] UE: use nas_user_t in nas_* function prototype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merely adds a "user" object in all nas_* functions. This don't move any data structure. It allows next patches to be nicely split. Signed-off-by: Frédéric Leroy --- openair3/NAS/UE/UEprocess.c | 4 ++- openair3/NAS/UE/nas_network.c | 16 ++++----- openair3/NAS/UE/nas_network.h | 2 +- openair3/NAS/UE/nas_proc.c | 68 +++++++++++++++++------------------ openair3/NAS/UE/nas_proc.h | 48 ++++++++++++------------- openair3/NAS/UE/nas_ue_task.c | 10 +++--- openair3/NAS/UE/nas_user.c | 40 ++++++++++----------- 7 files changed, 95 insertions(+), 93 deletions(-) diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index a0eaf2f9c2..aa96a97b73 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -408,7 +408,9 @@ static void _nas_clean(int usr_fd, int net_fd) LOG_FUNC_IN; LOG_TRACE (INFO, "UE-MAIN - Perform EMM and ESM cleanup"); - nas_network_cleanup (); + // FIXME nas_network_cleanup depends on nas_user_t + // Why this program should interfere like that with oaisim ? + //nas_network_cleanup (); LOG_TRACE (INFO, "UE-MAIN - " "Closing user connection %d and network connection %d", diff --git a/openair3/NAS/UE/nas_network.c b/openair3/NAS/UE/nas_network.c index 2962585ede..6ca4a34c7f 100644 --- a/openair3/NAS/UE/nas_network.c +++ b/openair3/NAS/UE/nas_network.c @@ -92,11 +92,11 @@ void nas_network_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -void nas_network_cleanup(void) +void nas_network_cleanup(nas_user_t *user) { LOG_FUNC_IN; - nas_proc_cleanup(); + nas_proc_cleanup(user); LOG_FUNC_OUT; } @@ -161,12 +161,12 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) if ( (confirm->errCode == AS_SUCCESS) || (confirm->errCode == AS_TERMINATED_NAS) ) { - rc = nas_proc_establish_cnf(confirm->nasMsg.data, + rc = nas_proc_establish_cnf(user, confirm->nasMsg.data, confirm->nasMsg.length); } else { LOG_TRACE(WARNING, "NET-MAIN - " "Initial NAS message not delivered"); - rc = nas_proc_establish_rej(); + rc = nas_proc_establish_rej(user); } break; @@ -174,7 +174,7 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) case AS_NAS_RELEASE_IND: /* Received NAS signalling connection releaase indication */ - rc = nas_proc_release_ind(msg->msg.nas_release_ind.cause); + rc = nas_proc_release_ind(user, msg->msg.nas_release_ind.cause); break; case AS_UL_INFO_TRANSFER_CNF: @@ -183,9 +183,9 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) if (msg->msg.ul_info_transfer_cnf.errCode != AS_SUCCESS) { LOG_TRACE(WARNING, "NET-MAIN - " "Uplink NAS message not delivered"); - rc = nas_proc_ul_transfer_rej(); + rc = nas_proc_ul_transfer_rej(user); } else { - rc = nas_proc_ul_transfer_cnf(); + rc = nas_proc_ul_transfer_cnf(user); } break; @@ -193,7 +193,7 @@ int nas_network_process_data(nas_user_t *user, int msg_id, const void *data) case AS_DL_INFO_TRANSFER_IND: { const dl_info_transfer_ind_t *info = &msg->msg.dl_info_transfer_ind; /* Received downlink data transfer indication */ - rc = nas_proc_dl_transfer_ind(info->nasMsg.data, + rc = nas_proc_dl_transfer_ind(user, info->nasMsg.data, info->nasMsg.length); break; } diff --git a/openair3/NAS/UE/nas_network.h b/openair3/NAS/UE/nas_network.h index 31716a2276..fb05c8dd2a 100644 --- a/openair3/NAS/UE/nas_network.h +++ b/openair3/NAS/UE/nas_network.h @@ -61,7 +61,7 @@ Description NAS procedure functions triggered by the network void nas_network_initialize(void); -void nas_network_cleanup(void); +void nas_network_cleanup(nas_user_t *user); int nas_network_process_data(nas_user_t *user, int command_id, const void *data); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 352fae6e09..c4b1dc9928 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -64,8 +64,8 @@ Description NAS procedure call manager #define NAS_PROC_RSRP_UNKNOWN 255 -static int _nas_proc_activate(int cid, int apply_to_all); -static int _nas_proc_deactivate(int cid, int apply_to_all); +static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all); +static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -121,12 +121,12 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, ** Others: None ** ** ** ***************************************************************************/ -void nas_proc_cleanup() +void nas_proc_cleanup(nas_user_t *user) { LOG_FUNC_IN; /* Detach the UE from the EPS network */ - int rc = nas_proc_detach(TRUE); + int rc = nas_proc_detach(user, TRUE); if (rc != RETURNok) { LOG_TRACE(ERROR, "NAS-PROC - Failed to detach from the network"); @@ -377,7 +377,7 @@ int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT) +int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn_t *oper, int AcT) { LOG_FUNC_IN; @@ -416,7 +416,7 @@ int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_deregister() +int nas_proc_deregister(nas_user_t *user) { LOG_FUNC_IN; @@ -446,7 +446,7 @@ int nas_proc_deregister() ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_reg_data(int *mode, int *selected, int format, +int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, network_plmn_t *oper, int *AcT) { LOG_FUNC_IN; @@ -485,7 +485,7 @@ int nas_proc_get_reg_data(int *mode, int *selected, int format, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_oper_list(const char **oper_list) +int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list) { LOG_FUNC_IN; @@ -510,7 +510,7 @@ int nas_proc_get_oper_list(const char **oper_list) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_reg_status(int *stat) +int nas_proc_get_reg_status(nas_user_t *user, int *stat) { LOG_FUNC_IN; @@ -538,7 +538,7 @@ int nas_proc_get_reg_status(int *stat) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_loc_info(char *tac, char *ci, int *AcT) +int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT) { LOG_FUNC_IN; @@ -563,7 +563,7 @@ int nas_proc_get_loc_info(char *tac, char *ci, int *AcT) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_detach(int switch_off) +int nas_proc_detach(nas_user_t *user, int switch_off) { LOG_FUNC_IN; @@ -594,7 +594,7 @@ int nas_proc_detach(int switch_off) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_attach() +int nas_proc_attach(nas_user_t *user) { LOG_FUNC_IN; @@ -626,7 +626,7 @@ int nas_proc_attach() ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_attach_status() +int nas_proc_get_attach_status(nas_user_t *user) { LOG_FUNC_IN; @@ -649,7 +649,7 @@ int nas_proc_get_attach_status() ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_range() +int nas_proc_get_pdn_range(nas_user_t *user) { LOG_FUNC_IN; @@ -674,7 +674,7 @@ int nas_proc_get_pdn_range() ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_status(int *cids, int *states, int n_pdn_max) +int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max) { LOG_FUNC_IN; @@ -718,7 +718,7 @@ int nas_proc_get_pdn_status(int *cids, int *states, int n_pdn_max) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_param(int *cids, int *types, const char **apns, +int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char **apns, int n_pdn_max) { LOG_FUNC_IN; @@ -770,7 +770,7 @@ int nas_proc_get_pdn_param(int *cids, int *types, const char **apns, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, +int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **addr1, const char **addr2, int n_pdn_max) { LOG_FUNC_IN; @@ -833,7 +833,7 @@ int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_set_pdn(int cid, int type, const char *apn, int ipv4_addr, +int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, int emergency, int p_cscf, int im_cn_signal) { LOG_FUNC_IN; @@ -871,7 +871,7 @@ int nas_proc_set_pdn(int cid, int type, const char *apn, int ipv4_addr, ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_reset_pdn(int cid) +int nas_proc_reset_pdn(nas_user_t *user, int cid) { LOG_FUNC_IN; @@ -905,7 +905,7 @@ int nas_proc_reset_pdn(int cid) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_deactivate_pdn(int cid) +int nas_proc_deactivate_pdn(nas_user_t *user, int cid) { LOG_FUNC_IN; @@ -913,7 +913,7 @@ int nas_proc_deactivate_pdn(int cid) if (cid > 0) { /* Deactivate only the specified PDN context */ - rc = _nas_proc_deactivate(cid, FALSE); + rc = _nas_proc_deactivate(user, cid, FALSE); } else { /* Do not deactivate the PDN connection established during initial * network attachment (identifier 1) */ @@ -921,7 +921,7 @@ int nas_proc_deactivate_pdn(int cid) /* Deactivate all active PDN contexts */ while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) { - rc = _nas_proc_deactivate(cid++, TRUE); + rc = _nas_proc_deactivate(user, cid++, TRUE); } } @@ -944,7 +944,7 @@ int nas_proc_deactivate_pdn(int cid) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_activate_pdn(int cid) +int nas_proc_activate_pdn(nas_user_t *user, int cid) { LOG_FUNC_IN; @@ -956,7 +956,7 @@ int nas_proc_activate_pdn(int cid) * procedure prior to attempt to request any PDN connectivity */ LOG_TRACE(WARNING, "NAS-PROC - UE is not attached to the network"); - rc = nas_proc_attach(); + rc = nas_proc_attach(user); } else if (emm_main_is_emergency()) { /* The UE is attached for emergency bearer services; It shall not * request a PDN connection to any other PDN */ @@ -967,13 +967,13 @@ int nas_proc_activate_pdn(int cid) if (rc != RETURNerror) { if (cid > 0) { /* Activate only the specified PDN context */ - rc = _nas_proc_activate(cid, FALSE); + rc = _nas_proc_activate(user, cid, FALSE); } else { cid = 1; /* Activate all defined PDN contexts */ while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) { - rc = _nas_proc_activate(cid++, TRUE); + rc = _nas_proc_activate(user, cid++, TRUE); } } } @@ -1056,7 +1056,7 @@ int nas_proc_cell_info(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t Ac ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_establish_cnf(const Byte_t *data, uint32_t len) +int nas_proc_establish_cnf(nas_user_t *user, const Byte_t *data, uint32_t len) { LOG_FUNC_IN; @@ -1093,7 +1093,7 @@ int nas_proc_establish_cnf(const Byte_t *data, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_establish_rej() +int nas_proc_establish_rej(nas_user_t *user) { LOG_FUNC_IN; @@ -1126,7 +1126,7 @@ int nas_proc_establish_rej() ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_release_ind(int cause) +int nas_proc_release_ind(nas_user_t *user, int cause) { LOG_FUNC_IN; @@ -1160,7 +1160,7 @@ int nas_proc_release_ind(int cause) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_ul_transfer_cnf() +int nas_proc_ul_transfer_cnf(nas_user_t *user) { LOG_FUNC_IN; @@ -1197,7 +1197,7 @@ int nas_proc_ul_transfer_cnf() ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_ul_transfer_rej() +int nas_proc_ul_transfer_rej(nas_user_t *user) { LOG_FUNC_IN; @@ -1234,7 +1234,7 @@ int nas_proc_ul_transfer_rej() ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_dl_transfer_ind(const Byte_t *data, uint32_t len) +int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) { LOG_FUNC_IN; @@ -1281,7 +1281,7 @@ int nas_proc_dl_transfer_ind(const Byte_t *data, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_activate(int cid, int apply_to_all) +static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) { LOG_FUNC_IN; @@ -1354,7 +1354,7 @@ static int _nas_proc_activate(int cid, int apply_to_all) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_deactivate(int cid, int apply_to_all) +static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index aaefe6f046..9efccb80ca 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -63,7 +63,7 @@ Description NAS procedure call manager void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *imei); -void nas_proc_cleanup(void); +void nas_proc_cleanup(nas_user_t *user); /* * -------------------------------------------------------------------------- @@ -80,30 +80,30 @@ int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi); int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp); -int nas_proc_register(int mode, int format, const network_plmn_t *oper, int AcT); -int nas_proc_deregister(void); -int nas_proc_get_reg_data(int *mode, int *selected, int format, +int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn_t *oper, int AcT); +int nas_proc_deregister(nas_user_t *user); +int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, network_plmn_t *oper, int *AcT); -int nas_proc_get_oper_list(const char **oper_list); +int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list); -int nas_proc_get_reg_status(int *stat); -int nas_proc_get_loc_info(char *tac, char *ci, int *AcT); +int nas_proc_get_reg_status(nas_user_t *user, int *stat); +int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT); -int nas_proc_detach(int switch_off); -int nas_proc_attach(void); -int nas_proc_get_attach_status(void); +int nas_proc_detach(nas_user_t *user, int switch_off); +int nas_proc_attach(nas_user_t *user); +int nas_proc_get_attach_status(nas_user_t *user); -int nas_proc_reset_pdn(int cid); -int nas_proc_set_pdn(int cid, int type, const char *apn, int ipv4_addr, +int nas_proc_reset_pdn(nas_user_t *user, int cid); +int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, int emergency, int p_cscf, int im_cn_signal); -int nas_proc_get_pdn_range(void); -int nas_proc_get_pdn_status(int *cids, int *states, int n_pdn_max); -int nas_proc_get_pdn_param(int *cids, int *types, const char **apns, +int nas_proc_get_pdn_range(nas_user_t *user); +int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max); +int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char **apns, int n_pdn_max); -int nas_proc_get_pdn_addr(int cid, int *cids, const char **addr1, +int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **addr1, const char **addr2, int n_addr_max); -int nas_proc_deactivate_pdn(int cid); -int nas_proc_activate_pdn(int cid); +int nas_proc_deactivate_pdn(nas_user_t *user, int cid); +int nas_proc_activate_pdn(nas_user_t *user, int cid); /* * -------------------------------------------------------------------------- @@ -114,14 +114,14 @@ int nas_proc_activate_pdn(int cid); int nas_proc_cell_info(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat, uint8_t rsrp, uint8_t rsrq); -int nas_proc_establish_cnf(const Byte_t *data, uint32_t len); -int nas_proc_establish_rej(void); +int nas_proc_establish_cnf(nas_user_t *user, const Byte_t *data, uint32_t len); +int nas_proc_establish_rej(nas_user_t *user); -int nas_proc_release_ind(int cause); +int nas_proc_release_ind(nas_user_t *user, int cause); -int nas_proc_ul_transfer_cnf(void); -int nas_proc_ul_transfer_rej(void); -int nas_proc_dl_transfer_ind(const Byte_t *data, uint32_t len); +int nas_proc_ul_transfer_cnf(nas_user_t *user); +int nas_proc_ul_transfer_rej(nas_user_t *user); +int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len); diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 85606d2a4c..78fc49e682 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -163,7 +163,7 @@ void *nas_ue_task(void *args_p) if ((NAS_CONN_ESTABLI_CNF (msg_p).errCode == AS_SUCCESS) || (NAS_CONN_ESTABLI_CNF (msg_p).errCode == AS_TERMINATED_NAS)) { - nas_proc_establish_cnf(NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); + nas_proc_establish_cnf(user, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.data, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); /* TODO checks if NAS will free the nas message, better to do it there anyway! */ // result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data); @@ -176,7 +176,7 @@ void *nas_ue_task(void *args_p) LOG_I(NAS, "[UE %d] Received %s: cause %u\n", Mod_id, msg_name, NAS_CONN_RELEASE_IND (msg_p).cause); - nas_proc_release_ind (NAS_CONN_RELEASE_IND (msg_p).cause); + nas_proc_release_ind (user, NAS_CONN_RELEASE_IND (msg_p).cause); break; case NAS_UPLINK_DATA_CNF: @@ -184,9 +184,9 @@ void *nas_ue_task(void *args_p) NAS_UPLINK_DATA_CNF (msg_p).UEid, NAS_UPLINK_DATA_CNF (msg_p).errCode); if (NAS_UPLINK_DATA_CNF (msg_p).errCode == AS_SUCCESS) { - nas_proc_ul_transfer_cnf (); + nas_proc_ul_transfer_cnf (user); } else { - nas_proc_ul_transfer_rej (); + nas_proc_ul_transfer_rej (user); } break; @@ -195,7 +195,7 @@ void *nas_ue_task(void *args_p) LOG_I(NAS, "[UE %d] Received %s: UEid %u, length %u\n", Mod_id, msg_name, NAS_DOWNLINK_DATA_IND (msg_p).UEid, NAS_DOWNLINK_DATA_IND (msg_p).nasMsg.length); - nas_proc_dl_transfer_ind (NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length); + nas_proc_dl_transfer_ind (user, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length); if (0) { /* TODO checks if NAS will free the nas message, better to do it there anyway! */ diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 0b7b6627a8..9bdb720678 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -1168,7 +1168,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNerror) { if (mode == AT_COPS_DEREG) { /* Force an attempt to deregister from the network */ - ret_code = nas_proc_deregister(); + ret_code = nas_proc_deregister(user); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Network deregistration failed"); @@ -1178,7 +1178,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) } else if (mode != AT_COPS_FORMAT) { /* Force an attempt to automatically/manualy select * and register the GSM/UMTS/EPS network operator */ - ret_code = nas_proc_register(mode, format, + ret_code = nas_proc_register(user, mode, format, &data->command.cops.plmn, AcT); if (ret_code != RETURNok) { @@ -1198,7 +1198,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) */ /* Get the current network registration data */ - ret_code = nas_proc_get_reg_data(&mode, + ret_code = nas_proc_get_reg_data(user, &mode, &oper_is_selected, read_format, &cops->get.plmn, &cops->get.AcT); @@ -1236,7 +1236,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) * Test command returns a set of parameters, each representing * an operator present in the network. */ - cops->tst.size = nas_proc_get_oper_list(&cops->tst.data); + cops->tst.size = nas_proc_get_oper_list(user, &cops->tst.data); break; default: @@ -1308,9 +1308,9 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) ret_code = RETURNerror; if (data->command.cgatt.state == AT_CGATT_ATTACHED) { - ret_code = nas_proc_attach(); + ret_code = nas_proc_attach(user); } else if (data->command.cgatt.state == AT_CGATT_DETACHED) { - ret_code = nas_proc_detach(FALSE); + ret_code = nas_proc_detach(user, FALSE); } if (ret_code != RETURNok) { @@ -1328,7 +1328,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) /* * Read command returns the current EPS service state. */ - if (nas_proc_get_attach_status() != TRUE) { + if (nas_proc_get_attach_status(user) != TRUE) { cgatt->state = AT_CGATT_DETACHED; } else { cgatt->state = AT_CGATT_ATTACHED; @@ -1474,7 +1474,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) case AT_CREG_OFF: case AT_CREG_ON: /* Get network registration status */ - ret_code = nas_proc_get_reg_status(&creg->stat); + ret_code = nas_proc_get_reg_status(user, &creg->stat); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); @@ -1623,7 +1623,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) case AT_CGREG_OFF: case AT_CGREG_ON: /* Get network registration status */ - ret_code = nas_proc_get_reg_status(&cgreg->stat); + ret_code = nas_proc_get_reg_status(user, &cgreg->stat); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); @@ -1776,7 +1776,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) switch (n) { case AT_CEREG_BOTH: /* Get EPS location information */ - ret_code = nas_proc_get_loc_info(cereg->tac, cereg->ci, + ret_code = nas_proc_get_loc_info(user, cereg->tac, cereg->ci, &cereg->AcT); if (ret_code != RETURNok) { @@ -1799,7 +1799,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) case AT_CEREG_OFF: case AT_CEREG_ON: /* Get network registration status */ - ret_code = nas_proc_get_reg_status(&cereg->stat); + ret_code = nas_proc_get_reg_status(user, &cereg->stat); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); @@ -2022,10 +2022,10 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) if (reset_pdn) { /* A special form of the set command, +CGDCONT= causes * the values for context number to become undefined */ - ret_code = nas_proc_reset_pdn(cid); + ret_code = nas_proc_reset_pdn(user, cid); } else { /* Define a new PDN connection */ - ret_code = nas_proc_set_pdn(cid, pdn_type, apn, + ret_code = nas_proc_set_pdn(user, cid, pdn_type, apn, ipv4_addr_allocation, emergency, p_cscf, im_cn_signalling); } @@ -2043,7 +2043,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) * Read command returns the current settings for each * defined PDN connection/default EPS bearer context */ - cgdcont->n_pdns = nas_proc_get_pdn_param(cgdcont->cid, + cgdcont->n_pdns = nas_proc_get_pdn_param(user, cgdcont->cid, cgdcont->PDP_type, cgdcont->APN, AT_CGDCONT_RESP_SIZE); @@ -2061,7 +2061,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) */ { /* Get the maximum value of a PDN context identifier */ - int cid_max = nas_proc_get_pdn_range(); + int cid_max = nas_proc_get_pdn_range(user); if (cid_max > AT_CGDCONT_RESP_SIZE) { /* The range is defined by the user interface */ @@ -2164,9 +2164,9 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) ret_code = RETURNerror; if (state == AT_CGACT_DEACTIVATED) { - ret_code = nas_proc_deactivate_pdn(cid); + ret_code = nas_proc_deactivate_pdn(user, cid); } else if (state == AT_CGACT_ACTIVATED) { - ret_code = nas_proc_activate_pdn(cid); + ret_code = nas_proc_activate_pdn(user, cid); } if (ret_code != RETURNok) { @@ -2184,7 +2184,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) * The read command returns the current activation states for * all the defined PDN/EPS bearer contexts */ - cgact->n_pdns = nas_proc_get_pdn_status(cgact->cid, cgact->state, + cgact->n_pdns = nas_proc_get_pdn_status(user, cgact->cid, cgact->state, AT_CGACT_RESP_SIZE); if (cgact->n_pdns == 0) { @@ -2517,7 +2517,7 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) /* * Get the PDP addresses */ - cgpaddr->n_pdns = nas_proc_get_pdn_addr(cid, cgpaddr->cid, + cgpaddr->n_pdns = nas_proc_get_pdn_addr(user, cid, cgpaddr->cid, cgpaddr->PDP_addr_1, cgpaddr->PDP_addr_2, AT_CGPADDR_RESP_SIZE); @@ -2533,7 +2533,7 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) /* * The test command returns a list of defined s. */ - cgpaddr->n_pdns = nas_proc_get_pdn_addr(cid, cgpaddr->cid, + cgpaddr->n_pdns = nas_proc_get_pdn_addr(user, cid, cgpaddr->cid, cgpaddr->PDP_addr_1, cgpaddr->PDP_addr_2, AT_CGPADDR_RESP_SIZE); From 4742178aeeb0f5ce49ca0f00f3961db98225b8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 6 Jul 2016 08:19:23 +0200 Subject: [PATCH 140/571] UE/ESM: Make _esm_data a pointer instance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds esm_data_t parameter to ESM functions. This fixes a bug where the old _esm_data was redefined in all .o Signed-off-by: Frédéric Leroy --- .../ESM/DedicatedEpsBearerContextActivation.c | 10 +- .../ESM/DefaultEpsBearerContextActivation.c | 10 +- .../NAS/UE/ESM/EpsBearerContextDeactivation.c | 28 ++-- openair3/NAS/UE/ESM/PdnConnectivity.c | 134 +++++++++--------- openair3/NAS/UE/ESM/PdnDisconnect.c | 33 ++--- openair3/NAS/UE/ESM/SAP/esm_recv.c | 20 +-- openair3/NAS/UE/ESM/SAP/esm_recv.h | 10 +- openair3/NAS/UE/ESM/SAP/esm_sap.c | 35 ++--- openair3/NAS/UE/ESM/esmData.h | 2 +- openair3/NAS/UE/ESM/esm_ebr_context.c | 24 ++-- openair3/NAS/UE/ESM/esm_ebr_context.h | 8 +- openair3/NAS/UE/ESM/esm_main.c | 107 +++++++------- openair3/NAS/UE/ESM/esm_main.h | 17 +-- openair3/NAS/UE/ESM/esm_proc.h | 18 +-- openair3/NAS/UE/nas_proc.c | 38 ++--- openair3/NAS/UE/nas_proc.h | 7 +- openair3/NAS/UE/nas_user.c | 6 +- 17 files changed, 258 insertions(+), 249 deletions(-) diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 21e54fd2d0..0ce27b1fcf 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -104,7 +104,7 @@ Description Defines the dedicated EPS bearer context activation ESM ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, +int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause) @@ -117,7 +117,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, "requested by the network (ebi=%d)", ebi); /* Get the PDN connection the dedicated EPS bearer is linked to */ - int pid = esm_ebr_context_get_pid(default_ebi); + int pid = esm_ebr_context_get_pid(esm_data, default_ebi); if (pid < 0) { /* 3GPP TS 24.301, section 6.4.2.5, abnormal case c @@ -141,7 +141,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested dedicated EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -155,7 +155,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, if (ebi != ESM_EBI_UNASSIGNED) { /* Check syntactical errors in packet filters */ - rc = esm_ebr_context_check_tft(pid, ebi, tft, + rc = esm_ebr_context_check_tft(esm_data, pid, ebi, tft, ESM_EBR_CONTEXT_TFT_CREATE); if (rc != RETURNok) { @@ -165,7 +165,7 @@ int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, *esm_cause = ESM_CAUSE_SYNTACTICAL_ERROR_IN_PACKET_FILTER; } else { /* Create new dedicated EPS bearer context */ - default_ebi = esm_ebr_context_create(pid, ebi, FALSE, qos, tft); + default_ebi = esm_ebr_context_create(esm_data, pid, ebi, FALSE, qos, tft); if (default_ebi != ESM_EBI_UNASSIGNED) { /* Dedicated EPS bearer contextx successfully created */ diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 82c4e51be8..0d1a307c96 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -104,7 +104,7 @@ static struct { ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_request(int pid, int ebi, +int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, int ebi, const esm_proc_qos_t *qos, int *esm_cause) { @@ -126,7 +126,7 @@ int esm_proc_default_eps_bearer_context_request(int pid, int ebi, int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested default EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -140,7 +140,7 @@ int esm_proc_default_eps_bearer_context_request(int pid, int ebi, if (ebi != ESM_EBI_UNASSIGNED) { /* Create new default EPS bearer context */ - ebi = esm_ebr_context_create(pid, ebi, TRUE, qos, NULL); + ebi = esm_ebr_context_create(esm_data, pid, ebi, TRUE, qos, NULL); if (ebi != ESM_EBI_UNASSIGNED) { /* Default EPS bearer contextx successfully created */ @@ -346,7 +346,7 @@ int esm_proc_default_eps_bearer_context_complete(void) ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_failure(void) +int esm_proc_default_eps_bearer_context_failure(esm_data_t *esm_data) { LOG_FUNC_IN; @@ -357,7 +357,7 @@ int esm_proc_default_eps_bearer_context_failure(void) "ESM-PROC - Default EPS bearer context activation failure"); /* Release the default EPS bearer context and enter state INACTIVE */ - int rc = esm_proc_eps_bearer_context_deactivate(TRUE, ebi, &pid, &bid); + int rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi, &pid, &bid); if (rc != RETURNerror) { /* Reset default EPS bearer context internal data */ diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index 774c80e97f..21aaeb262a 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -74,7 +74,7 @@ Description Defines the EPS bearer context deactivation ESM procedure * in the UE * -------------------------------------------------------------------------- */ -static int _eps_bearer_release(int ebi, int *pid, int *bid); +static int _eps_bearer_release(esm_data_t *esm_data, int ebi, int *pid, int *bid); /****************************************************************************/ @@ -112,7 +112,7 @@ static int _eps_bearer_release(int ebi, int *pid, int *bid); ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, +int esm_proc_eps_bearer_context_deactivate(esm_data_t *esm_data, int is_local, int ebi, int *pid, int *bid) { LOG_FUNC_IN; @@ -123,14 +123,14 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, if (is_local) { if (ebi != ESM_SAP_ALL_EBI) { /* Locally release the EPS bearer context */ - rc = _eps_bearer_release(ebi, pid, bid); + rc = _eps_bearer_release(esm_data, ebi, pid, bid); } else { /* Locally release all the EPS bearer contexts */ *bid = 0; for (*pid = 0; *pid < ESM_DATA_PDN_MAX; (*pid)++) { - if (_esm_data.pdn[*pid].data) { - rc = _eps_bearer_release(ESM_EBI_UNASSIGNED, pid, bid); + if (esm_data->pdn[*pid].data) { + rc = _eps_bearer_release(esm_data, ESM_EBI_UNASSIGNED, pid, bid); if (rc != RETURNok) { break; @@ -146,17 +146,17 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, ebi); if (*pid < ESM_DATA_PDN_MAX) { - if (_esm_data.pdn[*pid].pid != *pid) { + if (esm_data->pdn[*pid].pid != *pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier %d " "is not valid", *pid); - } else if (_esm_data.pdn[*pid].data == NULL) { + } else if (esm_data->pdn[*pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection %d has not been " "allocated", *pid); - } else if (!_esm_data.pdn[*pid].is_active) { + } else if (!esm_data->pdn[*pid].is_active) { LOG_TRACE(WARNING, "ESM-PROC - PDN connection %d is not active", *pid); } else { - esm_pdn_t *pdn = _esm_data.pdn[*pid].data; + esm_pdn_t *pdn = esm_data->pdn[*pid].data; for (i = 0; i < pdn->n_bearers; i++) { if (pdn->bearer[i]->ebi != ebi) { @@ -189,7 +189,7 @@ int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause) +int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi, int *esm_cause) { LOG_FUNC_IN; @@ -200,7 +200,7 @@ int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause) "requested by the network (ebi=%d)", ebi); /* Release the EPS bearer context entry */ - if (esm_ebr_context_release(ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) { + if (esm_ebr_context_release(esm_data, ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; LOG_FUNC_RETURN (RETURNerror); @@ -222,7 +222,7 @@ int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause) "connection reactivation"); /* Get PDN context parameters */ - rc = esm_main_get_pdn(pid + 1, &esm_sap.data.pdn_connect.pdn_type, + rc = esm_main_get_pdn(esm_data, pid + 1, &esm_sap.data.pdn_connect.pdn_type, &esm_sap.data.pdn_connect.apn, &esm_sap.data.pdn_connect.is_emergency, &active); @@ -352,14 +352,14 @@ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, ** Others: None ** ** ** ***************************************************************************/ -static int _eps_bearer_release(int ebi, int *pid, int *bid) +static int _eps_bearer_release(esm_data_t *esm_data, int ebi, int *pid, int *bid) { LOG_FUNC_IN; int rc = RETURNerror; /* Release the EPS bearer context entry */ - ebi = esm_ebr_context_release(ebi, pid, bid); + ebi = esm_ebr_context_release(esm_data, ebi, pid, bid); if (ebi == ESM_EBI_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 2d8718b0a3..46be3fef14 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -81,15 +81,15 @@ Description Defines the PDN connectivity ESM procedure executed by the /* * PDN connection handlers */ -static int _pdn_connectivity_create(int pid, const OctetString *apn, +static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, int is_emergency); -static int _pdn_connectivity_update(int pid, const OctetString *apn, +static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, int esm_cause); -static int _pdn_connectivity_delete(int pid); +static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid); -static int _pdn_connectivity_set_pti(int pid, int pti); -static int _pdn_connectivity_find_apn(const OctetString *apn); -static int _pdn_connectivity_find_pdn(const OctetString *apn, +static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti); +static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *apn); +static int _pdn_connectivity_find_pdn(esm_data_t * esm_data, const OctetString *apn, esm_proc_pdn_type_t pdn_type); /* @@ -134,7 +134,7 @@ static void *_pdn_connectivity_t3482_handler(void *); ** Others: _esm_data ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity(int cid, int is_to_define, +int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define, esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, unsigned int *pti) @@ -147,7 +147,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, if (!is_to_define) { LOG_TRACE(INFO, "ESM-PROC - Undefine PDN connection (cid=%d)", cid); /* Delete the PDN connection entry */ - int pti = _pdn_connectivity_delete(pid); + int pti = _pdn_connectivity_delete(esm_data, pid); if (pti != ESM_PT_UNASSIGNED) { /* Release the procedure transaction data */ @@ -168,7 +168,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, } /* Update the PDN connection data */ - rc = _pdn_connectivity_set_pti(pid, *pti); + rc = _pdn_connectivity_set_pti(esm_data, pid, *pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection"); @@ -182,14 +182,14 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, (pdn_type == ESM_PDN_TYPE_IPV6)? "IPv6" : "IPv4v6", apn->value, cid); - if (is_emergency && _esm_data.emergency) { + if (is_emergency && esm_data->emergency) { /* The UE shall not request additional PDN connection for * emergency bearer services */ LOG_TRACE(WARNING, "ESM-PROC - PDN connection for emergency bearer " "services is already active"); LOG_FUNC_RETURN (RETURNerror); } else if (pid < ESM_DATA_PDN_MAX) { - if ((pid == _esm_data.pdn[pid].pid) && (_esm_data.pdn[pid].is_active)) { + if ((pid == esm_data->pdn[pid].pid) && (esm_data->pdn[pid].is_active)) { /* PDN connection with the specified identifier is active */ LOG_TRACE(WARNING, "ESM-PROC - PDN connection is active"); LOG_FUNC_RETURN (RETURNerror); @@ -201,15 +201,15 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, if (apn && apn->length > 0) { /* The UE requested subsequent connectivity to additionnal PDNs */ - int pid = _pdn_connectivity_find_apn(apn); + int pid = _pdn_connectivity_find_apn(esm_data, apn); - if ( (pid >= 0) && _esm_data.pdn[pid].is_active ) { + if ( (pid >= 0) && esm_data->pdn[pid].is_active ) { /* An active PDN connection to this APN already exists */ - if ( (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) && - (_esm_data.pdn[pid].data->type != pdn_type) ) { + if ( (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) && + (esm_data->pdn[pid].data->type != pdn_type) ) { /* The UE is requesting PDN connection for other IP version * than the one already activated */ - if (!_esm_data.pdn[pid].data->addr_realloc) { + if (!esm_data->pdn[pid].data->addr_realloc) { /* The network does not allow PDN connectivity using * IPv4 and IPv6 address versions to the same APN */ if (pdn_type != ESM_PDN_TYPE_IPV4V6) { @@ -220,7 +220,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, } else { LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " "already exists", - (_esm_data.pdn[pid].data->type != + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? "IPv6" : "IPv4", apn->value); } @@ -232,8 +232,8 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, * same IP version than the one already activated */ LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " "already exists", - (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? - (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV6)? + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV6)? "IPv4v6" : "IPv6" : "IPv4", apn->value); LOG_FUNC_RETURN (RETURNerror); } @@ -248,7 +248,7 @@ int esm_proc_pdn_connectivity(int cid, int is_to_define, * not already established, or may have been allowed to request PDN * connectivity for other IP version than the one already activated */ - rc = _pdn_connectivity_create(pid, apn, pdn_type, is_emergency); + rc = _pdn_connectivity_create(esm_data, pid, apn, pdn_type, is_emergency); LOG_FUNC_RETURN(rc); } @@ -346,7 +346,7 @@ int esm_proc_pdn_connectivity_request(int is_standalone, int pti, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, +int esm_proc_pdn_connectivity_accept(esm_data_t *esm_data, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, const OctetString *apn, int *esm_cause) { @@ -391,7 +391,7 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, */ /* Check whether a PDN connection exists to this APN */ - pid = _pdn_connectivity_find_pdn(apn, pdn_type); + pid = _pdn_connectivity_find_pdn(esm_data, apn, pdn_type); if (pid < 0) { /* No any PDN connection has been defined to establish connectivity @@ -403,7 +403,7 @@ int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, } /* Update the PDN connection */ - rc = _pdn_connectivity_update(pid, apn, pdn_type, pdn_addr, *esm_cause); + rc = _pdn_connectivity_update(esm_data, pid, apn, pdn_type, pdn_addr, *esm_cause); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection " @@ -683,7 +683,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_create(int pid, const OctetString *apn, +static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, int is_emergency) { @@ -693,14 +693,14 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn, if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); return (RETURNerror); } - if (_esm_data.pdn[pid].data != NULL) { + if (esm_data->pdn[pid].data != NULL) { /* Update existing non-active PDN connection */ - pdn = _esm_data.pdn[pid].data; + pdn = esm_data->pdn[pid].data; } else { /* Create new PDN connection */ pdn = (esm_pdn_t *)malloc(sizeof(esm_pdn_t)); @@ -713,13 +713,13 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn, memset(pdn, 0, sizeof(esm_pdn_t)); /* Increment the number of PDN connections */ - _esm_data.n_pdns += 1; + esm_data->n_pdns += 1; /* Set the PDN connection identifier */ - _esm_data.pdn[pid].pid = pid; + esm_data->pdn[pid].pid = pid; /* Reset the PDN connection active indicator */ - _esm_data.pdn[pid].is_active = FALSE; + esm_data->pdn[pid].is_active = FALSE; /* Setup the PDN connection data */ - _esm_data.pdn[pid].data = pdn; + esm_data->pdn[pid].data = pdn; } /* Update the PDN connection data */ @@ -763,7 +763,7 @@ static int _pdn_connectivity_create(int pid, const OctetString *apn, ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_update(int pid, const OctetString *apn, +static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, int esm_cause) @@ -772,21 +772,21 @@ static int _pdn_connectivity_update(int pid, const OctetString *apn, if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); return (RETURNerror); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); return (RETURNerror); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(WARNING, "ESM-PROC - Active %s PDN connection to %s already " - "exists", (_esm_data.pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? - "IPv6" : "IPv4", _esm_data.pdn[pid].data->apn.value); + "exists", (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? + "IPv6" : "IPv4", esm_data->pdn[pid].data->apn.value); return (RETURNerror); } /* Get the PDN connection */ - esm_pdn_t *pdn = _esm_data.pdn[pid].data; + esm_pdn_t *pdn = esm_data->pdn[pid].data; /* Setup the Access Point Name value */ if ( apn && (apn->length > 0) ) { @@ -857,39 +857,39 @@ static int _pdn_connectivity_update(int pid, const OctetString *apn, ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_delete(int pid) +static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid) { int pti = ESM_PT_UNASSIGNED; if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); } else { /* Get the identity of the procedure transaction that created * the PDN connection */ - pti = _esm_data.pdn[pid].data->pti; + pti = esm_data->pdn[pid].data->pti; } } if (pti != ESM_PT_UNASSIGNED) { /* Decrement the number of PDN connections */ - _esm_data.n_pdns -= 1; + esm_data->n_pdns -= 1; /* Set the PDN connection as available */ - _esm_data.pdn[pid].pid = -1; + esm_data->pdn[pid].pid = -1; /* Release allocated PDN connection data */ - if (_esm_data.pdn[pid].data->apn.length > 0) { - free(_esm_data.pdn[pid].data->apn.value); + if (esm_data->pdn[pid].data->apn.length > 0) { + free(esm_data->pdn[pid].data->apn.value); } - free(_esm_data.pdn[pid].data); - _esm_data.pdn[pid].data = NULL; + free(esm_data->pdn[pid].data); + esm_data->pdn[pid].data = NULL; LOG_TRACE(WARNING, "ESM-PROC - PDN connection %d released", pid); } @@ -913,21 +913,21 @@ static int _pdn_connectivity_delete(int pid) ** Others: _esm_data ** ** ** ***************************************************************************/ -static int _pdn_connectivity_set_pti(int pid, int pti) +static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti) { if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); - } else if (_esm_data.pdn[pid].is_active) { + } else if (esm_data->pdn[pid].is_active) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); } else { /* Update the identity of the procedure transaction assigned to * the PDN connection */ - _esm_data.pdn[pid].data->pti = pti; + esm_data->pdn[pid].data->pti = pti; return (RETURNok); } } @@ -951,17 +951,17 @@ static int _pdn_connectivity_set_pti(int pid, int pti) ** Others: None ** ** ** ***************************************************************************/ -static int _pdn_connectivity_find_apn(const OctetString *apn) +static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *apn) { int i; for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) { - if (_esm_data.pdn[i].data->apn.length != apn->length) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { + if (esm_data->pdn[i].data->apn.length != apn->length) { continue; } - if (memcmp(_esm_data.pdn[i].data->apn.value, + if (memcmp(esm_data->pdn[i].data->apn.value, apn->value, apn->length) != 0) { continue; } @@ -972,7 +972,7 @@ static int _pdn_connectivity_find_apn(const OctetString *apn) } /* Return the identifier of the PDN connection */ - return (_esm_data.pdn[i].pid); + return (esm_data->pdn[i].pid); } /**************************************************************************** @@ -992,38 +992,38 @@ static int _pdn_connectivity_find_apn(const OctetString *apn) ** Others: None ** ** ** ***************************************************************************/ -static int _pdn_connectivity_find_pdn(const OctetString *apn, +static int _pdn_connectivity_find_pdn(esm_data_t *esm_data, const OctetString *apn, const esm_proc_pdn_type_t pdn_type) { int i; for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { /* PDN connection established during initial network attachment */ - if (_esm_data.pdn[i].data->apn.length == 0) { + if (esm_data->pdn[i].data->apn.length == 0) { break; } /* Subsequent PDN connection established for the specified APN */ - if (_esm_data.pdn[i].data->apn.length != apn->length) { + if (esm_data->pdn[i].data->apn.length != apn->length) { continue; } - if (memcmp(_esm_data.pdn[i].data->apn.value, + if (memcmp(esm_data->pdn[i].data->apn.value, apn->value, apn->length) != 0) { continue; } - if (_esm_data.pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) { + if (esm_data->pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) { break; } - if (_esm_data.pdn[i].data->type == pdn_type) { + if (esm_data->pdn[i].data->type == pdn_type) { break; } } } /* Return the identifier of the PDN connection */ - return (_esm_data.pdn[i].pid); + return (esm_data->pdn[i].pid); } diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 3cb2f56385..082463aa46 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -73,7 +73,7 @@ Description Defines the PDN disconnect ESM procedure executed by the /* * PDN disconnection handlers */ -static int _pdn_disconnect_get_default_ebi(int pti); +static int _pdn_disconnect_get_default_ebi(esm_data_t *esm_data, int pti); /* * Timer handlers @@ -114,7 +114,7 @@ static void *_pdn_disconnect_t3492_handler(void *); ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi) +int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi) { LOG_FUNC_IN; @@ -122,21 +122,21 @@ int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi) int pid = cid - 1; if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-PROC - PDN connection identifier %d is " "not valid", pid); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection %d has not been " "allocated", pid); - } else if (!_esm_data.pdn[pid].is_active) { + } else if (!esm_data->pdn[pid].is_active) { LOG_TRACE(WARNING, "ESM-PROC - PDN connection is not active"); } else { /* Get the procedure transaction identity assigned to the PDN * connection to be released */ - *pti = _esm_data.pdn[pid].data->pti; + *pti = esm_data->pdn[pid].data->pti; /* Get the EPS bearer identity of the default bearer associated * with the PDN to disconnect from */ - *ebi = _esm_data.pdn[pid].data->bearer[0]->ebi; + *ebi = esm_data->pdn[pid].data->bearer[0]->ebi; rc = RETURNok; } } @@ -284,7 +284,7 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) +int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause) { LOG_FUNC_IN; @@ -313,7 +313,7 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) } else if (*esm_cause != ESM_CAUSE_LAST_PDN_DISCONNECTION_NOT_ALLOWED) { /* Get the identity of the default EPS bearer context allocated to * the PDN connection entry assigned to this procedure transaction */ - int ebi = _pdn_disconnect_get_default_ebi(pti); + int ebi = _pdn_disconnect_get_default_ebi(esm_data, pti); if (ebi < 0) { LOG_TRACE(ERROR, "ESM-PROC - No default EPS bearer found"); @@ -382,7 +382,8 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause) static void *_pdn_disconnect_t3492_handler(void *args) { LOG_FUNC_IN; - + // FIXME check callback call + esm_data_t *esm_data = args;; int rc; /* Get retransmission timer parameters data */ @@ -431,7 +432,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) /* Get the identity of the default EPS bearer context * allocated to the PDN connection entry assigned to * this procedure transaction */ - int ebi = _pdn_disconnect_get_default_ebi(data->pti); + int ebi = _pdn_disconnect_get_default_ebi(esm_data, data->pti); if (ebi < 0) { LOG_TRACE(ERROR, "ESM-PROC - No default EPS bearer found"); @@ -479,22 +480,22 @@ static void *_pdn_disconnect_t3492_handler(void *args) ** Others: None ** ** ** ***************************************************************************/ -static int _pdn_disconnect_get_default_ebi(int pti) +static int _pdn_disconnect_get_default_ebi(esm_data_t *esm_data, int pti) { int ebi = -1; int i; for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (_esm_data.pdn[i].pid != -1) && _esm_data.pdn[i].data ) { - if (_esm_data.pdn[i].data->pti != pti) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { + if (esm_data->pdn[i].data->pti != pti) { continue; } /* PDN entry found */ - if (_esm_data.pdn[i].data->bearer[0] != NULL) { + if (esm_data->pdn[i].data->bearer[0] != NULL) { /* Get the EPS bearer identity of the default EPS bearer * context associated to the PDN connection */ - ebi = _esm_data.pdn[i].data->bearer[0]->ebi; + ebi = esm_data->pdn[i].data->bearer[0]->ebi; } break; diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.c b/openair3/NAS/UE/ESM/SAP/esm_recv.c index 243d619896..63262c6829 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.c +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.c @@ -135,7 +135,7 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg) ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_pdn_connectivity_reject(int pti, int ebi, +int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi, const pdn_connectivity_reject_msg *msg) { LOG_FUNC_IN; @@ -206,7 +206,7 @@ int esm_recv_pdn_connectivity_reject(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_pdn_disconnect_reject(int pti, int ebi, +int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi, const pdn_disconnect_reject_msg *msg) { LOG_FUNC_IN; @@ -250,7 +250,7 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi, esm_cause = msg->esmcause; /* Execute the PDN disconnect procedure not accepted by the network */ - int rc = esm_proc_pdn_disconnect_reject(pti, &esm_cause); + int rc = esm_proc_pdn_disconnect_reject(esm_data, pti, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; @@ -278,7 +278,7 @@ int esm_recv_pdn_disconnect_reject(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, const activate_default_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; @@ -369,14 +369,14 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, } /* Execute the PDN connectivity procedure accepted by the network */ - int pid = esm_proc_pdn_connectivity_accept(pti, pdn_type, + int pid = esm_proc_pdn_connectivity_accept(esm_data, pti, pdn_type, &msg->pdnaddress.pdnaddressinformation, &msg->accesspointname.accesspointnamevalue, &esm_cause); if (pid != RETURNerror) { /* Create local default EPS bearer context */ - int rc = esm_proc_default_eps_bearer_context_request(pid, ebi, &qos, + int rc = esm_proc_default_eps_bearer_context_request(esm_data, pid, ebi, &qos, &esm_cause); if (rc != RETURNerror) { @@ -406,7 +406,7 @@ int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, const activate_dedicated_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; @@ -580,7 +580,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, } /* Execute the dedicated EPS bearer context activation procedure */ - int rc = esm_proc_dedicated_eps_bearer_context_request(ebi, + int rc = esm_proc_dedicated_eps_bearer_context_request(esm_data, ebi, msg->linkedepsbeareridentity, &qos, &tft, &esm_cause); @@ -614,7 +614,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, +int esm_recv_deactivate_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, const deactivate_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; @@ -670,7 +670,7 @@ int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, if (rc != RETURNerror) { /* Execute the EPS bearer context deactivation procedure */ - rc = esm_proc_eps_bearer_context_deactivate_request(ebi, &esm_cause); + rc = esm_proc_eps_bearer_context_deactivate_request(esm_data, ebi, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.h b/openair3/NAS/UE/ESM/SAP/esm_recv.h index db65230e1e..f1641bd939 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.h +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.h @@ -88,23 +88,23 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg); * Transaction related messages * ---------------------------- */ -int esm_recv_pdn_connectivity_reject(int pti, int ebi, +int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi, const pdn_connectivity_reject_msg *msg); -int esm_recv_pdn_disconnect_reject(int pti, int ebi, +int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi, const pdn_disconnect_reject_msg *msg); /* * Messages related to EPS bearer contexts * --------------------------------------- */ -int esm_recv_activate_default_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, const activate_default_eps_bearer_context_request_msg *msg); -int esm_recv_activate_dedicated_eps_bearer_context_request(int pti, int ebi, +int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, const activate_dedicated_eps_bearer_context_request_msg *msg); -int esm_recv_deactivate_eps_bearer_context_request(int pti, int ebi, +int esm_recv_deactivate_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, const deactivate_eps_bearer_context_request_msg *msg); diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index 5ead95d5b4..ca9e0c2c6f 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -63,7 +63,8 @@ Description Defines the ESM Service Access Points at which the EPS /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -static int _esm_sap_recv(int msg_type, int is_standalone, +// FIXME NOT SURE FOR THIS ONE +static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err); static int _esm_sap_send(int msg_type, int is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp); @@ -147,6 +148,8 @@ void esm_sap_initialize(void) int esm_sap_send(esm_sap_t *msg) { LOG_FUNC_IN; + // FIXME + esm_data_t *esm_data = _esm_data; int rc = RETURNerror; int pid; @@ -172,7 +175,7 @@ int esm_sap_send(esm_sap_t *msg) } /* Define new PDN context */ - rc = esm_proc_pdn_connectivity(pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, TRUE, pdn_connect->pdn_type, &apn, pdn_connect->is_emergency, NULL); @@ -184,7 +187,7 @@ int esm_sap_send(esm_sap_t *msg) if (pdn_connect->is_defined) { unsigned int pti; /* Assign new procedure transaction identity */ - rc = esm_proc_pdn_connectivity(pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, TRUE, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, &pti); @@ -206,12 +209,12 @@ int esm_sap_send(esm_sap_t *msg) if ( msg->is_standalone && pdn_connect->is_defined ) { /* Undefine the specified PDN context */ - rc = esm_proc_pdn_connectivity(pdn_connect->cid, FALSE, + rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, FALSE, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, NULL); } else if (msg->recv != NULL) { /* The UE received a PDN connectivity reject message */ - rc = _esm_sap_recv(PDN_CONNECTIVITY_REJECT, msg->is_standalone, + rc = _esm_sap_recv(esm_data, PDN_CONNECTIVITY_REJECT, msg->is_standalone, msg->recv, &msg->send, &msg->err); } else { /* The PDN connectivity procedure locally failed */ @@ -226,7 +229,7 @@ int esm_sap_send(esm_sap_t *msg) /* Get the procedure transaction identity and the EPS bearer * identity of the default bearer assigned to the PDN to * disconnect from */ - rc = esm_proc_pdn_disconnect(msg->data.pdn_disconnect.cid, + rc = esm_proc_pdn_disconnect(esm_data, msg->data.pdn_disconnect.cid, &pti, &ebi); if (rc != RETURNerror) { @@ -254,7 +257,7 @@ int esm_sap_send(esm_sap_t *msg) case ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ: /* The UE received activate default ESP bearer context request */ - rc = _esm_sap_recv(ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, + rc = _esm_sap_recv(esm_data, ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, msg->is_standalone, msg->recv, &msg->send, &msg->err); break; @@ -276,7 +279,7 @@ int esm_sap_send(esm_sap_t *msg) /* * Default ESP bearer context activation procedure locally failed */ - rc = esm_proc_default_eps_bearer_context_failure(); + rc = esm_proc_default_eps_bearer_context_failure(esm_data); if (rc != RETURNerror) { rc = esm_proc_pdn_connectivity_failure(FALSE); @@ -307,7 +310,7 @@ int esm_sap_send(esm_sap_t *msg) /* * Locally deactivate EPS bearer context */ - rc = esm_proc_eps_bearer_context_deactivate(TRUE, + rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, msg->data.eps_bearer_context_deactivate.ebi, &pid, &bid); } break; @@ -316,7 +319,7 @@ int esm_sap_send(esm_sap_t *msg) break; case ESM_UNITDATA_IND: - rc = _esm_sap_recv(-1, msg->is_standalone, msg->recv, + rc = _esm_sap_recv(esm_data, -1, msg->is_standalone, msg->recv, &msg->send, &msg->err); break; @@ -361,7 +364,7 @@ int esm_sap_send(esm_sap_t *msg) ** Others: _esm_sap_buffer ** ** ** ***************************************************************************/ -static int _esm_sap_recv(int msg_type, int is_standalone, +static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err) { @@ -439,7 +442,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, * received from the MME */ esm_cause = esm_recv_activate_default_eps_bearer_context_request( - pti, ebi, + esm_data, pti, ebi, &esm_msg.activate_default_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_SUCCESS) || @@ -477,7 +480,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, * received from the MME */ esm_cause = esm_recv_activate_dedicated_eps_bearer_context_request( - pti, ebi, + esm_data, pti, ebi, &esm_msg.activate_dedicated_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_SUCCESS) || @@ -517,7 +520,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, * Process deactivate EPS bearer context request message * received from the MME */ - esm_cause = esm_recv_deactivate_eps_bearer_context_request(pti, ebi, + esm_cause = esm_recv_deactivate_eps_bearer_context_request(esm_data, pti, ebi, &esm_msg.deactivate_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -553,7 +556,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, /* * Process PDN connectivity reject message received from the MME */ - esm_cause = esm_recv_pdn_connectivity_reject(pti, ebi, + esm_cause = esm_recv_pdn_connectivity_reject(esm_data, pti, ebi, &esm_msg.pdn_connectivity_reject); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -576,7 +579,7 @@ static int _esm_sap_recv(int msg_type, int is_standalone, /* * Process PDN disconnect reject message received from the MME */ - esm_cause = esm_recv_pdn_disconnect_reject(pti, ebi, + esm_cause = esm_recv_pdn_disconnect_reject(esm_data, pti, ebi, &esm_msg.pdn_disconnect_reject); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 4a498b5d2e..857d6dc3bd 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -194,7 +194,7 @@ typedef esm_data_context_t esm_data_t; * ESM internal data (used within ESM only) * ---------------------------------------- */ -esm_data_t _esm_data; +extern esm_data_t *_esm_data; /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index cca1e06913..48b8c83bba 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -100,7 +100,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ** ** ***************************************************************************/ int esm_ebr_context_create( - + esm_data_t *esm_data, int pid, int ebi, int is_default, const network_qos_t *qos, const network_tft_t *tft) { @@ -111,7 +111,7 @@ int esm_ebr_context_create( LOG_FUNC_IN; - esm_ctx = &_esm_data; + esm_ctx = esm_data; bid = ESM_DATA_EPS_BEARER_MAX; @@ -331,7 +331,7 @@ int esm_ebr_context_create( ** ** ***************************************************************************/ int esm_ebr_context_release( - + esm_data_t *esm_data, int ebi, int *pid, int *bid) { int found = FALSE; @@ -342,7 +342,7 @@ int esm_ebr_context_release( LOG_FUNC_IN; - esm_ctx = &_esm_data; + esm_ctx = esm_data; if (ebi != ESM_EBI_UNASSIGNED) { /* @@ -533,22 +533,22 @@ int esm_ebr_context_release( ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_context_get_pid(int ebi) +int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi) { LOG_FUNC_IN; int pid; for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) { - if (_esm_data.pdn[pid].data == NULL) { + if (esm_data->pdn[pid].data == NULL) { continue; } - if (_esm_data.pdn[pid].data->bearer[0] == NULL) { + if (esm_data->pdn[pid].data->bearer[0] == NULL) { continue; } - if (_esm_data.pdn[pid].data->bearer[0]->ebi == ebi) { + if (esm_data->pdn[pid].data->bearer[0]->ebi == ebi) { break; } } @@ -583,7 +583,7 @@ int esm_ebr_context_get_pid(int ebi) ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_context_check_tft(int pid, int ebi, +int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi, const network_tft_t *tft, esm_ebr_context_tft_t operation) { @@ -593,14 +593,14 @@ int esm_ebr_context_check_tft(int pid, int ebi, int i; if (pid < ESM_DATA_PDN_MAX) { - if (pid != _esm_data.pdn[pid].pid) { + if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier %d " "is not valid", pid); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-PROC - PDN connection %d has not been " "allocated", pid); } else if (operation == ESM_EBR_CONTEXT_TFT_CREATE) { - esm_pdn_t *pdn = _esm_data.pdn[pid].data; + esm_pdn_t *pdn = esm_data->pdn[pid].data; /* For each EPS bearer context associated to the PDN connection */ for (i = 0; i < pdn->n_bearers; i++) { diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.h b/openair3/NAS/UE/ESM/esm_ebr_context.h index 95d7b081d8..739ee0d3fe 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.h +++ b/openair3/NAS/UE/ESM/esm_ebr_context.h @@ -65,14 +65,14 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_ebr_context_create(int pid, int ebi, int is_default, +int esm_ebr_context_create(esm_data_t *esm_data, int pid, int ebi, int is_default, const network_qos_t *qos, const network_tft_t *tft); -int esm_ebr_context_release(int ebi, int *pid, int *bid); +int esm_ebr_context_release(esm_data_t *esm_data, int ebi, int *pid, int *bid); -int esm_ebr_context_get_pid(int ebi); +int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi); -int esm_ebr_context_check_tft(int pid, int ebi, const network_tft_t *tft, +int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi, const network_tft_t *tft, esm_ebr_context_tft_t operation); diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index 74af9935aa..b56988f025 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -50,6 +50,8 @@ Description Defines the EPS Session Management procedure call manager, /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ +esm_data_t *_esm_data = NULL; + /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -69,36 +71,42 @@ Description Defines the EPS Session Management procedure call manager, ** ** ** Outputs: None ** ** Return: None ** - ** Others: _esm_data ** + ** Others: esm_data-> ** ** ** ***************************************************************************/ -void esm_main_initialize(esm_indication_callback_t cb) +esm_data_t * esm_main_initialize(esm_indication_callback_t cb) { LOG_FUNC_IN; int i; - + esm_data_t *esm_data = calloc(1, sizeof(esm_data_t)); + if ( esm_data == NULL ) { + LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc esm_data"); + // FIXME Stop here !!! + } /* Total number of active EPS bearer contexts */ - _esm_data.n_ebrs = 0; + esm_data->n_ebrs = 0; /* List of active PDN connections */ - _esm_data.n_pdns = 0; + esm_data->n_pdns = 0; for (i = 0; i < ESM_DATA_PDN_MAX + 1; i++) { - _esm_data.pdn[i].pid = -1; - _esm_data.pdn[i].is_active = FALSE; - _esm_data.pdn[i].data = NULL; + esm_data->pdn[i].pid = -1; + esm_data->pdn[i].is_active = FALSE; + esm_data->pdn[i].data = NULL; } /* Emergency bearer services indicator */ - _esm_data.emergency = FALSE; + esm_data->emergency = FALSE; /* Initialize the procedure transaction identity manager */ + esm_pt_initialize(); /* Initialize the EPS bearer context manager */ esm_ebr_initialize(cb); LOG_FUNC_OUT; + return esm_data; } @@ -116,7 +124,7 @@ void esm_main_initialize(esm_indication_callback_t cb) ** Others: None ** ** ** ***************************************************************************/ -void esm_main_cleanup(void) +void esm_main_cleanup(esm_data_t *esm_data) { LOG_FUNC_IN; @@ -127,8 +135,8 @@ void esm_main_cleanup(void) /* De-activate EPS bearers and clean up PDN connections */ for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) { - if (_esm_data.pdn[pid].data) { - esm_pdn_t *pdn = _esm_data.pdn[pid].data; + if (esm_data->pdn[pid].data) { + esm_pdn_t *pdn = esm_data->pdn[pid].data; if (pdn->apn.length > 0) { free(pdn->apn.value); @@ -152,7 +160,7 @@ void esm_main_cleanup(void) } /* Release the PDN connection */ - free(_esm_data.pdn[pid].data); + free(esm_data->pdn[pid].data); } } } @@ -168,7 +176,7 @@ void esm_main_cleanup(void) ** a defined state at the same time ** ** ** ** Inputs: None ** - ** Others: _esm_data ** + ** Others: esm_data-> ** ** ** ** Outputs: None ** ** Return: The maximum number of PDN connections that ** @@ -176,7 +184,7 @@ void esm_main_cleanup(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_nb_pdns_max(void) +int esm_main_get_nb_pdns_max(esm_data_t *esm_data) { LOG_FUNC_IN; @@ -190,18 +198,18 @@ int esm_main_get_nb_pdns_max(void) ** Description: Get the number of active PDN connections ** ** ** ** Inputs: None ** - ** Others: _esm_data ** + ** Others: esm_data-> ** ** ** ** Outputs: None ** ** Return: The number of active PDN connections ** ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_nb_pdns(void) +int esm_main_get_nb_pdns(esm_data_t *esm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_esm_data.n_pdns); + LOG_FUNC_RETURN (esm_data->n_pdns); } /**************************************************************************** @@ -212,7 +220,7 @@ int esm_main_get_nb_pdns(void) ** vices is established ** ** ** ** Inputs: None ** - ** Others: _esm_data ** + ** Others: esm_data-> ** ** ** ** Outputs: None ** ** Return: TRUE if a PDN connection for emergency ** @@ -220,11 +228,11 @@ int esm_main_get_nb_pdns(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_has_emergency(void) +int esm_main_has_emergency(esm_data_t *esm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_esm_data.emergency); + LOG_FUNC_RETURN (esm_data->emergency); } /**************************************************************************** @@ -234,7 +242,7 @@ int esm_main_has_emergency(void) ** Description: Get the status of the specified PDN connection ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: _esm_data ** + ** Others: esm_data-> ** ** ** ** Outputs: state: TRUE if the current state of the PDN con- ** ** nection is ACTIVE; FALSE otherwise. ** @@ -245,7 +253,7 @@ int esm_main_has_emergency(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn_status(int cid, int *state) +int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state) { LOG_FUNC_IN; @@ -253,19 +261,19 @@ int esm_main_get_pdn_status(int cid, int *state) if (pid >= ESM_DATA_PDN_MAX) { return (FALSE); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); return (FALSE); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); return (FALSE); } - if (_esm_data.pdn[pid].data->bearer[0] != NULL) { + if (esm_data->pdn[pid].data->bearer[0] != NULL) { /* The status of a PDN connection is the status of the default EPS bearer * that has been assigned to this PDN connection at activation time */ - int ebi = _esm_data.pdn[pid].data->bearer[0]->ebi; + int ebi = esm_data->pdn[pid].data->bearer[0]->ebi; *state = (esm_ebr_get_status(ebi) == ESM_EBR_ACTIVE); } @@ -280,7 +288,7 @@ int esm_main_get_pdn_status(int cid, int *state) ** Description: Get parameters defined for the specified PDN connection ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: _esm_data ** + ** Others: esm_data-> ** ** ** ** Outputs: type: PDN connection type (IPv4, IPv6, IPv4v6) ** ** apn: Access Point logical Name in used ** @@ -290,7 +298,7 @@ int esm_main_get_pdn_status(int cid, int *state) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn(int cid, int *type, const char **apn, +int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency, int *is_active) { LOG_FUNC_IN; @@ -299,29 +307,29 @@ int esm_main_get_pdn(int cid, int *type, const char **apn, if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); return (RETURNerror); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); return (RETURNerror); } /* Get the PDN type */ - *type = _esm_data.pdn[pid].data->type; + *type = esm_data->pdn[pid].data->type; /* Get the Access Point Name */ - if (_esm_data.pdn[pid].data->apn.length > 0) { - *apn = (char *)(_esm_data.pdn[pid].data->apn.value); + if (esm_data->pdn[pid].data->apn.length > 0) { + *apn = (char *)(esm_data->pdn[pid].data->apn.value); } else { *apn = NULL; } /* Get the emergency bearer services indicator */ - *is_emergency = _esm_data.pdn[pid].data->is_emergency; + *is_emergency = esm_data->pdn[pid].data->is_emergency; /* Get the active PDN connection indicator */ - *is_active = _esm_data.pdn[pid].is_active; + *is_active = esm_data->pdn[pid].is_active; LOG_FUNC_RETURN (RETURNok); } @@ -334,7 +342,7 @@ int esm_main_get_pdn(int cid, int *type, const char **apn, ** tion ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: _esm_data ** + ** Others: esm_data-> ** ** ** ** Outputs: ipv4adddr: IPv4 address ** ** ipv6adddr: IPv6 address ** @@ -342,7 +350,7 @@ int esm_main_get_pdn(int cid, int *type, const char **apn, ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr) +int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr) { LOG_FUNC_IN; @@ -350,35 +358,30 @@ int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr) if (pid >= ESM_DATA_PDN_MAX) { return (RETURNerror); - } else if (pid != _esm_data.pdn[pid].pid) { + } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); return (RETURNerror); - } else if (_esm_data.pdn[pid].data == NULL) { + } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); return (RETURNerror); - } else if (!_esm_data.pdn[pid].is_active) { + } else if (!esm_data->pdn[pid].is_active) { /* No any IP address has been assigned to this PDN connection */ return (RETURNok); } - if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV4) { + if (esm_data->pdn[pid].data->type == NET_PDN_TYPE_IPV4) { /* Get IPv4 address */ - *ipv4addr = _esm_data.pdn[pid].data->ip_addr; - } else if (_esm_data.pdn[pid].data->type == NET_PDN_TYPE_IPV6) { + *ipv4addr = esm_data->pdn[pid].data->ip_addr; + } else if (esm_data->pdn[pid].data->type == NET_PDN_TYPE_IPV6) { /* Get IPv6 address */ - *ipv6addr = _esm_data.pdn[pid].data->ip_addr; + *ipv6addr = esm_data->pdn[pid].data->ip_addr; } else { /* IPv4v6 dual-stack terminal */ - *ipv4addr = _esm_data.pdn[pid].data->ip_addr; - *ipv6addr = _esm_data.pdn[pid].data->ip_addr+ESM_DATA_IPV4_ADDRESS_SIZE; + *ipv4addr = esm_data->pdn[pid].data->ip_addr; + *ipv6addr = esm_data->pdn[pid].data->ip_addr+ESM_DATA_IPV4_ADDRESS_SIZE; } LOG_FUNC_RETURN (RETURNok); } - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h index d6fed970f0..8fea821bb1 100644 --- a/openair3/NAS/UE/ESM/esm_main.h +++ b/openair3/NAS/UE/ESM/esm_main.h @@ -42,6 +42,7 @@ Description Defines the EPS Session Management procedure call manager, #include "networkDef.h" #include "esm_ebr.h" +#include "esmData.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -59,19 +60,19 @@ Description Defines the EPS Session Management procedure call manager, /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void esm_main_initialize(esm_indication_callback_t cb); +esm_data_t * esm_main_initialize(esm_indication_callback_t cb); -void esm_main_cleanup(void); +void esm_main_cleanup(esm_data_t *esm_data); /* User's getter for PDN connections and EPS bearer contexts */ -int esm_main_get_nb_pdns_max(void); -int esm_main_get_nb_pdns(void); -int esm_main_has_emergency(void); -int esm_main_get_pdn_status(int cid, int *state); -int esm_main_get_pdn(int cid, int *type, const char **apn, int *is_emergency, +int esm_main_get_nb_pdns_max(esm_data_t *esm_data); +int esm_main_get_nb_pdns(esm_data_t *esm_data); +int esm_main_has_emergency(esm_data_t *esm_data); +int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state); +int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency, int *is_active); -int esm_main_get_pdn_addr(int cid, const char **ipv4addr, const char **ipv6addr); +int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr); #endif /* __ESM_MAIN_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h index edbd926309..7f29166bbf 100644 --- a/openair3/NAS/UE/ESM/esm_proc.h +++ b/openair3/NAS/UE/ESM/esm_proc.h @@ -121,12 +121,12 @@ int esm_proc_status(int is_standalone, int pti, OctetString *msg, * PDN connectivity procedure * -------------------------------------------------------------------------- */ -int esm_proc_pdn_connectivity(int cid, int to_define, +int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int to_define, esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, unsigned int *pti); int esm_proc_pdn_connectivity_request(int is_standalone, int pti, OctetString *msg, int sent_by_ue); -int esm_proc_pdn_connectivity_accept(int pti, esm_proc_pdn_type_t pdn_type, +int esm_proc_pdn_connectivity_accept(esm_data_t *esm_data, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_address, const OctetString *apn, int *esm_cause); int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause); int esm_proc_pdn_connectivity_complete(void); @@ -138,12 +138,12 @@ int esm_proc_pdn_connectivity_failure(int is_pending); * PDN disconnect procedure * -------------------------------------------------------------------------- */ -int esm_proc_pdn_disconnect(int cid, unsigned int *pti, unsigned int *ebi); +int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi); int esm_proc_pdn_disconnect_request(int is_standalone, int pti, OctetString *msg, int sent_by_ue); int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause); -int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause); +int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause); /* * -------------------------------------------------------------------------- @@ -151,10 +151,10 @@ int esm_proc_pdn_disconnect_reject(int pti, int *esm_cause); * -------------------------------------------------------------------------- */ -int esm_proc_default_eps_bearer_context_request(int pid, int ebi, +int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, int ebi, const esm_proc_qos_t *esm_qos, int *esm_cause); int esm_proc_default_eps_bearer_context_complete(void); -int esm_proc_default_eps_bearer_context_failure(void); +int esm_proc_default_eps_bearer_context_failure(esm_data_t *esm_data); int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, OctetString *msg, int ue_triggered); @@ -167,7 +167,7 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, * -------------------------------------------------------------------------- */ -int esm_proc_dedicated_eps_bearer_context_request(int ebi, int default_ebi, +int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause); int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, @@ -181,9 +181,9 @@ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, * -------------------------------------------------------------------------- */ -int esm_proc_eps_bearer_context_deactivate(int is_local, int ebi, int *pid, +int esm_proc_eps_bearer_context_deactivate(esm_data_t *esm_data, int is_local, int ebi, int *pid, int *bid); -int esm_proc_eps_bearer_context_deactivate_request(int ebi, int *esm_cause); +int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi, int *esm_cause); int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, OctetString *msg, int ue_triggered); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index c4b1dc9928..17397a01a9 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -101,7 +101,7 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, emm_main_initialize(emm_cb, imei); /* Initialize the ESM procedure manager */ - esm_main_initialize(esm_cb); + _esm_data = esm_main_initialize(esm_cb); LOG_FUNC_OUT; } @@ -137,7 +137,7 @@ void nas_proc_cleanup(nas_user_t *user) emm_main_cleanup(); /* Perform the EPS Session Manager's clean up procedure */ - esm_main_cleanup(); + esm_main_cleanup(_esm_data); LOG_FUNC_OUT; } @@ -649,11 +649,11 @@ int nas_proc_get_attach_status(nas_user_t *user) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_range(nas_user_t *user) +int nas_proc_get_pdn_range(esm_data_t *esm_data) { LOG_FUNC_IN; - int max_pdn_id = esm_main_get_nb_pdns_max(); + int max_pdn_id = esm_main_get_nb_pdns_max(esm_data); LOG_FUNC_RETURN (max_pdn_id); } @@ -674,7 +674,7 @@ int nas_proc_get_pdn_range(nas_user_t *user) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max) +int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_pdn_max) { LOG_FUNC_IN; @@ -682,13 +682,13 @@ int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_ int n_defined_pdn = 0; /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(); + int n_pdn = esm_main_get_nb_pdns_max(esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get the status of this PDN */ int state = FALSE; - int is_defined = esm_main_get_pdn_status(cid, &state); + int is_defined = esm_main_get_pdn_status(esm_data, cid, &state); if (is_defined != FALSE) { /* This PDN has been defined */ @@ -718,7 +718,7 @@ int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_ ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char **apns, +int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const char **apns, int n_pdn_max) { LOG_FUNC_IN; @@ -727,13 +727,13 @@ int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char * int n_defined_pdn = 0; /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(); + int n_pdn = esm_main_get_nb_pdns_max(esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { int emergency, active; /* Get PDN connection parameters */ - int rc = esm_main_get_pdn(cid, types, apns, &emergency, &active); + int rc = esm_main_get_pdn(esm_data, cid, types, apns, &emergency, &active); if (rc != RETURNerror) { /* This PDN has been defined */ @@ -780,7 +780,7 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add if (cid > 0) { /* Get addresses assigned to the specified PDN */ - rc = esm_main_get_pdn_addr(cid, addr1, addr2); + rc = esm_main_get_pdn_addr(_esm_data, cid, addr1, addr2); if (rc != RETURNerror) { *cids = cid; @@ -788,12 +788,12 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add } } else if (cid < 0) { /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(); + int n_pdn = esm_main_get_nb_pdns_max(_esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get PDN connection addresses */ - rc = esm_main_get_pdn_addr(cid, addr1, addr2); + rc = esm_main_get_pdn_addr(_esm_data, cid, addr1, addr2); if (rc != RETURNerror) { /* This PDN has been defined */ @@ -920,7 +920,7 @@ int nas_proc_deactivate_pdn(nas_user_t *user, int cid) cid = 2; /* Deactivate all active PDN contexts */ - while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) { + while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(_esm_data)+1)) { rc = _nas_proc_deactivate(user, cid++, TRUE); } } @@ -972,7 +972,7 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid) cid = 1; /* Activate all defined PDN contexts */ - while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max()+1)) { + while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(_esm_data)+1)) { rc = _nas_proc_activate(user, cid++, TRUE); } } @@ -1291,7 +1291,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) esm_sap_t esm_sap; /* Get PDN context parameters */ - rc = esm_main_get_pdn(cid, &esm_sap.data.pdn_connect.pdn_type, + rc = esm_main_get_pdn(_esm_data, cid, &esm_sap.data.pdn_connect.pdn_type, &esm_sap.data.pdn_connect.apn, &esm_sap.data.pdn_connect.is_emergency, &active); @@ -1313,7 +1313,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) } if (esm_sap.data.pdn_connect.is_emergency) { - if (esm_main_has_emergency()) { + if (esm_main_has_emergency(_esm_data)) { /* There is already a PDN connection for emergency * bearer services established; the UE shall not * request an additional PDN connection for emer- @@ -1365,7 +1365,7 @@ static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) int active = FALSE; /* Get PDN context parameters */ - rc = esm_main_get_pdn(cid, &pdn_type, &apn, &emergency, &active); + rc = esm_main_get_pdn(_esm_data, cid, &pdn_type, &apn, &emergency, &active); if (rc != RETURNok) { /* No any context is defined for the specified PDN */ @@ -1383,7 +1383,7 @@ static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) LOG_FUNC_RETURN (RETURNok); } - if (esm_main_get_nb_pdns() > 1) { + if (esm_main_get_nb_pdns(_esm_data) > 1) { /* * Notify ESM that all EPS bearers towards the specified PDN * has to be released diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index 9efccb80ca..6851746d38 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -43,6 +43,7 @@ Description NAS procedure call manager #include "user_defs.h" #include "emm_main.h" #include "esm_ebr.h" +#include "esmData.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -96,9 +97,9 @@ int nas_proc_get_attach_status(nas_user_t *user); int nas_proc_reset_pdn(nas_user_t *user, int cid); int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, int emergency, int p_cscf, int im_cn_signal); -int nas_proc_get_pdn_range(nas_user_t *user); -int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max); -int nas_proc_get_pdn_param(nas_user_t *user, int *cids, int *types, const char **apns, +int nas_proc_get_pdn_range(esm_data_t *esm_data); +int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_pdn_max); +int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const char **apns, int n_pdn_max); int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **addr1, const char **addr2, int n_addr_max); diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 9bdb720678..f0fcae59c6 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -2043,7 +2043,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) * Read command returns the current settings for each * defined PDN connection/default EPS bearer context */ - cgdcont->n_pdns = nas_proc_get_pdn_param(user, cgdcont->cid, + cgdcont->n_pdns = nas_proc_get_pdn_param(_esm_data, cgdcont->cid, cgdcont->PDP_type, cgdcont->APN, AT_CGDCONT_RESP_SIZE); @@ -2061,7 +2061,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) */ { /* Get the maximum value of a PDN context identifier */ - int cid_max = nas_proc_get_pdn_range(user); + int cid_max = nas_proc_get_pdn_range(_esm_data); if (cid_max > AT_CGDCONT_RESP_SIZE) { /* The range is defined by the user interface */ @@ -2184,7 +2184,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) * The read command returns the current activation states for * all the defined PDN/EPS bearer contexts */ - cgact->n_pdns = nas_proc_get_pdn_status(user, cgact->cid, cgact->state, + cgact->n_pdns = nas_proc_get_pdn_status(_esm_data, cgact->cid, cgact->state, AT_CGACT_RESP_SIZE); if (cgact->n_pdns == 0) { From 223247ceb099bcb9ae2482985f2fe7d82d57b87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 11 Jul 2016 15:48:09 +0200 Subject: [PATCH 141/571] UE/EMM: add nas_user_t parameter to emm_sap_send Surprisingly, it touches every part of openair3, and most of the prototype. Moreover, a special attention have been put to callback review. However, there are still places to fix or review indicated by FIXME --- openair3/NAS/UE/EMM/Attach.c | 73 ++++++++++--------- openair3/NAS/UE/EMM/Authentication.c | 40 +++++----- openair3/NAS/UE/EMM/Detach.c | 35 +++++---- openair3/NAS/UE/EMM/EmmStatusHdl.c | 4 +- openair3/NAS/UE/EMM/Identification.c | 5 +- openair3/NAS/UE/EMM/IdleMode.c | 32 ++++---- openair3/NAS/UE/EMM/IdleMode.h | 3 +- openair3/NAS/UE/EMM/LowerLayer.c | 22 +++--- openair3/NAS/UE/EMM/LowerLayer.h | 14 ++-- openair3/NAS/UE/EMM/SAP/EmmDeregistered.c | 4 +- .../SAP/EmmDeregisteredAttemptingToAttach.c | 4 +- .../EMM/SAP/EmmDeregisteredLimitedService.c | 4 +- .../EMM/SAP/EmmDeregisteredNoCellAvailable.c | 4 +- .../UE/EMM/SAP/EmmDeregisteredNormalService.c | 6 +- .../UE/EMM/SAP/EmmDeregisteredPlmnSearch.c | 4 +- openair3/NAS/UE/EMM/SAP/EmmNull.c | 4 +- openair3/NAS/UE/EMM/SAP/EmmRegistered.c | 4 +- .../NAS/UE/EMM/SAP/EmmRegisteredInitiated.c | 6 +- openair3/NAS/UE/EMM/SAP/emm_as.c | 70 +++++++++--------- openair3/NAS/UE/EMM/SAP/emm_as.h | 5 +- openair3/NAS/UE/EMM/SAP/emm_esm.c | 8 +- openair3/NAS/UE/EMM/SAP/emm_esm.h | 3 +- openair3/NAS/UE/EMM/SAP/emm_recv.c | 30 ++++---- openair3/NAS/UE/EMM/SAP/emm_recv.h | 16 ++-- openair3/NAS/UE/EMM/SAP/emm_sap.c | 11 +-- openair3/NAS/UE/EMM/SAP/emm_sap.h | 5 +- openair3/NAS/UE/EMM/SecurityModeControl.c | 4 +- openair3/NAS/UE/EMM/emm_main.c | 4 +- openair3/NAS/UE/EMM/emm_main.h | 3 +- openair3/NAS/UE/EMM/emm_proc.h | 34 +++++---- .../ESM/DedicatedEpsBearerContextActivation.c | 14 ++-- .../ESM/DefaultEpsBearerContextActivation.c | 18 ++--- .../NAS/UE/ESM/EpsBearerContextDeactivation.c | 25 ++++--- openair3/NAS/UE/ESM/EsmStatusHdl.c | 4 +- openair3/NAS/UE/ESM/PdnConnectivity.c | 20 ++--- openair3/NAS/UE/ESM/PdnDisconnect.c | 17 +++-- openair3/NAS/UE/ESM/SAP/esm_recv.c | 23 +++--- openair3/NAS/UE/ESM/SAP/esm_recv.h | 11 +-- openair3/NAS/UE/ESM/SAP/esm_sap.c | 45 ++++++------ openair3/NAS/UE/ESM/SAP/esm_sap.h | 3 +- openair3/NAS/UE/ESM/esm_ebr_context.c | 9 +-- openair3/NAS/UE/ESM/esm_ebr_context.h | 3 +- openair3/NAS/UE/ESM/esm_proc.h | 39 +++++----- openair3/NAS/UE/ESM/esm_pt.c | 1 + openair3/NAS/UE/ESM/esm_pt.h | 2 + openair3/NAS/UE/nas_proc.c | 34 ++++----- 46 files changed, 380 insertions(+), 349 deletions(-) diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 939c5b4afd..7084c69f92 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -97,7 +97,7 @@ static void *_emm_attach_t3402_handler(void *); /* * Abnormal case attach procedure */ -static void _emm_attach_abnormal_cases_bcd(emm_sap_t *); +static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *); /* * Internal data used for attach procedure @@ -140,7 +140,7 @@ static struct { ** Others: T3402, T3410, T3411 ** ** ** ***************************************************************************/ -int emm_proc_attach(emm_proc_attach_type_t type) +int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) { LOG_FUNC_IN; @@ -245,14 +245,14 @@ int emm_proc_attach(emm_proc_attach_type_t type) esm_sap.data.pdn_connect.pdn_type = NET_PDN_TYPE_IPV4; esm_sap.data.pdn_connect.apn = NULL; esm_sap.data.pdn_connect.is_emergency = _emm_data.is_emergency; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); if (rc != RETURNerror) { /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(emm_proc_attach_request, emm_proc_attach_failure, - emm_proc_attach_release, NULL); + emm_proc_attach_release, user); if (rc != RETURNok) { LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); @@ -260,7 +260,7 @@ int emm_proc_attach(emm_proc_attach_type_t type) } /* Start T3410 timer */ - T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); + T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in %ld seconds", T3410.id, T3410.sec); /* Stop T3402 and T3411 timers if running */ @@ -276,7 +276,7 @@ int emm_proc_attach(emm_proc_attach_type_t type) /* Get the PDN connectivity request to transfer within the ESM * container of the initial attach request message */ emm_sap.u.emm_as.u.establish.NASmsg = esm_sap.send; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN(rc); @@ -301,7 +301,7 @@ int emm_proc_attach(emm_proc_attach_type_t type) int emm_proc_attach_request(void *args) { LOG_FUNC_IN; - + nas_user_t *user=args; emm_sap_t emm_sap; int rc; @@ -309,7 +309,7 @@ int emm_proc_attach_request(void *args) * Notify EMM that Attach Request has been sent to the network */ emm_sap.primitive = EMMREG_ATTACH_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -345,7 +345,7 @@ int emm_proc_attach_request(void *args) ** Others: _emm_data, T3412, T3402, T3423 ** ** ** ***************************************************************************/ -int emm_proc_attach_accept(long t3412, long t3402, long t3423, +int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, int n_tais, tai_t *tai, GUTI_t *guti, int n_eplmns, plmn_t *eplmn, const OctetString *esm_msg_pP) @@ -427,14 +427,14 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ; esm_sap.is_standalone = FALSE; esm_sap.recv = esm_msg_pP; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) { /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ rc = emm_proc_lowerlayer_initialize(emm_proc_attach_complete, emm_proc_attach_failure, - NULL, NULL); + NULL, user); if (rc != RETURNok) { LOG_TRACE(WARNING, @@ -458,7 +458,7 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, * complete message */ emm_sap.u.emm_as.u.data.NASinfo = EMM_AS_NAS_DATA_ATTACH; emm_sap.u.emm_as.u.data.NASmsg = esm_sap.send; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } else if (esm_sap.err != ESM_SAP_DISCARDED) { /* 3GPP TS 24.301, section 5.5.1.2.6, case j * If the ACTIVATE DEFAULT BEARER CONTEXT REQUEST message combined @@ -467,7 +467,7 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, * procedure by sending a DETACH REQUEST message to the network. */ emm_sap.primitive = EMMREG_DETACH_INIT; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } else { /* * ESM procedure failed and, received message has been discarded or @@ -500,7 +500,7 @@ int emm_proc_attach_accept(long t3412, long t3402, long t3423, ** Others: _emm_data, _emm_attach_data, T3410 ** ** ** ***************************************************************************/ -int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) +int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg_pP) { LOG_FUNC_IN; @@ -676,11 +676,11 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) default : /* Other values are considered as abnormal cases * 3GPP TS 24.301, section 5.5.1.2.6, case d */ - _emm_attach_abnormal_cases_bcd(&emm_sap); + _emm_attach_abnormal_cases_bcd(user, &emm_sap); break; } - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); /* * Notify ESM that the network rejected connectivity to the PDN @@ -690,7 +690,7 @@ int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg_pP) esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; esm_sap.is_standalone = FALSE; esm_sap.recv = esm_msg_pP; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } LOG_FUNC_RETURN(rc); @@ -721,6 +721,7 @@ int emm_proc_attach_complete(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; emm_sap_t emm_sap; esm_sap_t esm_sap; int rc; @@ -743,7 +744,7 @@ int emm_proc_attach_complete(void *args) * to the network */ emm_sap.primitive = EMMREG_ATTACH_CNF; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* @@ -753,7 +754,7 @@ int emm_proc_attach_complete(void *args) */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_CNF; esm_sap.is_standalone = FALSE; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } LOG_FUNC_RETURN(rc); @@ -786,9 +787,9 @@ int emm_proc_attach_complete(void *args) int emm_proc_attach_failure(int is_initial, void *args) { LOG_FUNC_IN; - int rc = RETURNok; esm_sap_t esm_sap; + nas_user_t *user=args; LOG_TRACE(WARNING, "EMM-PROC - EPS attach failure"); @@ -821,7 +822,7 @@ int emm_proc_attach_failure(int is_initial, void *args) esm_sap.recv = NULL; } - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); if (rc != RETURNerror) { /* Start T3411 timer */ @@ -855,16 +856,16 @@ int emm_proc_attach_failure(int is_initial, void *args) int emm_proc_attach_release(void *args) { LOG_FUNC_IN; - + nas_user_t *user=args; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - NAS signalling connection released"); /* Execute abnormal case attach procedure */ - _emm_attach_abnormal_cases_bcd(&emm_sap); + _emm_attach_abnormal_cases_bcd(user, &emm_sap); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -883,7 +884,7 @@ int emm_proc_attach_release(void *args) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_attach_restart(void) +int emm_proc_attach_restart(nas_user_t *user) { LOG_FUNC_IN; @@ -897,7 +898,7 @@ int emm_proc_attach_restart(void) */ emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -943,10 +944,11 @@ int emm_proc_attach_set_emergency(void) ** Others: _emm_data ** ** ** ***************************************************************************/ -int emm_proc_attach_set_detach(void) +int emm_proc_attach_set_detach(void *nas_user) { LOG_FUNC_IN; + nas_user_t *user=nas_user; int rc; LOG_TRACE(WARNING, @@ -959,7 +961,7 @@ int emm_proc_attach_set_detach(void) */ emm_sap_t emm_sap; emm_sap.primitive = EMMREG_DETACH_CNF; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -999,6 +1001,7 @@ void *_emm_attach_t3410_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; emm_sap_t emm_sap; int rc; @@ -1007,9 +1010,9 @@ void *_emm_attach_t3410_handler(void *args) /* Stop T3410 timer */ T3410.id = nas_timer_stop(T3410.id); /* Execute abnormal case attach procedure */ - _emm_attach_abnormal_cases_bcd(&emm_sap); + _emm_attach_abnormal_cases_bcd(user, &emm_sap); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Locally release the NAS signalling connection */ @@ -1041,6 +1044,7 @@ static void *_emm_attach_t3411_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3411 timer expired"); @@ -1054,7 +1058,7 @@ static void *_emm_attach_t3411_handler(void *args) emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(NULL); } @@ -1085,6 +1089,7 @@ static void *_emm_attach_t3402_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3402 timer expired"); @@ -1100,7 +1105,7 @@ static void *_emm_attach_t3402_handler(void *args) emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(NULL); } @@ -1132,7 +1137,7 @@ static void *_emm_attach_t3402_handler(void *args) ** T3411 ** ** ** ***************************************************************************/ -static void _emm_attach_abnormal_cases_bcd(emm_sap_t *emm_sap) +static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap) { LOG_FUNC_IN; @@ -1177,7 +1182,7 @@ static void _emm_attach_abnormal_cases_bcd(emm_sap_t *emm_sap) _emm_data.status = EU2_NOT_UPDATED; /* Start T3402 timer */ - T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, NULL); + T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3402 (%d) expires in %ld seconds", T3402.id, T3402.sec); /* diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 9022acbdac..7b5672c3bf 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -119,9 +119,9 @@ static struct { /* * Abnormal case authentication procedure */ -static int _authentication_abnormal_cases_cde(int emm_cause, +static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, const OctetString *auts); -static int _authentication_abnormal_case_f(void); +static int _authentication_abnormal_case_f(nas_user_t *user); static int _authentication_stop_timers(void); static int _authentication_start_timers(void); @@ -171,7 +171,7 @@ static int _authentication_kasme(const OctetString *autn, ** T3418, T3420 ** ** ** ***************************************************************************/ -int emm_proc_authentication_request(int native_ksi, int ksi, +int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, const OctetString *rand, const OctetString *autn) { @@ -261,17 +261,17 @@ int emm_proc_authentication_request(int native_ksi, int ksi, /* 3GPP TS 24.301, section 5.4.2.6, case e * SQN failure */ rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_SYNCH_FAILURE, &auts); + user, EMM_CAUSE_SYNCH_FAILURE, &auts); } else if (sbit == 0) { /* 3GPP TS 24.301, section 5.4.2.6, case d * Non-EPS authentication unacceptable */ rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE, NULL); + user, EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE, NULL); } else { /* 3GPP TS 24.301, section 5.4.2.6, case c * MAC code failure */ rc = _authentication_abnormal_cases_cde( - EMM_CAUSE_MAC_FAILURE, NULL); + user, EMM_CAUSE_MAC_FAILURE, NULL); } /* Free the AUTS parameter */ @@ -335,7 +335,7 @@ int emm_proc_authentication_request(int native_ksi, int ksi, /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, _emm_data.security, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Reset the authentication failure counters */ @@ -396,7 +396,7 @@ int emm_proc_authentication_request(int native_ksi, int ksi, ** T3417, T3430 ** ** ** ***************************************************************************/ -int emm_proc_authentication_reject(void) +int emm_proc_authentication_reject(nas_user_t *user) { LOG_FUNC_IN; @@ -451,7 +451,7 @@ int emm_proc_authentication_reject(void) * Notify EMM that authentication is not accepted by the network */ emm_sap.primitive = EMMREG_AUTH_REJ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -563,6 +563,7 @@ static void *_authentication_t3418_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; int rc; LOG_TRACE(WARNING, "EMM-PROC - T3418 timer expired"); @@ -573,7 +574,7 @@ static void *_authentication_t3418_handler(void *args) _authentication_data.mac_count = 0; _authentication_data.umts_count = 0; /* 3GPP TS 24.301, section 5.4.2.7, case f */ - rc = _authentication_abnormal_case_f(); + rc = _authentication_abnormal_case_f(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); @@ -604,6 +605,7 @@ static void *_authentication_t3420_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; int rc; LOG_TRACE(WARNING, "EMM-PROC - T3420 timer expired"); @@ -613,7 +615,7 @@ static void *_authentication_t3420_handler(void *args) /* Reset the sync failure counter */ _authentication_data.sync_count = 0; /* 3GPP TS 24.301, section 5.4.2.7, case f */ - rc = _authentication_abnormal_case_f(); + rc = _authentication_abnormal_case_f(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - Failed to proceed abnormal case f"); @@ -644,7 +646,7 @@ static void *_authentication_t3420_handler(void *args) ** Others: _authentication_data, T3418, T3420 ** ** ** ***************************************************************************/ -static int _authentication_abnormal_cases_cde(int emm_cause, +static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, const OctetString *auts) { LOG_FUNC_IN; @@ -670,7 +672,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, _emm_data.security, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* @@ -683,7 +685,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, _authentication_data.mac_count += 1; /* Start timer T3418 */ T3418.id = nas_timer_start(T3418.sec, - _authentication_t3418_handler, NULL); + _authentication_t3418_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " "%ld seconds", T3418.id, T3418.sec); break; @@ -694,7 +696,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, _authentication_data.umts_count += 1; /* Start timer T3418 */ T3418.id = nas_timer_start(T3418.sec, - _authentication_t3418_handler, NULL); + _authentication_t3418_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " "%ld seconds", T3418.id, T3418.sec); break; @@ -705,7 +707,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, _authentication_data.sync_count += 1; /* Start timer T3420 */ T3420.id = nas_timer_start(T3420.sec, - _authentication_t3420_handler, NULL); + _authentication_t3420_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3420 (%d) expires in " "%ld seconds", T3420.id, T3420.sec); break; @@ -743,7 +745,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, if (failure_counter >= AUTHENTICATION_COUNTER_MAX) { /* 3GPP TS 24.301, section 5.4.2.6, case f */ - rc = _authentication_abnormal_case_f(); + rc = _authentication_abnormal_case_f(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - " @@ -771,7 +773,7 @@ static int _authentication_abnormal_cases_cde(int emm_cause, ** Others: None ** ** ** ***************************************************************************/ -static int _authentication_abnormal_case_f(void) +static int _authentication_abnormal_case_f(nas_user_t *user) { LOG_FUNC_IN; @@ -787,7 +789,7 @@ static int _authentication_abnormal_case_f(void) emm_sap.primitive = EMMAS_RELEASE_REQ; emm_sap.u.emm_as.u.release.guti = _emm_data.guti; emm_sap.u.emm_as.u.release.cause = EMM_AS_CAUSE_AUTHENTICATION; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start any retransmission timers (e.g. T3410, T3417, T3421 or diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index 7fd7330524..7ea4220cae 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -83,7 +83,7 @@ void *_emm_detach_t3421_handler(void *); /* * Abnormal case detach procedures */ -static int _emm_detach_abort(emm_proc_detach_type_t type); +static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type); /* * Internal data used for detach procedure @@ -131,7 +131,7 @@ static struct { ** Others: _emm_detach_data ** ** ** ***************************************************************************/ -int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off) { LOG_FUNC_IN; @@ -151,7 +151,7 @@ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) * lower layer notification */ rc = emm_proc_lowerlayer_initialize(emm_proc_detach_request, emm_proc_detach_failure, - emm_proc_detach_release, NULL); + emm_proc_detach_release, user); if (rc != RETURNok) { LOG_TRACE(WARNING, "Failed to initialize EMM procedure handler"); @@ -177,7 +177,7 @@ int emm_proc_detach(emm_proc_detach_type_t type, int switch_off) * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -202,12 +202,13 @@ int emm_proc_detach_request(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; emm_sap_t emm_sap; int rc; if ( !_emm_detach_data.switch_off ) { /* Start T3421 timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); + T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld seconds", T3421.id, T3421.sec); } @@ -216,7 +217,7 @@ int emm_proc_detach_request(void *args) * Notify EMM that Detach Request has been sent to the network */ emm_sap.primitive = EMMREG_DETACH_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -243,10 +244,11 @@ int emm_proc_detach_request(void *args) ** Others: T3421 ** ** ** ***************************************************************************/ -int emm_proc_detach_accept(void) +int emm_proc_detach_accept(void* args) { LOG_FUNC_IN; + nas_user_t *user=args; int rc; LOG_TRACE(INFO, "EMM-PROC - UE initiated detach procedure completion"); @@ -263,7 +265,7 @@ int emm_proc_detach_accept(void) esm_sap_t esm_sap; esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; esm_sap.data.eps_bearer_context_deactivate.ebi = ESM_SAP_ALL_EBI; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); /* * XXX - Upon receiving notification from ESM that all EPS bearer @@ -296,6 +298,7 @@ int emm_proc_detach_failure(int is_initial, void *args) { LOG_FUNC_IN; + nas_user_t *user=args; emm_sap_t emm_sap; int rc; @@ -312,7 +315,7 @@ int emm_proc_detach_failure(int is_initial, void *args) */ emm_sap.primitive = EMMREG_DETACH_INIT; emm_sap.u.emm_reg.u.detach.switch_off = _emm_detach_data.switch_off; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); } @@ -342,8 +345,9 @@ int emm_proc_detach_release(void *args) LOG_TRACE(WARNING, "EMM-PROC - NAS signalling connection released"); + nas_user_t *user=args; /* Abort the detach procedure */ - int rc = _emm_detach_abort(_emm_detach_data.type); + int rc = _emm_detach_abort(user, _emm_detach_data.type); LOG_FUNC_RETURN(rc); } @@ -383,6 +387,7 @@ void *_emm_detach_t3421_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; int rc; /* Increment the retransmission counter */ @@ -419,17 +424,17 @@ void *_emm_detach_t3421_handler(void *args) * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start T3421 timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); + T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld " "seconds", T3421.id, T3421.sec); } } else { /* Abort the detach procedure */ - rc = _emm_detach_abort(_emm_detach_data.type); + rc = _emm_detach_abort(user, _emm_detach_data.type); } LOG_FUNC_RETURN(NULL); @@ -455,7 +460,7 @@ void *_emm_detach_t3421_handler(void *args) ** Others: T3421 ** ** ** ***************************************************************************/ -static int _emm_detach_abort(emm_proc_detach_type_t type) +static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type) { LOG_FUNC_IN; @@ -475,7 +480,7 @@ static int _emm_detach_abort(emm_proc_detach_type_t type) */ emm_sap.primitive = EMMREG_DETACH_FAILED; emm_sap.u.emm_reg.u.detach.type = type; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/EmmStatusHdl.c b/openair3/NAS/UE/EMM/EmmStatusHdl.c index c95441d370..c0c1fc24de 100644 --- a/openair3/NAS/UE/EMM/EmmStatusHdl.c +++ b/openair3/NAS/UE/EMM/EmmStatusHdl.c @@ -115,7 +115,7 @@ int emm_proc_status_ind(unsigned int ueid, int emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_status(unsigned int ueid, int emm_cause) +int emm_proc_status(nas_user_t *user, unsigned int ueid, int emm_cause) { LOG_FUNC_IN; @@ -140,7 +140,7 @@ int emm_proc_status(unsigned int ueid, int emm_cause) emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c index a9ceb7a43b..ce64e65850 100644 --- a/openair3/NAS/UE/EMM/Identification.c +++ b/openair3/NAS/UE/EMM/Identification.c @@ -49,6 +49,7 @@ Description Defines the identification EMM procedure executed by the #include "emm_sap.h" #include "msc.h" +#include "user_defs.h" #include // malloc, free #include // memcpy @@ -102,7 +103,7 @@ static const char *_emm_identity_type_str[] = { ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_identification_request(emm_proc_identity_type_t type) +int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t type) { LOG_FUNC_IN; @@ -199,7 +200,7 @@ int emm_proc_identification_request(emm_proc_identity_type_t type) /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, _emm_data.security, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index a5a2c30708..f7e3274614 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -78,8 +78,8 @@ Description Defines EMM procedures executed by the Non-Access Stratum /****************************************************************************/ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn); -static int _IldlMode_get_opnn_id(const plmn_t *plmn); -static int _IdleMode_get_suitable_cell(int index); +static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn); +static int _IdleMode_get_suitable_cell(nas_user_t *user, int index); /* * A list of PLMN identities in priority order is maintained locally @@ -152,7 +152,7 @@ static IdleMode_callback_t _emm_indication_notify; ** Others: _emm_plmn_list, _emm_indication_notify ** ** ** ***************************************************************************/ -void IdleMode_initialize(IdleMode_callback_t cb) +void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) { /* Initialize the list of available PLMNs */ _emm_plmn_list.n_plmns = 0; @@ -166,7 +166,7 @@ void IdleMode_initialize(IdleMode_callback_t cb) _emm_indication_notify = *cb; /* Initialize EMM Service Access Point */ - emm_sap_initialize(); + emm_sap_initialize(user); } /* @@ -510,7 +510,7 @@ int IdleMode_get_plmn_id_index(const char *plmn) ** Others: _emm_plmn_list ** ** ** ***************************************************************************/ -int emm_proc_initialize(void) +int emm_proc_initialize(nas_user_t *user) { LOG_FUNC_IN; @@ -576,7 +576,7 @@ int emm_proc_initialize(void) /* Initialize the PLMNs' parameters */ for (i=0; i < _emm_plmn_list.n_plmns; i++) { struct plmn_param_t *plmn = &(_emm_plmn_list.param[i]); - int id = _IldlMode_get_opnn_id(_emm_plmn_list.plmn[i]); + int id = _IldlMode_get_opnn_id(user, _emm_plmn_list.plmn[i]); if (id < 0) { plmn->fullname[0] = '\0'; @@ -603,7 +603,7 @@ int emm_proc_initialize(void) emm_sap.u.emm_reg.u.regist.index = 0; } - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); @@ -634,7 +634,7 @@ int emm_proc_initialize(void) ** Others: _emm_plmn_list.index ** ** ** ***************************************************************************/ -int emm_proc_plmn_selection(int index) +int emm_proc_plmn_selection(nas_user_t *user, int index) { LOG_FUNC_IN; @@ -679,7 +679,7 @@ int emm_proc_plmn_selection(int index) * automatic mode. */ _emm_plmn_list.index = index; - rc = _IdleMode_get_suitable_cell(index); + rc = _IdleMode_get_suitable_cell(user, index); } LOG_FUNC_RETURN (rc); @@ -721,7 +721,7 @@ int emm_proc_plmn_selection(int index) ** Others: _emm_plmn_list, _emm_data ** ** ** ***************************************************************************/ -int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) +int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat) { LOG_FUNC_IN; @@ -890,7 +890,7 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) if (index < last_plmn_index) { /* Try to select the next PLMN in the list of available PLMNs */ _emm_plmn_list.index = index; - rc = emm_proc_plmn_selection(index); + rc = emm_proc_plmn_selection(user, index); } else { /* No suitable cell of any PLMN within the ordered list * of available PLMNs has been found */ @@ -932,7 +932,7 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) /* * Notify EMM that PLMN selection procedure has completed */ - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (_emm_plmn_list.splmn != -1) { if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) { @@ -950,7 +950,7 @@ int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat) * to register the presence of the UE to the selected PLMN */ emm_sap.primitive = EMMREG_ATTACH_INIT; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } } @@ -1135,7 +1135,7 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** Others: None ** ** ** ***************************************************************************/ -static int _IldlMode_get_opnn_id(const plmn_t *plmn) +static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) { int i; @@ -1188,7 +1188,7 @@ static int _IldlMode_get_opnn_id(const plmn_t *plmn) ** Others: None ** ** ** ***************************************************************************/ -static int _IdleMode_get_suitable_cell(int index) +static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) { emm_sap_t emm_sap; const plmn_t *plmn = _emm_plmn_list.plmn[index]; @@ -1212,6 +1212,6 @@ static int _IdleMode_get_suitable_cell(int index) emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE; } - return emm_sap_send(&emm_sap); + return emm_sap_send(user, &emm_sap); } diff --git a/openair3/NAS/UE/EMM/IdleMode.h b/openair3/NAS/UE/EMM/IdleMode.h index f75d149e91..f602cb37b0 100644 --- a/openair3/NAS/UE/EMM/IdleMode.h +++ b/openair3/NAS/UE/EMM/IdleMode.h @@ -41,6 +41,7 @@ Description Defines the functions used to get information from the list #define __IDLEMODE_H__ #include "commonDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -60,7 +61,7 @@ typedef int (*IdleMode_callback_t) (int); /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void IdleMode_initialize(IdleMode_callback_t cb); +void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb); int IdleMode_get_nb_plmns(void); int IdleMode_get_hplmn_index(void); diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c index f0f7a3c5b6..afe8f37c1b 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.c +++ b/openair3/NAS/UE/EMM/LowerLayer.c @@ -96,7 +96,7 @@ static struct { ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_success(unsigned int ueid) +int lowerlayer_success(nas_user_t *user, unsigned int ueid) { LOG_FUNC_IN; @@ -105,7 +105,7 @@ int lowerlayer_success(unsigned int ueid) emm_sap.primitive = EMMREG_LOWERLAYER_SUCCESS; emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -125,7 +125,7 @@ int lowerlayer_success(unsigned int ueid) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_failure(unsigned int ueid) +int lowerlayer_failure(nas_user_t *user, unsigned int ueid) { LOG_FUNC_IN; @@ -134,7 +134,7 @@ int lowerlayer_failure(unsigned int ueid) emm_sap.primitive = EMMREG_LOWERLAYER_FAILURE; emm_sap.u.emm_reg.ueid = ueid; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -155,7 +155,7 @@ int lowerlayer_failure(unsigned int ueid) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_establish(void) +int lowerlayer_establish(nas_user_t *user) { LOG_FUNC_IN; @@ -180,7 +180,7 @@ int lowerlayer_establish(void) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_release(int cause) +int lowerlayer_release(nas_user_t *user, int cause) { LOG_FUNC_IN; @@ -192,7 +192,7 @@ int lowerlayer_release(int cause) emm_sap.primitive = EMMREG_LOWERLAYER_RELEASE; emm_sap.u.emm_reg.ueid = 0; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -213,7 +213,7 @@ int lowerlayer_release(int cause) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) +int lowerlayer_data_ind(nas_user_t *user, unsigned int ueid, const OctetString *data) { esm_sap_t esm_sap; int rc; @@ -226,7 +226,7 @@ int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) esm_sap.ueid = ueid; esm_sap.recv = data; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -247,7 +247,7 @@ int lowerlayer_data_ind(unsigned int ueid, const OctetString *data) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_req(unsigned int ueid, const OctetString *data) +int lowerlayer_data_req(nas_user_t *user, unsigned int ueid, const OctetString *data) { LOG_FUNC_IN; @@ -266,7 +266,7 @@ int lowerlayer_data_req(unsigned int ueid, const OctetString *data) emm_sap.u.emm_as.u.data.NASmsg.value = data->value; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, sctx, FALSE, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/LowerLayer.h b/openair3/NAS/UE/EMM/LowerLayer.h index 396de203d3..85229de686 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.h +++ b/openair3/NAS/UE/EMM/LowerLayer.h @@ -43,6 +43,7 @@ Description Defines EMM procedures executed by the Non-Access Stratum #define __LOWERLAYER_H__ #include "OctetString.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -78,12 +79,13 @@ typedef int (*lowerlayer_release_callback_t)(void *); /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int lowerlayer_success(unsigned int ueid); -int lowerlayer_failure(unsigned int ueid); -int lowerlayer_establish(void); -int lowerlayer_release(int cause); +// FIXME prototype with ueid +int lowerlayer_success(nas_user_t *user, unsigned int ueid); +int lowerlayer_failure(nas_user_t *user, unsigned int ueid); +int lowerlayer_establish(nas_user_t *user); +int lowerlayer_release(nas_user_t *user, int cause); -int lowerlayer_data_ind(unsigned int ueid, const OctetString *data); -int lowerlayer_data_req(unsigned int ueid, const OctetString *data); +int lowerlayer_data_ind(nas_user_t *user, unsigned int ueid, const OctetString *data); +int lowerlayer_data_req(nas_user_t *user, unsigned int ueid, const OctetString *data); #endif /* __LOWERLAYER_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c index 801de96145..b92e7a0c60 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c @@ -86,7 +86,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregistered(const emm_reg_t *evt) +int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -149,7 +149,7 @@ int EmmDeregistered(const emm_reg_t *evt) if (rc != RETURNerror) { /* Restart the attach procedure */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c index ed1d079930..42476fd24d 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c @@ -79,7 +79,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredAttemptingToAttach(const emm_reg_t *evt) +int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -104,7 +104,7 @@ int EmmDeregisteredAttemptingToAttach(const emm_reg_t *evt) if (rc != RETURNerror) { /* Restart the attach procedure */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c index 78d418c69c..31b52469fa 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c @@ -83,7 +83,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredLimitedService(const emm_reg_t *evt) +int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -109,7 +109,7 @@ int EmmDeregisteredLimitedService(const emm_reg_t *evt) /* * Initiate attach procedure for emergency bearer services */ - rc = emm_proc_attach(EMM_ATTACH_TYPE_EMERGENCY); + rc = emm_proc_attach(user, EMM_ATTACH_TYPE_EMERGENCY); break; case _EMMREG_ATTACH_REQ: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c index 9f1f526e83..517d574dc7 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c @@ -84,7 +84,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredNoCellAvailable(const emm_reg_t *evt) +int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -118,7 +118,7 @@ int EmmDeregisteredNoCellAvailable(const emm_reg_t *evt) /* * Perform network re-selection procedure */ - rc = emm_proc_plmn_selection(evt->u.regist.index); + rc = emm_proc_plmn_selection(user, evt->u.regist.index); } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index 85f98c4bd7..a3ac3bbdab 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -84,7 +84,7 @@ extern uint8_t usim_test; ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredNormalService(const emm_reg_t *evt) +int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -112,11 +112,11 @@ int EmmDeregisteredNormalService(const emm_reg_t *evt) */ if(usim_test == 0) { - rc = emm_proc_attach(EMM_ATTACH_TYPE_EPS); + rc = emm_proc_attach(user, EMM_ATTACH_TYPE_EPS); } else { - rc = emm_proc_attach(EMM_ATTACH_TYPE_IMSI); // CMW500 IMSI initial attach expected + rc = emm_proc_attach(user, EMM_ATTACH_TYPE_IMSI); // CMW500 IMSI initial attach expected } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c index d9865c9b72..692e9a9e85 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c @@ -82,7 +82,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredPlmnSearch(const emm_reg_t *evt) +int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -122,7 +122,7 @@ int EmmDeregisteredPlmnSearch(const emm_reg_t *evt) /* * Perform network selection procedure */ - rc = emm_proc_plmn_selection(evt->u.regist.index); + rc = emm_proc_plmn_selection(user, evt->u.regist.index); break; case _EMMREG_REGISTER_REJ: diff --git a/openair3/NAS/UE/EMM/SAP/EmmNull.c b/openair3/NAS/UE/EMM/SAP/EmmNull.c index e482281a71..5da067bfe8 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmNull.c +++ b/openair3/NAS/UE/EMM/SAP/EmmNull.c @@ -76,7 +76,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmNull(const emm_reg_t *evt) +int EmmNull(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -104,7 +104,7 @@ int EmmNull(const emm_reg_t *evt) * establish an EMM context and make the UE reachable by an MME. */ if (rc != RETURNerror) { - rc = emm_proc_initialize(); + rc = emm_proc_initialize(user); } break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c index dcbeee167e..83bb9ea37a 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c @@ -81,7 +81,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegistered(const emm_reg_t *evt) +int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -96,7 +96,7 @@ int EmmRegistered(const emm_reg_t *evt) /* * Initiate detach procedure for EPS services */ - rc = emm_proc_detach(EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); + rc = emm_proc_detach(user, EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); break; case _EMMREG_DETACH_REQ: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index 688b168b53..71c9eb0a1d 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -78,7 +78,7 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredInitiated(const emm_reg_t *evt) +int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; @@ -103,7 +103,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) if (rc != RETURNerror) { /* Restart the attach procedure */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); } break; @@ -209,7 +209,7 @@ int EmmRegisteredInitiated(const emm_reg_t *evt) /* * Initiate detach procedure for EPS services */ - rc = emm_proc_detach(EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); + rc = emm_proc_detach(user, EMM_DETACH_TYPE_EPS, evt->u.detach.switch_off); break; case _EMMREG_DETACH_REQ: diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 7650f97ee8..8e0c661b09 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -99,19 +99,19 @@ static const char *_emm_as_primitive_str[] = { * Functions executed to process EMM procedures upon receiving * data from the network */ -static int _emm_as_recv(unsigned int ueid, const char *msg, int len, +static int _emm_as_recv(nas_user_t *user, unsigned int ueid, const char *msg, int len, int *emm_cause); -static int _emm_as_establish_cnf(const emm_as_establish_t *msg, int *emm_cause); -static int _emm_as_establish_rej(void); -static int _emm_as_release_ind(const emm_as_release_t *msg); +static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg, int *emm_cause); +static int _emm_as_establish_rej(nas_user_t *user); +static int _emm_as_release_ind(nas_user_t *user, const emm_as_release_t *msg); static int _emm_as_page_ind(const emm_as_page_t *msg); static int _emm_as_cell_info_res(const emm_as_cell_info_t *msg); static int _emm_as_cell_info_ind(const emm_as_cell_info_t *msg); -static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause); +static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm_cause); /* * Functions executed to send data to the network when requested @@ -133,7 +133,7 @@ static int _emm_as_encrypt( int length, emm_security_context_t *emm_security_context); -static int _emm_as_send(const emm_as_t *msg); +static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg); static int _emm_as_security_res(const emm_as_security_t *, ul_info_transfer_req_t *); @@ -143,7 +143,7 @@ static int _emm_as_establish_req(const emm_as_establish_t *, static int _emm_as_cell_info_req(const emm_as_cell_info_t *, cell_info_req_t *); -static int _emm_as_data_req(const emm_as_data_t *, ul_info_transfer_req_t *); +static int _emm_as_data_req(const emm_as_data_t *msg, ul_info_transfer_req_t *); static int _emm_as_status_ind(const emm_as_status_t *, ul_info_transfer_req_t *); static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *); @@ -165,7 +165,7 @@ static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *); ** Others: NONE ** ** ** ***************************************************************************/ -void emm_as_initialize(void) +void emm_as_initialize(nas_user_t *user) { LOG_FUNC_IN; @@ -188,7 +188,7 @@ void emm_as_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_as_send(const emm_as_t *msg) +int emm_as_send(nas_user_t *user, const emm_as_t *msg) { LOG_FUNC_IN; @@ -203,21 +203,21 @@ int emm_as_send(const emm_as_t *msg) switch (primitive) { case _EMMAS_DATA_IND: - rc = _emm_as_data_ind(&msg->u.data, &emm_cause); + rc = _emm_as_data_ind(user, &msg->u.data, &emm_cause); ueid = msg->u.data.ueid; break; case _EMMAS_ESTABLISH_CNF: - rc = _emm_as_establish_cnf(&msg->u.establish, &emm_cause); + rc = _emm_as_establish_cnf(user, &msg->u.establish, &emm_cause); break; case _EMMAS_ESTABLISH_REJ: - rc = _emm_as_establish_rej(); + rc = _emm_as_establish_rej(user); break; case _EMMAS_RELEASE_IND: - rc = _emm_as_release_ind(&msg->u.release); + rc = _emm_as_release_ind(user, &msg->u.release); break; case _EMMAS_PAGE_IND: @@ -234,7 +234,7 @@ int emm_as_send(const emm_as_t *msg) default: /* Other primitives are forwarded to the Access Stratum */ - rc = _emm_as_send(msg); + rc = _emm_as_send(user, msg); if (rc != RETURNok) { LOG_TRACE(ERROR, "EMMAS-SAP - " @@ -306,7 +306,7 @@ int emm_as_send(const emm_as_t *msg) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_recv(unsigned int ueid, const char *msg, int len, +static int _emm_as_recv(nas_user_t *user, unsigned int ueid, const char *msg, int len, int *emm_cause) { LOG_FUNC_IN; @@ -342,30 +342,30 @@ static int _emm_as_recv(unsigned int ueid, const char *msg, int len, break; case IDENTITY_REQUEST: - rc = emm_recv_identity_request(&emm_msg->identity_request, + rc = emm_recv_identity_request(user, &emm_msg->identity_request, emm_cause); break; case AUTHENTICATION_REQUEST: - rc = emm_recv_authentication_request( + rc = emm_recv_authentication_request(user, &emm_msg->authentication_request, emm_cause); break; case AUTHENTICATION_REJECT: - rc = emm_recv_authentication_reject( + rc = emm_recv_authentication_reject(user, &emm_msg->authentication_reject, emm_cause); break; case SECURITY_MODE_COMMAND: - rc = emm_recv_security_mode_command( + rc = emm_recv_security_mode_command(user, &emm_msg->security_mode_command, emm_cause); break; case DETACH_ACCEPT: - rc = emm_recv_detach_accept(&emm_msg->detach_accept, emm_cause); + rc = emm_recv_detach_accept(user, &emm_msg->detach_accept, emm_cause); break; @@ -406,7 +406,7 @@ static int _emm_as_recv(unsigned int ueid, const char *msg, int len, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause) +static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm_cause) { LOG_FUNC_IN; @@ -443,23 +443,23 @@ static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause) } else if (header.protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { /* Process EMM data */ - rc = _emm_as_recv(msg->ueid, plain_msg, bytes, emm_cause); + rc = _emm_as_recv(user, msg->ueid, plain_msg, bytes, emm_cause); } else if (header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) { const OctetString data = {bytes, (uint8_t *)plain_msg}; /* Foward ESM data to EPS session management */ - rc = lowerlayer_data_ind(msg->ueid, &data); + rc = lowerlayer_data_ind(user, msg->ueid, &data); } free(plain_msg); } } else { /* Process successfull lower layer transfer indication */ - rc = lowerlayer_success(msg->ueid); + rc = lowerlayer_success(user, msg->ueid); } } else { /* Process lower layer transmission failure of NAS message */ - rc = lowerlayer_failure(msg->ueid); + rc = lowerlayer_failure(user, msg->ueid); } LOG_FUNC_RETURN (rc); @@ -482,7 +482,7 @@ static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_establish_cnf(const emm_as_establish_t *msg, +static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg, int *emm_cause) { LOG_FUNC_IN; @@ -494,11 +494,11 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, if (msg->NASmsg.length > 0) { /* The NAS signalling connection is established */ - (void) lowerlayer_establish(); + (void) lowerlayer_establish(user); } else { /* The initial NAS message has been successfully delivered to * lower layers */ - rc = lowerlayer_success(0); + rc = lowerlayer_success(user, 0); LOG_FUNC_RETURN (rc); } @@ -523,11 +523,11 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, switch (emm_msg->header.message_type) { case ATTACH_ACCEPT: - rc = emm_recv_attach_accept(&emm_msg->attach_accept, emm_cause); + rc = emm_recv_attach_accept(user, &emm_msg->attach_accept, emm_cause); break; case ATTACH_REJECT: - rc = emm_recv_attach_reject(&emm_msg->attach_reject, emm_cause); + rc = emm_recv_attach_reject(user, &emm_msg->attach_reject, emm_cause); break; case DETACH_ACCEPT: @@ -563,7 +563,7 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_establish_rej(void) +static int _emm_as_establish_rej(nas_user_t *user) { LOG_FUNC_IN; @@ -573,7 +573,7 @@ static int _emm_as_establish_rej(void) "failure"); /* Process lower layer transmission failure of initial NAS message */ - rc = lowerlayer_failure(0); + rc = lowerlayer_failure(user, 0); LOG_FUNC_RETURN (rc); } @@ -595,7 +595,7 @@ static int _emm_as_establish_rej(void) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_release_ind(const emm_as_release_t *msg) +static int _emm_as_release_ind(nas_user_t *user, const emm_as_release_t *msg) { LOG_FUNC_IN; @@ -605,7 +605,7 @@ static int _emm_as_release_ind(const emm_as_release_t *msg) "(cause=%d)", msg->cause); /* Process NAS signalling connection release indication */ - rc = lowerlayer_release(msg->cause); + rc = lowerlayer_release(user, msg->cause); LOG_FUNC_RETURN (rc); } @@ -928,7 +928,7 @@ _emm_as_encrypt( ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_send(const emm_as_t *msg) +static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.h b/openair3/NAS/UE/EMM/SAP/emm_as.h index 04a14cf3cb..726a363d75 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.h +++ b/openair3/NAS/UE/EMM/SAP/emm_as.h @@ -41,6 +41,7 @@ Description Defines the EMMAS Service Access Point that provides #define __EMM_AS_H__ #include "emm_asDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -58,8 +59,8 @@ Description Defines the EMMAS Service Access Point that provides /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_as_initialize(void); +void emm_as_initialize(nas_user_t *user); -int emm_as_send(const emm_as_t *msg); +int emm_as_send(nas_user_t *user, const emm_as_t *msg); #endif /* __EMM_AS_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_esm.c b/openair3/NAS/UE/EMM/SAP/emm_esm.c index a12d71d79b..10b34f0a1d 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esm.c +++ b/openair3/NAS/UE/EMM/SAP/emm_esm.c @@ -108,7 +108,7 @@ void emm_esm_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_esm_send(const emm_esm_t *msg) +int emm_esm_send(nas_user_t *user, const emm_esm_t *msg) { LOG_FUNC_IN; @@ -123,7 +123,7 @@ int emm_esm_send(const emm_esm_t *msg) case _EMMESM_ESTABLISH_REQ: /* ESM requests EMM to initiate an attach procedure before * requesting subsequent connectivity to additional PDNs */ - rc = emm_proc_attach_restart(); + rc = emm_proc_attach_restart(user); break; case _EMMESM_ESTABLISH_CNF: @@ -138,7 +138,7 @@ int emm_esm_send(const emm_esm_t *msg) } } else { /* Consider the UE locally detached from the network */ - rc = emm_proc_attach_set_detach(); + rc = emm_proc_attach_set_detach(user); } break; @@ -149,7 +149,7 @@ int emm_esm_send(const emm_esm_t *msg) case _EMMESM_UNITDATA_REQ: /* ESM requests EMM to transfer ESM data unit to lower layer */ - rc = lowerlayer_data_req(msg->ueid, &msg->u.data.msg); + rc = lowerlayer_data_req(user, msg->ueid, &msg->u.data.msg); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/emm_esm.h b/openair3/NAS/UE/EMM/SAP/emm_esm.h index 7a763d4759..11aa42213f 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esm.h +++ b/openair3/NAS/UE/EMM/SAP/emm_esm.h @@ -42,6 +42,7 @@ Description Defines the EMMESM Service Access Point that provides #define __EMM_ESM_H__ #include "emm_esmDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -61,6 +62,6 @@ Description Defines the EMMESM Service Access Point that provides void emm_esm_initialize(void); -int emm_esm_send(const emm_esm_t *msg); +int emm_esm_send(nas_user_t *user, const emm_esm_t *msg); #endif /* __EMM_ESM_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_recv.c b/openair3/NAS/UE/EMM/SAP/emm_recv.c index 0ad41b09d8..5b7c6d7dda 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_recv.c +++ b/openair3/NAS/UE/EMM/SAP/emm_recv.c @@ -125,7 +125,7 @@ int emm_recv_status(unsigned int ueid, emm_status_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause) +int emm_recv_attach_accept(nas_user_t *user, attach_accept_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -224,7 +224,7 @@ int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause) } /* Execute attach procedure accepted by the network */ - rc = emm_proc_attach_accept(T3412, T3402, T3423, n_tais, tai, pguti, + rc = emm_proc_attach_accept(user, T3412, T3402, T3423, n_tais, tai, pguti, n_eplmns, &eplmn, &msg->esmmessagecontainer.esmmessagecontainercontents); @@ -245,7 +245,7 @@ int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause) +int emm_recv_attach_reject(nas_user_t *user, attach_reject_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -275,11 +275,11 @@ int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause) */ if (msg->presencemask & ATTACH_REJECT_ESM_MESSAGE_CONTAINER_PRESENT) { /* Execute attach procedure rejected by the network */ - rc = emm_proc_attach_reject(msg->emmcause, + rc = emm_proc_attach_reject(user, msg->emmcause, &msg->esmmessagecontainer.esmmessagecontainercontents); } else { /* Execute attach procedure rejected by the network */ - rc = emm_proc_attach_reject(msg->emmcause, NULL); + rc = emm_proc_attach_reject(user, msg->emmcause, NULL); } LOG_FUNC_RETURN (rc); @@ -299,7 +299,7 @@ int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause) +int emm_recv_detach_accept(nas_user_t *user, detach_accept_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -311,7 +311,7 @@ int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause) * Message processing */ /* Execute the UE initiated detach procedure completion by the UE */ - rc = emm_proc_detach_accept(); + rc = emm_proc_detach_accept(user); LOG_FUNC_RETURN (rc); } @@ -330,7 +330,7 @@ int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause) +int emm_recv_identity_request(nas_user_t *user, identity_request_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -358,7 +358,7 @@ int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause) } /* Execute the identification procedure initiated by the network */ - rc = emm_proc_identification_request(type); + rc = emm_proc_identification_request(user, type); LOG_FUNC_RETURN (rc); } @@ -377,7 +377,7 @@ int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_authentication_request(authentication_request_msg *msg, +int emm_recv_authentication_request(nas_user_t *user, authentication_request_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -404,7 +404,7 @@ int emm_recv_authentication_request(authentication_request_msg *msg, * Message processing */ /* Execute the authentication procedure initiated by the network */ - rc = emm_proc_authentication_request( + rc = emm_proc_authentication_request(user, msg->naskeysetidentifierasme.tsc != NAS_KEY_SET_IDENTIFIER_MAPPED, msg->naskeysetidentifierasme.naskeysetidentifier, &msg->authenticationparameterrand.rand, @@ -427,7 +427,7 @@ int emm_recv_authentication_request(authentication_request_msg *msg, ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_authentication_reject(authentication_reject_msg *msg, +int emm_recv_authentication_reject(nas_user_t *user, authentication_reject_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -440,7 +440,7 @@ int emm_recv_authentication_reject(authentication_reject_msg *msg, * Message processing */ /* Execute the authentication procedure not accepted by the network */ - rc = emm_proc_authentication_reject(); + rc = emm_proc_authentication_reject(user); LOG_FUNC_RETURN (rc); } @@ -459,7 +459,7 @@ int emm_recv_authentication_reject(authentication_reject_msg *msg, ** Others: None ** ** ** ***************************************************************************/ -int emm_recv_security_mode_command(security_mode_command_msg *msg, +int emm_recv_security_mode_command(nas_user_t *user, security_mode_command_msg *msg, int *emm_cause) { LOG_FUNC_IN; @@ -473,7 +473,7 @@ int emm_recv_security_mode_command(security_mode_command_msg *msg, */ /* Execute the security mode control procedure initiated by the network */ LOG_TRACE(INFO,"Execute the security mode control procedure initiated by the network: imeisvrequest %d\n",msg->imeisvrequest); - rc = emm_proc_security_mode_command( + rc = emm_proc_security_mode_command(user, msg->naskeysetidentifier.tsc != NAS_KEY_SET_IDENTIFIER_MAPPED, msg->naskeysetidentifier.naskeysetidentifier, msg->selectednassecurityalgorithms.typeofcipheringalgorithm, diff --git a/openair3/NAS/UE/EMM/SAP/emm_recv.h b/openair3/NAS/UE/EMM/SAP/emm_recv.h index cec52a8c1f..ead59e3851 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_recv.h +++ b/openair3/NAS/UE/EMM/SAP/emm_recv.h @@ -59,7 +59,7 @@ Description Defines functions executed at the EMMAS Service Access #include "EmmInformation.h" #include "DownlinkNasTransport.h" #include "CsServiceNotification.h" - +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ @@ -88,17 +88,17 @@ int emm_recv_status(unsigned int ueid, emm_status_msg *msg, int *emm_cause); * Functions executed by the UE upon receiving EMM message from the network * -------------------------------------------------------------------------- */ -int emm_recv_attach_accept(attach_accept_msg *msg, int *emm_cause); -int emm_recv_attach_reject(attach_reject_msg *msg, int *emm_cause); +int emm_recv_attach_accept(nas_user_t *user, attach_accept_msg *msg, int *emm_cause); +int emm_recv_attach_reject(nas_user_t *user, attach_reject_msg *msg, int *emm_cause); -int emm_recv_detach_accept(detach_accept_msg *msg, int *emm_cause); +int emm_recv_detach_accept(nas_user_t *user, detach_accept_msg *msg, int *emm_cause); -int emm_recv_identity_request(identity_request_msg *msg, int *emm_cause); -int emm_recv_authentication_request(authentication_request_msg *msg, +int emm_recv_identity_request(nas_user_t *user, identity_request_msg *msg, int *emm_cause); +int emm_recv_authentication_request(nas_user_t *user, authentication_request_msg *msg, int *emm_cause); -int emm_recv_authentication_reject(authentication_reject_msg *msg, +int emm_recv_authentication_reject(nas_user_t *user, authentication_reject_msg *msg, int *emm_cause); -int emm_recv_security_mode_command(security_mode_command_msg *msg, +int emm_recv_security_mode_command(nas_user_t *user, security_mode_command_msg *msg, int *emm_cause); #endif /* __EMM_RECV_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_sap.c b/openair3/NAS/UE/EMM/SAP/emm_sap.c index d8312ee74c..6887982786 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_sap.c +++ b/openair3/NAS/UE/EMM/SAP/emm_sap.c @@ -46,6 +46,7 @@ Description Defines the EMM Service Access Points at which the EPS #include "emm_reg.h" #include "emm_esm.h" #include "emm_as.h" +#include "user_defs.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -73,13 +74,13 @@ Description Defines the EMM Service Access Points at which the EPS ** Others: NONE ** ** ** ***************************************************************************/ -void emm_sap_initialize(void) +void emm_sap_initialize(nas_user_t *user) { LOG_FUNC_IN; emm_reg_initialize(); emm_esm_initialize(); - emm_as_initialize(); + emm_as_initialize(user); LOG_FUNC_OUT; } @@ -98,7 +99,7 @@ void emm_sap_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_sap_send(emm_sap_t *msg) +int emm_sap_send(nas_user_t *user, emm_sap_t *msg) { int rc = RETURNerror; @@ -116,12 +117,12 @@ int emm_sap_send(emm_sap_t *msg) (primitive < (emm_primitive_t)EMMESM_PRIMITIVE_MAX) ) { /* Forward to the EMMESM-SAP */ msg->u.emm_esm.primitive = primitive; - rc = emm_esm_send(&msg->u.emm_esm); + rc = emm_esm_send(user, &msg->u.emm_esm); } else if ( (primitive > (emm_primitive_t)EMMAS_PRIMITIVE_MIN) && (primitive < (emm_primitive_t)EMMAS_PRIMITIVE_MAX) ) { /* Forward to the EMMAS-SAP */ msg->u.emm_as.primitive = primitive; - rc = emm_as_send(&msg->u.emm_as); + rc = emm_as_send(user, &msg->u.emm_as); } else { LOG_TRACE(WARNING, "EMM-SAP - Out of range primitive (%d)", primitive); diff --git a/openair3/NAS/UE/EMM/SAP/emm_sap.h b/openair3/NAS/UE/EMM/SAP/emm_sap.h index f27e8d4e58..b84fd7808b 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_sap.h +++ b/openair3/NAS/UE/EMM/SAP/emm_sap.h @@ -46,6 +46,7 @@ Description Defines the EMM Service Access Points at which the EPS #include "emm_regDef.h" #include "emm_esmDef.h" #include "emm_asDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -156,8 +157,8 @@ typedef struct emm_sap_s { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_sap_initialize(void); +void emm_sap_initialize(nas_user_t *user); -int emm_sap_send(emm_sap_t *msg); +int emm_sap_send(nas_user_t *user, emm_sap_t *msg); #endif /* __EMM_SAP_H__*/ diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index f27eb7b4af..05f094b22d 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -145,7 +145,7 @@ static void _security_release(emm_security_context_t *ctx); ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_security_mode_command(int native_ksi, int ksi, +int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, int seea, int seia, int reea, int reia, int imeisv_request) { LOG_FUNC_IN; @@ -334,7 +334,7 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, _emm_data.security, security_context_is_new, TRUE); - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 2eb4d8fa24..e3342ed3ba 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -100,7 +100,7 @@ static int _emm_main_callback(int); ** Others: _emm_data ** ** ** ***************************************************************************/ -void emm_main_initialize(emm_indication_callback_t cb, const char *imei) +void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei) { LOG_FUNC_IN; @@ -392,7 +392,7 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei) /* * Initialize EMM internal data used for UE in idle mode */ - IdleMode_initialize(&_emm_main_callback); + IdleMode_initialize(user, &_emm_main_callback); LOG_FUNC_OUT; } diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index c41dc0b664..403a87507d 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -41,6 +41,7 @@ Description Defines the EPS Mobility Management procedure call manager, #include "commonDef.h" #include "networkDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -67,7 +68,7 @@ typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_main_initialize(emm_indication_callback_t cb, const char *imei); +void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei); void emm_main_cleanup(void); diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 60f71f11c2..8bfe447e50 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -42,6 +42,7 @@ Description Defines the EPS Mobility Management procedures executed at #include "commonDef.h" #include "OctetString.h" #include "LowerLayer.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -92,7 +93,7 @@ typedef enum { *--------------------------------------------------------------------------- */ int emm_proc_status_ind(unsigned int ueid, int emm_cause); -int emm_proc_status(unsigned int ueid, int emm_cause); +int emm_proc_status(nas_user_t *user, unsigned int ueid, int emm_cause); /* *--------------------------------------------------------------------------- @@ -112,28 +113,29 @@ int emm_proc_lowerlayer_release(void); * UE's Idle mode procedure *--------------------------------------------------------------------------- */ -int emm_proc_initialize(void); -int emm_proc_plmn_selection(int index); -int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat); +int emm_proc_initialize(nas_user_t *user); +int emm_proc_plmn_selection(nas_user_t *user, int index); +int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat); /* * -------------------------------------------------------------------------- * Attach procedure * -------------------------------------------------------------------------- */ -int emm_proc_attach(emm_proc_attach_type_t type); +int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type); int emm_proc_attach_request(void *args); -int emm_proc_attach_accept(long T3412, long T3402, long T3423, int n_tais, +int emm_proc_attach_accept(nas_user_t *user, long T3412, long T3402, long T3423, int n_tais, tai_t *tai, GUTI_t *guti, int n_eplmns, plmn_t *eplmn, const OctetString *esm_msg); -int emm_proc_attach_reject(int emm_cause, const OctetString *esm_msg); +int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg); int emm_proc_attach_complete(void *args); int emm_proc_attach_failure(int is_initial, void *args); int emm_proc_attach_release(void *args); -int emm_proc_attach_restart(void); +int emm_proc_attach_restart(nas_user_t *user); int emm_proc_attach_set_emergency(void); -int emm_proc_attach_set_detach(void); +// FIXME check prototype +int emm_proc_attach_set_detach(void *user); @@ -142,9 +144,9 @@ int emm_proc_attach_set_detach(void); * Detach procedure * -------------------------------------------------------------------------- */ -int emm_proc_detach(emm_proc_detach_type_t type, int switch_off); +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off); int emm_proc_detach_request(void *args); -int emm_proc_detach_accept(void); +int emm_proc_detach_accept(void *args); int emm_proc_detach_failure(int is_initial, void *args); int emm_proc_detach_release(void *args); @@ -154,7 +156,7 @@ int emm_proc_detach_release(void *args); * Identification procedure * -------------------------------------------------------------------------- */ -int emm_proc_identification_request(emm_proc_identity_type_t type); +int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t type); /* @@ -162,9 +164,9 @@ int emm_proc_identification_request(emm_proc_identity_type_t type); * Authentication procedure * -------------------------------------------------------------------------- */ -int emm_proc_authentication_request(int native_ksi, int ksi, +int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, const OctetString *rand, const OctetString *autn); -int emm_proc_authentication_reject(void); +int emm_proc_authentication_reject(nas_user_t *user); int emm_proc_authentication_delete(void); @@ -173,8 +175,8 @@ int emm_proc_authentication_delete(void); * Security mode control procedure * -------------------------------------------------------------------------- */ -int emm_proc_security_mode_command(int native_ksi, int ksi, int seea, int seia, - int reea, int reia,int imeisv_request); +int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, int seea, int seia, + int reea, int reia, int imeisv_request); /* *--------------------------------------------------------------------------- diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 0ce27b1fcf..1863b14a34 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -104,13 +104,13 @@ Description Defines the dedicated EPS bearer context activation ESM ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, int default_ebi, +int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = _esm_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - Dedicated EPS bearer context activation " @@ -141,7 +141,7 @@ int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested dedicated EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -206,7 +206,7 @@ int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; @@ -225,7 +225,7 @@ int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ @@ -266,7 +266,7 @@ int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; @@ -293,7 +293,7 @@ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 0d1a307c96..21dc81cdf5 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -104,12 +104,12 @@ static struct { ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, int ebi, +int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int ebi, const esm_proc_qos_t *qos, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = _esm_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - Default EPS bearer context activation " @@ -126,7 +126,7 @@ int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, i int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested default EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -188,7 +188,7 @@ int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, i ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; @@ -208,7 +208,7 @@ int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } if (rc != RETURNerror) { @@ -256,7 +256,7 @@ int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; @@ -283,7 +283,7 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } else { /* An error is returned to notify EMM that the default EPS bearer * activation procedure initiated as part of the initial attach @@ -346,7 +346,7 @@ int esm_proc_default_eps_bearer_context_complete(void) ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_failure(esm_data_t *esm_data) +int esm_proc_default_eps_bearer_context_failure(nas_user_t *user) { LOG_FUNC_IN; @@ -357,7 +357,7 @@ int esm_proc_default_eps_bearer_context_failure(esm_data_t *esm_data) "ESM-PROC - Default EPS bearer context activation failure"); /* Release the default EPS bearer context and enter state INACTIVE */ - int rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, ebi, &pid, &bid); + int rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &pid, &bid); if (rc != RETURNerror) { /* Reset default EPS bearer context internal data */ diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index 21aaeb262a..2bafb9c18e 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -74,7 +74,7 @@ Description Defines the EPS bearer context deactivation ESM procedure * in the UE * -------------------------------------------------------------------------- */ -static int _eps_bearer_release(esm_data_t *esm_data, int ebi, int *pid, int *bid); +static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid); /****************************************************************************/ @@ -112,25 +112,25 @@ static int _eps_bearer_release(esm_data_t *esm_data, int ebi, int *pid, int *bid ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate(esm_data_t *esm_data, int is_local, int ebi, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, int *pid, int *bid) { LOG_FUNC_IN; int rc = RETURNerror; int i; - + esm_data_t *esm_data = _esm_data; if (is_local) { if (ebi != ESM_SAP_ALL_EBI) { /* Locally release the EPS bearer context */ - rc = _eps_bearer_release(esm_data, ebi, pid, bid); + rc = _eps_bearer_release(user, ebi, pid, bid); } else { /* Locally release all the EPS bearer contexts */ *bid = 0; for (*pid = 0; *pid < ESM_DATA_PDN_MAX; (*pid)++) { if (esm_data->pdn[*pid].data) { - rc = _eps_bearer_release(esm_data, ESM_EBI_UNASSIGNED, pid, bid); + rc = _eps_bearer_release(user, ESM_EBI_UNASSIGNED, pid, bid); if (rc != RETURNok) { break; @@ -189,18 +189,19 @@ int esm_proc_eps_bearer_context_deactivate(esm_data_t *esm_data, int is_local, i ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi, int *esm_cause) +int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, int *esm_cause) { LOG_FUNC_IN; int pid, bid; int rc = RETURNok; + esm_data_t *esm_data = _esm_data; LOG_TRACE(INFO, "ESM-PROC - EPS bearer context deactivation " "requested by the network (ebi=%d)", ebi); /* Release the EPS bearer context entry */ - if (esm_ebr_context_release(esm_data, ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) { + if (esm_ebr_context_release(user, ebi, &pid, &bid) == ESM_EBI_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; LOG_FUNC_RETURN (RETURNerror); @@ -243,7 +244,7 @@ int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi esm_sap.is_standalone = TRUE; esm_sap.data.pdn_connect.is_defined = TRUE; esm_sap.data.pdn_connect.cid = pid + 1; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } } } @@ -275,7 +276,7 @@ int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { LOG_FUNC_IN; @@ -293,7 +294,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, emm_sap.u.emm_esm.ueid = 0; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } if (rc != RETURNerror) { @@ -352,14 +353,14 @@ int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, ** Others: None ** ** ** ***************************************************************************/ -static int _eps_bearer_release(esm_data_t *esm_data, int ebi, int *pid, int *bid) +static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) { LOG_FUNC_IN; int rc = RETURNerror; /* Release the EPS bearer context entry */ - ebi = esm_ebr_context_release(esm_data, ebi, pid, bid); + ebi = esm_ebr_context_release(user, ebi, pid, bid); if (ebi == ESM_EBI_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); diff --git a/openair3/NAS/UE/ESM/EsmStatusHdl.c b/openair3/NAS/UE/ESM/EsmStatusHdl.c index 48e86f4a60..f42cdb02ae 100644 --- a/openair3/NAS/UE/ESM/EsmStatusHdl.c +++ b/openair3/NAS/UE/ESM/EsmStatusHdl.c @@ -161,7 +161,7 @@ int esm_proc_status_ind( ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_status(int is_standalone, +int esm_proc_status(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered) { @@ -179,7 +179,7 @@ int esm_proc_status(int is_standalone, emm_sap.u.emm_esm.ueid = 0; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 46be3fef14..161e88669a 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -279,7 +279,7 @@ int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_request(int is_standalone, int pti, +int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue) { LOG_FUNC_IN; @@ -298,7 +298,7 @@ int esm_proc_pdn_connectivity_request(int is_standalone, int pti, emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start T3482 retransmission timer */ @@ -346,12 +346,12 @@ int esm_proc_pdn_connectivity_request(int is_standalone, int pti, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_accept(esm_data_t *esm_data, int pti, esm_proc_pdn_type_t pdn_type, +int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, const OctetString *apn, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = _esm_data; int rc; int pid = RETURNerror; char apn_first_char[4]; @@ -438,7 +438,7 @@ int esm_proc_pdn_connectivity_accept(esm_data_t *esm_data, int pti, esm_proc_pdn ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause) +int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause) { LOG_FUNC_IN; @@ -489,7 +489,7 @@ int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_complete(void) +int esm_proc_pdn_connectivity_complete(nas_user_t *user) { LOG_FUNC_IN; @@ -530,7 +530,7 @@ int esm_proc_pdn_connectivity_complete(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_failure(int is_pending) +int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending) { LOG_FUNC_IN; @@ -603,6 +603,7 @@ int esm_proc_pdn_connectivity_failure(int is_pending) ** Others: None ** ** ** ***************************************************************************/ +// FIXME static void *_pdn_connectivity_t3482_handler(void *args) { LOG_FUNC_IN; @@ -610,7 +611,8 @@ static void *_pdn_connectivity_t3482_handler(void *args) int rc; /* Get retransmission timer parameters data */ - esm_pt_timer_data_t *data = (esm_pt_timer_data_t *)(args); + esm_pt_timer_data_t *data = args; + nas_user_t *user = data->user; /* Increment the retransmission counter */ data->count += 1; @@ -629,7 +631,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = data->msg.length; emm_esm->msg.value = data->msg.value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Restart the timer T3482 */ diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 082463aa46..18ffe34a99 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -168,7 +168,7 @@ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, un ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_request(int is_standalone, int pti, +int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue) { LOG_FUNC_IN; @@ -187,7 +187,7 @@ int esm_proc_pdn_disconnect_request(int is_standalone, int pti, emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Start T3482 retransmission timer */ @@ -284,10 +284,10 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause) +int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) { LOG_FUNC_IN; - + esm_data_t *esm_data = _esm_data; int rc; LOG_TRACE(WARNING, "ESM-PROC - PDN disconnection rejected by the network " @@ -331,7 +331,7 @@ int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); if (rc != RETURNok) { *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; @@ -383,7 +383,8 @@ static void *_pdn_disconnect_t3492_handler(void *args) { LOG_FUNC_IN; // FIXME check callback call - esm_data_t *esm_data = args;; + nas_user_t *user = args; + esm_data_t *esm_data = _esm_data;; int rc; /* Get retransmission timer parameters data */ @@ -406,7 +407,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = data->msg.length; emm_esm->msg.value = data->msg.value; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { /* Restart the timer T3492 */ @@ -449,7 +450,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } } } diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.c b/openair3/NAS/UE/ESM/SAP/esm_recv.c index 63262c6829..ecf9dedcbe 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.c +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.c @@ -135,7 +135,7 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg) ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_pdn_connectivity_reject(nas_user_t *user, int pti, int ebi, const pdn_connectivity_reject_msg *msg) { LOG_FUNC_IN; @@ -179,7 +179,7 @@ int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi, esm_cause = msg->esmcause; /* Execute the PDN connectivity procedure not accepted by the network */ - int rc = esm_proc_pdn_connectivity_reject(pti, &esm_cause); + int rc = esm_proc_pdn_connectivity_reject(user, pti, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; @@ -206,7 +206,7 @@ int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_pdn_disconnect_reject(nas_user_t *user, int pti, int ebi, const pdn_disconnect_reject_msg *msg) { LOG_FUNC_IN; @@ -250,7 +250,7 @@ int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi, esm_cause = msg->esmcause; /* Execute the PDN disconnect procedure not accepted by the network */ - int rc = esm_proc_pdn_disconnect_reject(esm_data, pti, &esm_cause); + int rc = esm_proc_pdn_disconnect_reject(user, pti, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; @@ -278,11 +278,10 @@ int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_default_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; - int esm_cause = ESM_CAUSE_SUCCESS; LOG_TRACE(INFO, "ESM-SAP - Received Activate Default EPS Bearer Context " @@ -369,14 +368,14 @@ int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, i } /* Execute the PDN connectivity procedure accepted by the network */ - int pid = esm_proc_pdn_connectivity_accept(esm_data, pti, pdn_type, + int pid = esm_proc_pdn_connectivity_accept(user, pti, pdn_type, &msg->pdnaddress.pdnaddressinformation, &msg->accesspointname.accesspointnamevalue, &esm_cause); if (pid != RETURNerror) { /* Create local default EPS bearer context */ - int rc = esm_proc_default_eps_bearer_context_request(esm_data, pid, ebi, &qos, + int rc = esm_proc_default_eps_bearer_context_request(user, pid, ebi, &qos, &esm_cause); if (rc != RETURNerror) { @@ -406,7 +405,7 @@ int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, i ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_dedicated_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; @@ -580,7 +579,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, } /* Execute the dedicated EPS bearer context activation procedure */ - int rc = esm_proc_dedicated_eps_bearer_context_request(esm_data, ebi, + int rc = esm_proc_dedicated_eps_bearer_context_request(user, ebi, msg->linkedepsbeareridentity, &qos, &tft, &esm_cause); @@ -614,7 +613,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, ** Others: None ** ** ** ***************************************************************************/ -int esm_recv_deactivate_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const deactivate_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; @@ -670,7 +669,7 @@ int esm_recv_deactivate_eps_bearer_context_request(esm_data_t *esm_data, int pti if (rc != RETURNerror) { /* Execute the EPS bearer context deactivation procedure */ - rc = esm_proc_eps_bearer_context_deactivate_request(esm_data, ebi, &esm_cause); + rc = esm_proc_eps_bearer_context_deactivate_request(user, ebi, &esm_cause); if (rc != RETURNerror) { esm_cause = ESM_CAUSE_SUCCESS; diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.h b/openair3/NAS/UE/ESM/SAP/esm_recv.h index f1641bd939..ae36d650e3 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.h +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.h @@ -42,6 +42,7 @@ Description Defines functions executed at the ESM Service Access #include "EsmStatus.h" #include "emmData.h" +#include "user_defs.h" #include "PdnConnectivityReject.h" #include "PdnDisconnectReject.h" @@ -88,23 +89,23 @@ int esm_recv_status(int pti, int ebi, const esm_status_msg *msg); * Transaction related messages * ---------------------------- */ -int esm_recv_pdn_connectivity_reject(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_pdn_connectivity_reject(nas_user_t *user, int pti, int ebi, const pdn_connectivity_reject_msg *msg); -int esm_recv_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_pdn_disconnect_reject(nas_user_t *user, int pti, int ebi, const pdn_disconnect_reject_msg *msg); /* * Messages related to EPS bearer contexts * --------------------------------------- */ -int esm_recv_activate_default_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_default_eps_bearer_context_request_msg *msg); -int esm_recv_activate_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const activate_dedicated_eps_bearer_context_request_msg *msg); -int esm_recv_deactivate_eps_bearer_context_request(esm_data_t *esm_data, int pti, int ebi, +int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, int ebi, const deactivate_eps_bearer_context_request_msg *msg); diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index ca9e0c2c6f..dbc6925175 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -63,10 +63,9 @@ Description Defines the ESM Service Access Points at which the EPS /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -// FIXME NOT SURE FOR THIS ONE -static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err); -static int _esm_sap_send(int msg_type, int is_standalone, int pti, int ebi, +static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp); @@ -145,7 +144,7 @@ void esm_sap_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int esm_sap_send(esm_sap_t *msg) +int esm_sap_send(nas_user_t *user, esm_sap_t *msg) { LOG_FUNC_IN; // FIXME @@ -193,7 +192,7 @@ int esm_sap_send(esm_sap_t *msg) if (rc != RETURNerror) { /* Send PDN connectivity request */ - rc = _esm_sap_send(PDN_CONNECTIVITY_REQUEST, + rc = _esm_sap_send(user, PDN_CONNECTIVITY_REQUEST, msg->is_standalone, pti, EPS_BEARER_IDENTITY_UNASSIGNED, &msg->data, &msg->send); @@ -214,11 +213,11 @@ int esm_sap_send(esm_sap_t *msg) pdn_connect->is_emergency, NULL); } else if (msg->recv != NULL) { /* The UE received a PDN connectivity reject message */ - rc = _esm_sap_recv(esm_data, PDN_CONNECTIVITY_REJECT, msg->is_standalone, + rc = _esm_sap_recv(user, PDN_CONNECTIVITY_REJECT, msg->is_standalone, msg->recv, &msg->send, &msg->err); } else { /* The PDN connectivity procedure locally failed */ - rc = esm_proc_pdn_connectivity_failure(TRUE); + rc = esm_proc_pdn_connectivity_failure(user, TRUE); } } break; @@ -234,7 +233,7 @@ int esm_sap_send(esm_sap_t *msg) if (rc != RETURNerror) { /* Send PDN disconnect request */ - rc = _esm_sap_send(PDN_DISCONNECT_REQUEST, TRUE, pti, ebi, + rc = _esm_sap_send(user, PDN_DISCONNECT_REQUEST, TRUE, pti, ebi, &msg->data, &msg->send); } } @@ -257,7 +256,7 @@ int esm_sap_send(esm_sap_t *msg) case ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ: /* The UE received activate default ESP bearer context request */ - rc = _esm_sap_recv(esm_data, ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, + rc = _esm_sap_recv(user, ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, msg->is_standalone, msg->recv, &msg->send, &msg->err); break; @@ -270,7 +269,7 @@ int esm_sap_send(esm_sap_t *msg) rc = esm_proc_default_eps_bearer_context_complete(); if (rc != RETURNerror) { - rc = esm_proc_pdn_connectivity_complete(); + rc = esm_proc_pdn_connectivity_complete(user); } break; @@ -279,10 +278,10 @@ int esm_sap_send(esm_sap_t *msg) /* * Default ESP bearer context activation procedure locally failed */ - rc = esm_proc_default_eps_bearer_context_failure(esm_data); + rc = esm_proc_default_eps_bearer_context_failure(user); if (rc != RETURNerror) { - rc = esm_proc_pdn_connectivity_failure(FALSE); + rc = esm_proc_pdn_connectivity_failure(user, FALSE); } break; @@ -310,7 +309,7 @@ int esm_sap_send(esm_sap_t *msg) /* * Locally deactivate EPS bearer context */ - rc = esm_proc_eps_bearer_context_deactivate(esm_data, TRUE, + rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, msg->data.eps_bearer_context_deactivate.ebi, &pid, &bid); } break; @@ -319,7 +318,7 @@ int esm_sap_send(esm_sap_t *msg) break; case ESM_UNITDATA_IND: - rc = _esm_sap_recv(esm_data, -1, msg->is_standalone, msg->recv, + rc = _esm_sap_recv(user, -1, msg->is_standalone, msg->recv, &msg->send, &msg->err); break; @@ -364,7 +363,7 @@ int esm_sap_send(esm_sap_t *msg) ** Others: _esm_sap_buffer ** ** ** ***************************************************************************/ -static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err) { @@ -442,7 +441,7 @@ static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, * received from the MME */ esm_cause = esm_recv_activate_default_eps_bearer_context_request( - esm_data, pti, ebi, + user, pti, ebi, &esm_msg.activate_default_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_SUCCESS) || @@ -480,7 +479,7 @@ static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, * received from the MME */ esm_cause = esm_recv_activate_dedicated_eps_bearer_context_request( - esm_data, pti, ebi, + user, pti, ebi, &esm_msg.activate_dedicated_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_SUCCESS) || @@ -520,7 +519,7 @@ static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, * Process deactivate EPS bearer context request message * received from the MME */ - esm_cause = esm_recv_deactivate_eps_bearer_context_request(esm_data, pti, ebi, + esm_cause = esm_recv_deactivate_eps_bearer_context_request(user, pti, ebi, &esm_msg.deactivate_eps_bearer_context_request); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -556,7 +555,7 @@ static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, /* * Process PDN connectivity reject message received from the MME */ - esm_cause = esm_recv_pdn_connectivity_reject(esm_data, pti, ebi, + esm_cause = esm_recv_pdn_connectivity_reject(user, pti, ebi, &esm_msg.pdn_connectivity_reject); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -579,7 +578,7 @@ static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, /* * Process PDN disconnect reject message received from the MME */ - esm_cause = esm_recv_pdn_disconnect_reject(esm_data, pti, ebi, + esm_cause = esm_recv_pdn_disconnect_reject(user, pti, ebi, &esm_msg.pdn_disconnect_reject); if ( (esm_cause == ESM_CAUSE_INVALID_PTI_VALUE) || @@ -653,7 +652,7 @@ static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, } /* Complete the relevant ESM procedure */ - rc = (*esm_procedure)(is_standalone, ebi, rsp, triggered_by_ue); + rc = (*esm_procedure)(user, is_standalone, ebi, rsp, triggered_by_ue); if (is_discarded) { /* Return indication that received message has been discarded */ @@ -696,7 +695,7 @@ static int _esm_sap_recv(esm_data_t *esm_data, int msg_type, int is_standalone, ** Others: _esm_sap_buffer ** ** ** ***************************************************************************/ -static int _esm_sap_send(int msg_type, int is_standalone, +static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp) { @@ -784,7 +783,7 @@ static int _esm_sap_send(int msg_type, int is_standalone, /* Execute the relevant ESM procedure */ if (esm_procedure) { - rc = (*esm_procedure)(is_standalone, pti, rsp, sent_by_ue); + rc = (*esm_procedure)(user, is_standalone, pti, rsp, sent_by_ue); } } diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.h b/openair3/NAS/UE/ESM/SAP/esm_sap.h index 7364a4b661..b464e18900 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.h +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.h @@ -41,6 +41,7 @@ Description Defines the ESM Service Access Points at which the EPS #define __ESM_SAP_H__ #include "esm_sapDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -60,6 +61,6 @@ Description Defines the ESM Service Access Points at which the EPS void esm_sap_initialize(void); -int esm_sap_send(esm_sap_t *msg); +int esm_sap_send(nas_user_t *user, esm_sap_t *msg); #endif /* __ESM_SAP_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 48b8c83bba..d678ad2ec5 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -330,8 +330,7 @@ int esm_ebr_context_create( ** Others: _esm_data ** ** ** ***************************************************************************/ -int esm_ebr_context_release( - esm_data_t *esm_data, +int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid) { int found = FALSE; @@ -342,7 +341,7 @@ int esm_ebr_context_release( LOG_FUNC_IN; - esm_ctx = esm_data; + esm_ctx = _esm_data; if (ebi != ESM_EBI_UNASSIGNED) { /* @@ -492,7 +491,7 @@ int esm_ebr_context_release( emm_sap_t emm_sap; emm_sap.primitive = EMMESM_ESTABLISH_CNF; emm_sap.u.emm_esm.u.establish.is_attached = FALSE; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); } /* 3GPP TS 24.301, section 6.4.4.3, 6.4.4.6 * If due to the EPS bearer context deactivation only the PDN @@ -505,7 +504,7 @@ int esm_ebr_context_release( emm_sap.primitive = EMMESM_ESTABLISH_CNF; emm_sap.u.emm_esm.u.establish.is_attached = TRUE; emm_sap.u.emm_esm.u.establish.is_emergency = TRUE; - (void) emm_sap_send(&emm_sap); + (void) emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (ebi); diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.h b/openair3/NAS/UE/ESM/esm_ebr_context.h index 739ee0d3fe..ceb6553846 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.h +++ b/openair3/NAS/UE/ESM/esm_ebr_context.h @@ -39,6 +39,7 @@ Description Defines functions used to handle EPS bearer contexts. #define __ESM_EBR_CONTEXT_H__ #include "networkDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -68,7 +69,7 @@ typedef enum { int esm_ebr_context_create(esm_data_t *esm_data, int pid, int ebi, int is_default, const network_qos_t *qos, const network_tft_t *tft); -int esm_ebr_context_release(esm_data_t *esm_data, int ebi, int *pid, int *bid); +int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid); int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi); diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h index 7f29166bbf..9b533c6117 100644 --- a/openair3/NAS/UE/ESM/esm_proc.h +++ b/openair3/NAS/UE/ESM/esm_proc.h @@ -43,6 +43,7 @@ Description Defines the EPS Session Management procedures executed at #include "OctetString.h" #include "emmData.h" #include "ProtocolConfigurationOptions.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -78,7 +79,7 @@ typedef enum { * Type of the ESM procedure callback executed when requested by the UE * or initiated by the network */ -typedef int (*esm_proc_procedure_t) (int, int, OctetString *, int); +typedef int (*esm_proc_procedure_t) (nas_user_t *user, int, int, OctetString *, int); /* EPS bearer level QoS parameters */ typedef network_qos_t esm_proc_qos_t; @@ -112,7 +113,7 @@ typedef struct { * -------------------------------------------------------------------------- */ int esm_proc_status_ind(int pti, int ebi, int *esm_cause); -int esm_proc_status(int is_standalone, int pti, OctetString *msg, +int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue); @@ -124,13 +125,13 @@ int esm_proc_status(int is_standalone, int pti, OctetString *msg, int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int to_define, esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, unsigned int *pti); -int esm_proc_pdn_connectivity_request(int is_standalone, int pti, +int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue); -int esm_proc_pdn_connectivity_accept(esm_data_t *esm_data, int pti, esm_proc_pdn_type_t pdn_type, +int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_address, const OctetString *apn, int *esm_cause); -int esm_proc_pdn_connectivity_reject(int pti, int *esm_cause); -int esm_proc_pdn_connectivity_complete(void); -int esm_proc_pdn_connectivity_failure(int is_pending); +int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause); +int esm_proc_pdn_connectivity_complete(nas_user_t *user); +int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending); /* @@ -139,11 +140,11 @@ int esm_proc_pdn_connectivity_failure(int is_pending); * -------------------------------------------------------------------------- */ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi); -int esm_proc_pdn_disconnect_request(int is_standalone, int pti, +int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue); int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause); -int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause); +int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause); /* * -------------------------------------------------------------------------- @@ -151,14 +152,14 @@ int esm_proc_pdn_disconnect_reject(esm_data_t *esm_data, int pti, int *esm_cause * -------------------------------------------------------------------------- */ -int esm_proc_default_eps_bearer_context_request(esm_data_t *esm_data, int pid, int ebi, +int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int ebi, const esm_proc_qos_t *esm_qos, int *esm_cause); int esm_proc_default_eps_bearer_context_complete(void); -int esm_proc_default_eps_bearer_context_failure(esm_data_t *esm_data); +int esm_proc_default_eps_bearer_context_failure(nas_user_t *user); -int esm_proc_default_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); -int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); /* @@ -167,12 +168,12 @@ int esm_proc_default_eps_bearer_context_reject(int is_standalone, int ebi, * -------------------------------------------------------------------------- */ -int esm_proc_dedicated_eps_bearer_context_request(esm_data_t *esm_data, int ebi, int default_ebi, +int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause); -int esm_proc_dedicated_eps_bearer_context_accept(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); -int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); /* @@ -181,11 +182,11 @@ int esm_proc_dedicated_eps_bearer_context_reject(int is_standalone, int ebi, * -------------------------------------------------------------------------- */ -int esm_proc_eps_bearer_context_deactivate(esm_data_t *esm_data, int is_local, int ebi, int *pid, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, int *pid, int *bid); -int esm_proc_eps_bearer_context_deactivate_request(esm_data_t *esm_data, int ebi, int *esm_cause); +int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, int *esm_cause); -int esm_proc_eps_bearer_context_deactivate_accept(int is_standalone, int ebi, +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, OctetString *msg, int ue_triggered); #endif /* __ESM_PROC_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index 8e819fbd0b..1d8c8bc525 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -308,6 +308,7 @@ int esm_pt_start_timer(int pti, const OctetString *msg, * time interval */ ctx->timer.id = nas_timer_start(sec, cb, ctx->args); ctx->timer.sec = sec; + // FIXME add user } } diff --git a/openair3/NAS/UE/ESM/esm_pt.h b/openair3/NAS/UE/ESM/esm_pt.h index 7cc0c54780..c39d7f98bd 100644 --- a/openair3/NAS/UE/ESM/esm_pt.h +++ b/openair3/NAS/UE/ESM/esm_pt.h @@ -40,6 +40,7 @@ Description Defines functions used to handle ESM procedure transactions. #include "OctetString.h" #include "nas_timer.h" +#include "user_defs.h" #include "ProcedureTransactionIdentity.h" @@ -67,6 +68,7 @@ typedef struct { unsigned char pti; /* Procedure transaction identity */ unsigned int count; /* Retransmission counter */ OctetString msg; /* Encoded ESM message to re-transmit */ + nas_user_t *user; /* user reference */ } esm_pt_timer_data_t; /****************************************************************************/ diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 17397a01a9..112ac62de2 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -98,7 +98,7 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->proc.rsrp = NAS_PROC_RSRP_UNKNOWN; /* Initialize the EMM procedure manager */ - emm_main_initialize(emm_cb, imei); + emm_main_initialize(user, emm_cb, imei); /* Initialize the ESM procedure manager */ _esm_data = esm_main_initialize(esm_cb); @@ -175,7 +175,7 @@ int nas_proc_enable_s1_mode(nas_user_t *user) */ user->proc.EPS_capability_status = TRUE; emm_sap.primitive = EMMREG_S1_ENABLED; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -208,7 +208,7 @@ int nas_proc_disable_s1_mode(nas_user_t *user) */ user->proc.EPS_capability_status = FALSE; emm_sap.primitive = EMMREG_S1_DISABLED; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -396,7 +396,7 @@ int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn emm_sap_t emm_sap; emm_sap.primitive = EMMREG_REGISTER_REQ; emm_sap.u.emm_reg.u.regist.index = index; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -574,7 +574,7 @@ int nas_proc_detach(nas_user_t *user, int switch_off) /* Initiate an Detach procedure */ emm_sap.primitive = EMMREG_DETACH_INIT; emm_sap.u.emm_reg.u.detach.switch_off = switch_off; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -605,7 +605,7 @@ int nas_proc_attach(nas_user_t *user) /* Initiate an Attach procedure */ emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = FALSE; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -852,7 +852,7 @@ int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int i * Notify ESM that a new PDN context has to be defined for * the specified APN */ - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -885,7 +885,7 @@ int nas_proc_reset_pdn(nas_user_t *user, int cid) /* * Notify ESM that the specified PDN context has to be undefined */ - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -1034,7 +1034,7 @@ int nas_proc_cell_info(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t Ac emm_sap.u.emm_as.u.cell_info.tac = tac; emm_sap.u.emm_as.u.cell_info.cellID = ci; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1071,7 +1071,7 @@ int nas_proc_establish_cnf(nas_user_t *user, const Byte_t *data, uint32_t len) emm_sap.primitive = EMMAS_ESTABLISH_CNF; emm_sap.u.emm_as.u.establish.NASmsg.length = len; emm_sap.u.emm_as.u.establish.NASmsg.value = (uint8_t *)data; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1106,7 +1106,7 @@ int nas_proc_establish_rej(nas_user_t *user) * from lower layers */ emm_sap.primitive = EMMAS_ESTABLISH_REJ; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1139,7 +1139,7 @@ int nas_proc_release_ind(nas_user_t *user, int cause) */ emm_sap.primitive = EMMAS_RELEASE_IND; emm_sap.u.emm_as.u.release.cause = cause; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1176,7 +1176,7 @@ int nas_proc_ul_transfer_cnf(nas_user_t *user) emm_sap.u.emm_as.u.data.ueid = 0; emm_sap.u.emm_as.u.data.delivered = TRUE; emm_sap.u.emm_as.u.data.NASmsg.length = 0; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1213,7 +1213,7 @@ int nas_proc_ul_transfer_rej(nas_user_t *user) emm_sap.u.emm_as.u.data.ueid = 0; emm_sap.u.emm_as.u.data.delivered = FALSE; emm_sap.u.emm_as.u.data.NASmsg.length = 0; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); } @@ -1251,7 +1251,7 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) emm_sap.u.emm_as.u.data.delivered = TRUE; emm_sap.u.emm_as.u.data.NASmsg.length = len; emm_sap.u.emm_as.u.data.NASmsg.value = (uint8_t *)data; - rc = emm_sap_send(&emm_sap); + rc = emm_sap_send(user, &emm_sap); } LOG_FUNC_RETURN (rc); @@ -1332,7 +1332,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) esm_sap.is_standalone = TRUE; esm_sap.data.pdn_connect.is_defined = TRUE; esm_sap.data.pdn_connect.cid = cid; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); LOG_FUNC_RETURN (rc); } @@ -1391,7 +1391,7 @@ static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_DISCONNECT_REQ; esm_sap.data.pdn_disconnect.cid = cid; - rc = esm_sap_send(&esm_sap); + rc = esm_sap_send(user, &esm_sap); } else { /* For EPS, if an attempt is made to disconnect the last PDN * connection, then the MT responds with an error */ From 55364a8860da95c883e46c703978bdbe62aabbe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 11 Jul 2016 15:59:45 +0200 Subject: [PATCH 142/571] UE/ESM: fix esm_pt_start_timer callback --- openair3/NAS/UE/ESM/PdnConnectivity.c | 4 ++-- openair3/NAS/UE/ESM/PdnDisconnect.c | 5 ++--- openair3/NAS/UE/ESM/esm_pt.c | 4 ++-- openair3/NAS/UE/ESM/esm_pt.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 161e88669a..957e8279ab 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -302,7 +302,7 @@ int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int p if (rc != RETURNerror) { /* Start T3482 retransmission timer */ - rc = esm_pt_start_timer(pti, msg, T3482_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, pti, msg, T3482_DEFAULT_VALUE, _pdn_connectivity_t3482_handler); } } @@ -635,7 +635,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) if (rc != RETURNerror) { /* Restart the timer T3482 */ - rc = esm_pt_start_timer(data->pti, &data->msg, T3482_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, data->pti, &data->msg, T3482_DEFAULT_VALUE, _pdn_connectivity_t3482_handler); } } else { diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 18ffe34a99..0eb51d753c 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -191,7 +191,7 @@ int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti if (rc != RETURNerror) { /* Start T3482 retransmission timer */ - rc = esm_pt_start_timer(pti, msg, T3492_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, pti, msg, T3492_DEFAULT_VALUE, _pdn_disconnect_t3492_handler); } } @@ -382,7 +382,6 @@ int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) static void *_pdn_disconnect_t3492_handler(void *args) { LOG_FUNC_IN; - // FIXME check callback call nas_user_t *user = args; esm_data_t *esm_data = _esm_data;; int rc; @@ -411,7 +410,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) if (rc != RETURNerror) { /* Restart the timer T3492 */ - rc = esm_pt_start_timer(data->pti, &data->msg, T3492_DEFAULT_VALUE, + rc = esm_pt_start_timer(user, data->pti, &data->msg, T3492_DEFAULT_VALUE, _pdn_disconnect_t3492_handler); } } else { diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index 1d8c8bc525..fa9adb0b6e 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -264,7 +264,7 @@ int esm_pt_release(int pti) ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_start_timer(int pti, const OctetString *msg, +int esm_pt_start_timer(nas_user_t *user, int pti, const OctetString *msg, long sec, nas_timer_callback_t cb) { LOG_FUNC_IN; @@ -291,6 +291,7 @@ int esm_pt_start_timer(int pti, const OctetString *msg, ctx->args = (esm_pt_timer_data_t *)malloc(sizeof(esm_pt_timer_data_t)); if (ctx->args) { + ctx->args->user = user; /* Set the EPS bearer identity */ ctx->args->pti = pti; /* Reset the retransmission counter */ @@ -308,7 +309,6 @@ int esm_pt_start_timer(int pti, const OctetString *msg, * time interval */ ctx->timer.id = nas_timer_start(sec, cb, ctx->args); ctx->timer.sec = sec; - // FIXME add user } } diff --git a/openair3/NAS/UE/ESM/esm_pt.h b/openair3/NAS/UE/ESM/esm_pt.h index c39d7f98bd..a4a3de7651 100644 --- a/openair3/NAS/UE/ESM/esm_pt.h +++ b/openair3/NAS/UE/ESM/esm_pt.h @@ -86,7 +86,7 @@ void esm_pt_initialize(void); int esm_pt_assign(void); int esm_pt_release(int pti); -int esm_pt_start_timer(int pti, const OctetString *msg, long sec, +int esm_pt_start_timer(nas_user_t *user, int pti, const OctetString *msg, long sec, nas_timer_callback_t cb); int esm_pt_stop_timer(int pti); From 844a8af418f74768dad16b7fbf564e6bb3c5614a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 11 Jul 2016 16:20:34 +0200 Subject: [PATCH 143/571] UE/ESM: move _esm_data to nas_user_t --- .../ESM/DedicatedEpsBearerContextActivation.c | 2 +- .../ESM/DefaultEpsBearerContextActivation.c | 2 +- .../NAS/UE/ESM/EpsBearerContextDeactivation.c | 5 ++--- openair3/NAS/UE/ESM/PdnConnectivity.c | 11 +--------- openair3/NAS/UE/ESM/PdnDisconnect.c | 6 ++--- openair3/NAS/UE/ESM/SAP/esm_sap.c | 3 +-- openair3/NAS/UE/ESM/esmData.h | 6 ----- openair3/NAS/UE/ESM/esm_ebr_context.c | 8 +------ openair3/NAS/UE/ESM/esm_main.c | 9 -------- openair3/NAS/UE/nas_proc.c | 22 +++++++++---------- openair3/NAS/UE/nas_user.c | 6 ++--- openair3/NAS/UE/user_defs.h | 2 ++ 12 files changed, 25 insertions(+), 57 deletions(-) diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 1863b14a34..55008d7dac 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -110,7 +110,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int int *esm_cause) { LOG_FUNC_IN; - esm_data_t *esm_data = _esm_data; + esm_data_t *esm_data = user->esm_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - Dedicated EPS bearer context activation " diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 21dc81cdf5..a5e70703ed 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -109,7 +109,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e int *esm_cause) { LOG_FUNC_IN; - esm_data_t *esm_data = _esm_data; + esm_data_t *esm_data = user->esm_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - Default EPS bearer context activation " diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index 2bafb9c18e..fdba605f1e 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -102,7 +102,6 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid); ** gnalling between the UE and the MME ** ** ebi: EPS bearer identity of the EPS bearer con- ** ** text to be deactivated ** - ** Others: _esm_data ** ** ** ** Outputs: pid: Identifier of the PDN connection the EPS ** ** bearer belongs to ** @@ -119,7 +118,7 @@ int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int e int rc = RETURNerror; int i; - esm_data_t *esm_data = _esm_data; + esm_data_t *esm_data = user->esm_data; if (is_local) { if (ebi != ESM_SAP_ALL_EBI) { /* Locally release the EPS bearer context */ @@ -195,7 +194,7 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in int pid, bid; int rc = RETURNok; - esm_data_t *esm_data = _esm_data; + esm_data_t *esm_data = user->esm_data; LOG_TRACE(INFO, "ESM-PROC - EPS bearer context deactivation " "requested by the network (ebi=%d)", ebi); diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 957e8279ab..bcb32dddcb 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -131,7 +131,6 @@ static void *_pdn_connectivity_t3482_handler(void *); ** the new PDN connection or the released PDN ** ** connection ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define, @@ -351,7 +350,7 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ const OctetString *apn, int *esm_cause) { LOG_FUNC_IN; - esm_data_t *esm_data = _esm_data; + esm_data_t *esm_data = user->esm_data; int rc; int pid = RETURNerror; char apn_first_char[4]; @@ -678,11 +677,9 @@ static void *_pdn_connectivity_t3482_handler(void *args) ** pdn_type: PDN type (IPv4, IPv6, IPv4v6) ** ** is_emergency: TRUE if the PDN connection has to be esta- ** ** blished for emergency bearer services ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, @@ -762,7 +759,6 @@ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetSt ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn, @@ -849,14 +845,12 @@ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetSt ** ** ** Inputs: pid: Identifier of the PDN connection to be ** ** released ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identity of the procedure transaction ** ** assigned to the PDN connection when suc- ** ** cessfully released; ** ** UNASSIGNED value otherwise. ** - ** Others: _esm_data ** ** ** ***************************************************************************/ static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid) @@ -912,7 +906,6 @@ static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_data ** ** ** ***************************************************************************/ static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti) @@ -945,7 +938,6 @@ static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti) ** for the specified APN ** ** ** ** Inputs: apn: Access Point Name of the PDN connection ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identifier of the PDN connection if ** @@ -986,7 +978,6 @@ static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *a ** ** ** Inputs: apn: Access Point Name of the PDN connection ** ** pdn_type: PDN address type ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identifier of the PDN connection if ** diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 0eb51d753c..c8b3722d07 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -104,7 +104,6 @@ static void *_pdn_disconnect_t3492_handler(void *); ** tifier ** ** ** ** Inputs: cid: PDN context identifier ** - ** Others: _esm_data ** ** ** ** Outputs: pti: Procedure transaction identity assigned to ** ** the PDN connection to be released ** @@ -287,7 +286,7 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) { LOG_FUNC_IN; - esm_data_t *esm_data = _esm_data; + esm_data_t *esm_data = user->esm_data; int rc; LOG_TRACE(WARNING, "ESM-PROC - PDN disconnection rejected by the network " @@ -383,7 +382,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) { LOG_FUNC_IN; nas_user_t *user = args; - esm_data_t *esm_data = _esm_data;; + esm_data_t *esm_data = user->esm_data;; int rc; /* Get retransmission timer parameters data */ @@ -472,7 +471,6 @@ static void *_pdn_disconnect_t3492_handler(void *args) ** ven procedure transaction identity has been assigned ** ** ** ** Inputs: pti: The procedure transaction identity ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The EPS bearer identity of the default EPS ** diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index dbc6925175..5b6f52916f 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -147,8 +147,7 @@ void esm_sap_initialize(void) int esm_sap_send(nas_user_t *user, esm_sap_t *msg) { LOG_FUNC_IN; - // FIXME - esm_data_t *esm_data = _esm_data; + esm_data_t *esm_data = user->esm_data; int rc = RETURNerror; int pid; diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 857d6dc3bd..7977e3a3af 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -190,12 +190,6 @@ typedef esm_data_context_t esm_data_t; /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ -/* - * ESM internal data (used within ESM only) - * ---------------------------------------- - */ -extern esm_data_t *_esm_data; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index d678ad2ec5..00950428bb 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -89,14 +89,12 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ** bearer context ** ** esm_qos: EPS bearer level QoS parameters ** ** tft: Traffic flow template parameters ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The EPS bearer identity of the default EPS ** ** bearer associated to the new EPS bearer ** ** context if successfully created; ** ** UNASSIGN EPS bearer value otherwise. ** - ** Others: _esm_data ** ** ** ***************************************************************************/ int esm_ebr_context_create( @@ -318,7 +316,6 @@ int esm_ebr_context_create( ** ** ** Inputs: ueid: UE identifier ** ** ebi: EPS bearer identity ** - ** Others: _esm_data ** ** ** ** Outputs: pid: Identifier of the PDN connection entry the ** ** EPS bearer context belongs to ** @@ -327,7 +324,6 @@ int esm_ebr_context_create( ** Return: The EPS bearer identity associated to the ** ** EPS bearer context if successfully relea- ** ** sed; UNASSIGN EPS bearer value otherwise. ** - ** Others: _esm_data ** ** ** ***************************************************************************/ int esm_ebr_context_release(nas_user_t *user, @@ -341,7 +337,7 @@ int esm_ebr_context_release(nas_user_t *user, LOG_FUNC_IN; - esm_ctx = _esm_data; + esm_ctx = user->esm_data; if (ebi != ESM_EBI_UNASSIGNED) { /* @@ -523,7 +519,6 @@ int esm_ebr_context_release(nas_user_t *user, ** ** ** Inputs: ebi: The EPS bearer identity of the default EPS ** ** bearer context ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: The identifier of the PDN connection entry ** @@ -575,7 +570,6 @@ int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi) ** tft: The traffic flow template (set of packet ** ** filters) to be checked ** ** operation: Traffic flow template operation ** - ** Others: _esm_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index b56988f025..af59724157 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -50,8 +50,6 @@ Description Defines the EPS Session Management procedure call manager, /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -esm_data_t *_esm_data = NULL; - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -71,7 +69,6 @@ esm_data_t *_esm_data = NULL; ** ** ** Outputs: None ** ** Return: None ** - ** Others: esm_data-> ** ** ** ***************************************************************************/ esm_data_t * esm_main_initialize(esm_indication_callback_t cb) @@ -176,7 +173,6 @@ void esm_main_cleanup(esm_data_t *esm_data) ** a defined state at the same time ** ** ** ** Inputs: None ** - ** Others: esm_data-> ** ** ** ** Outputs: None ** ** Return: The maximum number of PDN connections that ** @@ -198,7 +194,6 @@ int esm_main_get_nb_pdns_max(esm_data_t *esm_data) ** Description: Get the number of active PDN connections ** ** ** ** Inputs: None ** - ** Others: esm_data-> ** ** ** ** Outputs: None ** ** Return: The number of active PDN connections ** @@ -220,7 +215,6 @@ int esm_main_get_nb_pdns(esm_data_t *esm_data) ** vices is established ** ** ** ** Inputs: None ** - ** Others: esm_data-> ** ** ** ** Outputs: None ** ** Return: TRUE if a PDN connection for emergency ** @@ -242,7 +236,6 @@ int esm_main_has_emergency(esm_data_t *esm_data) ** Description: Get the status of the specified PDN connection ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: esm_data-> ** ** ** ** Outputs: state: TRUE if the current state of the PDN con- ** ** nection is ACTIVE; FALSE otherwise. ** @@ -288,7 +281,6 @@ int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state) ** Description: Get parameters defined for the specified PDN connection ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: esm_data-> ** ** ** ** Outputs: type: PDN connection type (IPv4, IPv6, IPv4v6) ** ** apn: Access Point logical Name in used ** @@ -342,7 +334,6 @@ int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, ** tion ** ** ** ** Inputs: cid: PDN connection identifier ** - ** Others: esm_data-> ** ** ** ** Outputs: ipv4adddr: IPv4 address ** ** ipv6adddr: IPv6 address ** diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 112ac62de2..fc52843df9 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -101,7 +101,7 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, emm_main_initialize(user, emm_cb, imei); /* Initialize the ESM procedure manager */ - _esm_data = esm_main_initialize(esm_cb); + user->esm_data = esm_main_initialize(esm_cb); LOG_FUNC_OUT; } @@ -137,7 +137,7 @@ void nas_proc_cleanup(nas_user_t *user) emm_main_cleanup(); /* Perform the EPS Session Manager's clean up procedure */ - esm_main_cleanup(_esm_data); + esm_main_cleanup(user->esm_data); LOG_FUNC_OUT; } @@ -780,7 +780,7 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add if (cid > 0) { /* Get addresses assigned to the specified PDN */ - rc = esm_main_get_pdn_addr(_esm_data, cid, addr1, addr2); + rc = esm_main_get_pdn_addr(user->esm_data, cid, addr1, addr2); if (rc != RETURNerror) { *cids = cid; @@ -788,12 +788,12 @@ int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **add } } else if (cid < 0) { /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(_esm_data); + int n_pdn = esm_main_get_nb_pdns_max(user->esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get PDN connection addresses */ - rc = esm_main_get_pdn_addr(_esm_data, cid, addr1, addr2); + rc = esm_main_get_pdn_addr(user->esm_data, cid, addr1, addr2); if (rc != RETURNerror) { /* This PDN has been defined */ @@ -920,7 +920,7 @@ int nas_proc_deactivate_pdn(nas_user_t *user, int cid) cid = 2; /* Deactivate all active PDN contexts */ - while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(_esm_data)+1)) { + while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { rc = _nas_proc_deactivate(user, cid++, TRUE); } } @@ -972,7 +972,7 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid) cid = 1; /* Activate all defined PDN contexts */ - while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(_esm_data)+1)) { + while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { rc = _nas_proc_activate(user, cid++, TRUE); } } @@ -1291,7 +1291,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) esm_sap_t esm_sap; /* Get PDN context parameters */ - rc = esm_main_get_pdn(_esm_data, cid, &esm_sap.data.pdn_connect.pdn_type, + rc = esm_main_get_pdn(user->esm_data, cid, &esm_sap.data.pdn_connect.pdn_type, &esm_sap.data.pdn_connect.apn, &esm_sap.data.pdn_connect.is_emergency, &active); @@ -1313,7 +1313,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) } if (esm_sap.data.pdn_connect.is_emergency) { - if (esm_main_has_emergency(_esm_data)) { + if (esm_main_has_emergency(user->esm_data)) { /* There is already a PDN connection for emergency * bearer services established; the UE shall not * request an additional PDN connection for emer- @@ -1365,7 +1365,7 @@ static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) int active = FALSE; /* Get PDN context parameters */ - rc = esm_main_get_pdn(_esm_data, cid, &pdn_type, &apn, &emergency, &active); + rc = esm_main_get_pdn(user->esm_data, cid, &pdn_type, &apn, &emergency, &active); if (rc != RETURNok) { /* No any context is defined for the specified PDN */ @@ -1383,7 +1383,7 @@ static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) LOG_FUNC_RETURN (RETURNok); } - if (esm_main_get_nb_pdns(_esm_data) > 1) { + if (esm_main_get_nb_pdns(user->esm_data) > 1) { /* * Notify ESM that all EPS bearers towards the specified PDN * has to be released diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index f0fcae59c6..909c82a393 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -2043,7 +2043,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) * Read command returns the current settings for each * defined PDN connection/default EPS bearer context */ - cgdcont->n_pdns = nas_proc_get_pdn_param(_esm_data, cgdcont->cid, + cgdcont->n_pdns = nas_proc_get_pdn_param(user->esm_data, cgdcont->cid, cgdcont->PDP_type, cgdcont->APN, AT_CGDCONT_RESP_SIZE); @@ -2061,7 +2061,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) */ { /* Get the maximum value of a PDN context identifier */ - int cid_max = nas_proc_get_pdn_range(_esm_data); + int cid_max = nas_proc_get_pdn_range(user->esm_data); if (cid_max > AT_CGDCONT_RESP_SIZE) { /* The range is defined by the user interface */ @@ -2184,7 +2184,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) * The read command returns the current activation states for * all the defined PDN/EPS bearer contexts */ - cgact->n_pdns = nas_proc_get_pdn_status(_esm_data, cgact->cid, cgact->state, + cgact->n_pdns = nas_proc_get_pdn_status(user->esm_data, cgact->cid, cgact->state, AT_CGACT_RESP_SIZE); if (cgact->n_pdns == 0) { diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index b448a38f7f..f4be31e187 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -46,10 +46,12 @@ Description NAS type definition to manage a user equipment #define __USER_DEFS_H__ #include "nas_proc_defs.h" +#include "esmData.h" typedef struct { int fd; proc_data_t proc; + esm_data_t *esm_data; // ESM internal data (used within ESM only) } nas_user_t; #endif From e6b5e1c34d42d2b82d0b1b46911118feb87d5693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 08:28:10 +0200 Subject: [PATCH 144/571] UE: fix at_nas_ue compilation --- cmake_targets/at_commands/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index ca9a305463..a459649081 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -215,8 +215,8 @@ set(api_user_HDR add_library(api_user ${api_user_SRC} ${api_user_HDR}) target_include_directories(api_user PRIVATE ${OPENAIR_NAS_DIR}/UE/API/USER - ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/COMMON + ${OPENAIR_NAS_DIR}/UE ) ################################################################################ @@ -397,6 +397,7 @@ target_include_directories(emm PRIVATE ${OPENAIR_DIR}/common/utils/msc ${OPENAIR_DIR}/common/utils ${OPENAIR_DIR}/openair2/COMMON + ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/UE/API/USIM ${OPENAIR_NAS_DIR}/UE/EMM ${OPENAIR_NAS_DIR}/COMMON/EMM/MSG @@ -486,6 +487,7 @@ set(esm_HDR add_library(esm ${esm_SRC} ${esm_HDR}) target_include_directories(esm PRIVATE + ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/UE/API/USER ${OPENAIR_NAS_DIR}/UE/ESM ${OPENAIR_NAS_DIR}/COMMON/ESM/MSG @@ -670,6 +672,7 @@ target_include_directories(ies PRIVATE # EXECUTABLE at_nas_ue ################################################################################ include_directories( + ${OPENAIR_NAS_DIR}/UE ${OPENAIR_DIR}/common/utils/msc ${OPENAIR3_DIR}/COMMON ${OPENAIR3_DIR}/SECU From 73937668f0169800ba6ab44915748288029a5a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 10:17:55 +0200 Subject: [PATCH 145/571] UE/ESM: move _esm_pt_data to nas_user_t --- openair3/NAS/UE/ESM/PdnConnectivity.c | 46 +++++---- openair3/NAS/UE/ESM/PdnDisconnect.c | 22 ++--- openair3/NAS/UE/ESM/SAP/esm_recv.c | 16 ++-- openair3/NAS/UE/ESM/SAP/esm_sap.c | 6 +- openair3/NAS/UE/ESM/esmData.h | 1 - openair3/NAS/UE/ESM/esm_main.c | 7 +- openair3/NAS/UE/ESM/esm_main.h | 3 +- openair3/NAS/UE/ESM/esm_proc.h | 4 +- openair3/NAS/UE/ESM/esm_pt.c | 133 ++++++++++---------------- openair3/NAS/UE/ESM/esm_pt.h | 33 ++----- openair3/NAS/UE/ESM/esm_pt_defs.h | 63 ++++++++++++ openair3/NAS/UE/nas_proc.c | 2 +- openair3/NAS/UE/user_defs.h | 2 + 13 files changed, 182 insertions(+), 156 deletions(-) create mode 100644 openair3/NAS/UE/ESM/esm_pt_defs.h diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index bcb32dddcb..15ec49b2d0 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -133,7 +133,7 @@ static void *_pdn_connectivity_t3482_handler(void *); ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define, +int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, unsigned int *pti) @@ -142,6 +142,8 @@ int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define, int rc = RETURNerror; int pid = cid - 1; + esm_data_t *esm_data = user-> esm_data; + esm_pt_data_t *esm_pt_data = user-> esm_pt_data; if (!is_to_define) { LOG_TRACE(INFO, "ESM-PROC - Undefine PDN connection (cid=%d)", cid); @@ -150,7 +152,7 @@ int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define, if (pti != ESM_PT_UNASSIGNED) { /* Release the procedure transaction data */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); } LOG_FUNC_RETURN(rc); @@ -158,7 +160,7 @@ int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int is_to_define, LOG_TRACE(INFO, "ESM-PROC - Assign new procedure transaction identity " "(cid=%d)", cid); /* Assign new procedure transaction identity */ - *pti = esm_pt_assign(); + *pti = esm_pt_assign(esm_pt_data); if (*pti == ESM_PT_UNASSIGNED) { LOG_TRACE(WARNING, "ESM-PROC - Failed to assign new procedure " @@ -282,7 +284,7 @@ int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int p OctetString *msg, int sent_by_ue) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc = RETURNok; LOG_TRACE(INFO, "ESM-PROC - Initiate PDN connectivity (pti=%d)", pti); @@ -308,7 +310,7 @@ int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int p if (rc != RETURNerror) { /* Set the procedure transaction state to PENDING */ - rc = esm_pt_set_status(pti, ESM_PT_PENDING); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_PENDING); if (rc != RETURNok) { /* The procedure transaction was already in PENDING state */ @@ -351,6 +353,7 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ { LOG_FUNC_IN; esm_data_t *esm_data = user->esm_data; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc; int pid = RETURNerror; char apn_first_char[4]; @@ -368,9 +371,9 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ esm_data_get_ipv4v6_addr(pdn_addr)); /* Stop T3482 timer if running */ - (void) esm_pt_stop_timer(pti); + esm_pt_stop_timer(esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state @@ -440,16 +443,16 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc; LOG_TRACE(WARNING, "ESM-PROC - PDN connectivity rejected by " "the network (pti=%d), ESM cause = %d", pti, *esm_cause); /* Stop T3482 timer if running */ - (void) esm_pt_stop_timer(pti); + (void) esm_pt_stop_timer(esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -457,7 +460,7 @@ int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause) *esm_cause = ESM_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE; } else { /* Release the procedure transaction identity */ - rc = esm_pt_release(pti); + rc = esm_pt_release(user->esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -491,18 +494,18 @@ int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause) int esm_proc_pdn_connectivity_complete(nas_user_t *user) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - PDN connectivity complete"); /* Get the procedure transaction identity assigned to the PDN connection * entry which is still pending in the inactive state */ - int pti = esm_pt_get_pending_pti(ESM_PT_INACTIVE); + int pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); if (pti != ESM_PT_UNASSIGNED) { /* Release the procedure transaction identity */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); } LOG_FUNC_RETURN(rc); @@ -532,7 +535,7 @@ int esm_proc_pdn_connectivity_complete(nas_user_t *user) int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; int rc; int pti; @@ -542,7 +545,7 @@ int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending) if (is_pending) { /* Get the procedure transaction identity assigned to the pending PDN * connection entry */ - pti = esm_pt_get_pending_pti(ESM_PT_PENDING); + pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_PENDING); if (pti == ESM_PT_UNASSIGNED) { LOG_TRACE(ERROR, "ESM-PROC - No procedure transaction is PENDING"); @@ -550,15 +553,15 @@ int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending) } /* Set the procedure transaction state to INACTIVE */ - (void) esm_pt_set_status(pti, ESM_PT_INACTIVE); + (void) esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); } else { /* Get the procedure transaction identity assigned to the PDN * connection entry which is still pending in the inactive state */ - pti = esm_pt_get_pending_pti(ESM_PT_INACTIVE); + pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); } /* Release the procedure transaction identity */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -612,6 +615,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) /* Get retransmission timer parameters data */ esm_pt_timer_data_t *data = args; nas_user_t *user = data->user; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; /* Increment the retransmission counter */ data->count += 1; @@ -639,7 +643,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) } } else { /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(data->pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(esm_pt_data, data->pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -647,7 +651,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) data->pti); } else { /* Release the transaction identity assigned to this procedure */ - rc = esm_pt_release(data->pti); + rc = esm_pt_release(esm_pt_data, data->pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index c8b3722d07..445c0a6c34 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -173,7 +173,7 @@ int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti LOG_FUNC_IN; int rc = RETURNok; - + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-PROC - Initiate PDN disconnection (pti=%d)", pti); if (is_standalone) { @@ -197,7 +197,7 @@ int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti if (rc != RETURNerror) { /* Set the procedure transaction state to PENDING */ - rc = esm_pt_set_status(pti, ESM_PT_PENDING); + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_PENDING); if (rc != RETURNok) { /* The procedure transaction was already in PENDING state */ @@ -231,7 +231,7 @@ int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) +int esm_proc_pdn_disconnect_accept(esm_pt_data_t *esm_pt_data, int pti, int *esm_cause) { LOG_FUNC_IN; @@ -239,9 +239,9 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) "(pti=%d)", pti); /* Stop T3492 timer if running */ - (void) esm_pt_stop_timer(pti); + (void) esm_pt_stop_timer(esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - int rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + int rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -250,7 +250,7 @@ int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause) } else { /* Immediately release the transaction identity assigned to this * procedure */ - rc = esm_pt_release(pti); + rc = esm_pt_release(esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -293,9 +293,9 @@ int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) "(pti=%d), ESM cause = %d", pti, *esm_cause); /* Stop T3492 timer if running */ - (void) esm_pt_stop_timer(pti); + (void) esm_pt_stop_timer(user->esm_pt_data, pti); /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(user->esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state @@ -304,7 +304,7 @@ int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) *esm_cause = ESM_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE; } else { /* Release the transaction identity assigned to this procedure */ - rc = esm_pt_release(pti); + rc = esm_pt_release(user->esm_pt_data, pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); @@ -414,7 +414,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) } } else { /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(data->pti, ESM_PT_INACTIVE); + rc = esm_pt_set_status(user->esm_pt_data, data->pti, ESM_PT_INACTIVE); if (rc != RETURNok) { /* The procedure transaction was already in INACTIVE state */ @@ -422,7 +422,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) data->pti); } else { /* Release the transaction identity assigned to this procedure */ - rc = esm_pt_release(data->pti); + rc = esm_pt_release(user->esm_pt_data, data->pti); if (rc != RETURNok) { LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.c b/openair3/NAS/UE/ESM/SAP/esm_recv.c index ecf9dedcbe..ba8fafaf1c 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.c +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.c @@ -154,7 +154,7 @@ int esm_recv_pdn_connectivity_reject(nas_user_t *user, int pti, int ebi, */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(user->esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case a * Assigned value that does not match any PTI in use */ @@ -225,7 +225,7 @@ int esm_recv_pdn_disconnect_reject(nas_user_t *user, int pti, int ebi, */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(user->esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case b * Assigned value that does not match any PTI in use */ @@ -282,7 +282,9 @@ int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int p const activate_default_eps_bearer_context_request_msg *msg) { LOG_FUNC_IN; + int esm_cause = ESM_CAUSE_SUCCESS; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-SAP - Received Activate Default EPS Bearer Context " "Request message (pti=%d, ebi=%d)", pti, ebi); @@ -296,7 +298,7 @@ int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int p */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case g * Assigned value that does not match any PTI in use */ @@ -413,6 +415,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int int esm_cause = ESM_CAUSE_SUCCESS; int i; int j; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-SAP - Received Activate Dedicated EPS Bearer " "Context Request message (pti=%d, ebi=%d)", pti, ebi); @@ -426,7 +429,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( (pti != ESM_PT_UNASSIGNED) && esm_pt_is_not_in_use(pti) ) { + } else if ( (pti != ESM_PT_UNASSIGNED) && esm_pt_is_not_in_use(esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case i * Assigned value that does not match any PTI in use */ @@ -620,6 +623,7 @@ int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, in int rc = RETURNok; int esm_cause; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; LOG_TRACE(INFO, "ESM-SAP - Received Deactivate EPS Bearer Context " "Request message (pti=%d, ebi=%d)", pti, ebi); @@ -633,7 +637,7 @@ int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, in */ LOG_TRACE(WARNING, "ESM-SAP - Invalid PTI value (pti=%d)", pti); LOG_FUNC_RETURN (ESM_CAUSE_INVALID_PTI_VALUE); - } else if ( esm_pt_is_not_in_use(pti) ) { + } else if ( esm_pt_is_not_in_use(esm_pt_data, pti) ) { /* 3GPP TS 24.301, section 7.3.1, case m * Assigned value does not match any PTI in use */ @@ -664,7 +668,7 @@ int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, in /* Execute the PDN disconnect procedure accepted by the network */ if (pti != ESM_PT_UNASSIGNED) { - rc = esm_proc_pdn_disconnect_accept(pti, &esm_cause); + rc = esm_proc_pdn_disconnect_accept(esm_pt_data, pti, &esm_cause); } if (rc != RETURNerror) { diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index 5b6f52916f..3680d9455a 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -173,7 +173,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) } /* Define new PDN context */ - rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, pdn_connect->pdn_type, &apn, pdn_connect->is_emergency, NULL); @@ -185,7 +185,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if (pdn_connect->is_defined) { unsigned int pti; /* Assign new procedure transaction identity */ - rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, &pti); @@ -207,7 +207,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if ( msg->is_standalone && pdn_connect->is_defined ) { /* Undefine the specified PDN context */ - rc = esm_proc_pdn_connectivity(esm_data, pdn_connect->cid, FALSE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, FALSE, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, NULL); } else if (msg->recv != NULL) { diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 7977e3a3af..d3088f84b3 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -185,7 +185,6 @@ typedef struct esm_data_context_s { */ typedef esm_data_context_t esm_data_t; - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index af59724157..b14dd3e471 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -45,6 +45,7 @@ Description Defines the EPS Session Management procedure call manager, #include "esmData.h" #include "esm_pt.h" #include "esm_ebr.h" +#include "user_defs.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -71,7 +72,7 @@ Description Defines the EPS Session Management procedure call manager, ** Return: None ** ** ** ***************************************************************************/ -esm_data_t * esm_main_initialize(esm_indication_callback_t cb) +void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) { LOG_FUNC_IN; @@ -81,6 +82,7 @@ esm_data_t * esm_main_initialize(esm_indication_callback_t cb) LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc esm_data"); // FIXME Stop here !!! } + user->esm_data = esm_data; /* Total number of active EPS bearer contexts */ esm_data->n_ebrs = 0; /* List of active PDN connections */ @@ -97,13 +99,12 @@ esm_data_t * esm_main_initialize(esm_indication_callback_t cb) /* Initialize the procedure transaction identity manager */ - esm_pt_initialize(); + user->esm_pt_data = esm_pt_initialize(); /* Initialize the EPS bearer context manager */ esm_ebr_initialize(cb); LOG_FUNC_OUT; - return esm_data; } diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h index 8fea821bb1..99fe4ba38f 100644 --- a/openair3/NAS/UE/ESM/esm_main.h +++ b/openair3/NAS/UE/ESM/esm_main.h @@ -43,6 +43,7 @@ Description Defines the EPS Session Management procedure call manager, #include "networkDef.h" #include "esm_ebr.h" #include "esmData.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -60,7 +61,7 @@ Description Defines the EPS Session Management procedure call manager, /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -esm_data_t * esm_main_initialize(esm_indication_callback_t cb); +void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb); void esm_main_cleanup(esm_data_t *esm_data); diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h index 9b533c6117..7ea23015e8 100644 --- a/openair3/NAS/UE/ESM/esm_proc.h +++ b/openair3/NAS/UE/ESM/esm_proc.h @@ -122,7 +122,7 @@ int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *m * PDN connectivity procedure * -------------------------------------------------------------------------- */ -int esm_proc_pdn_connectivity(esm_data_t *esm_data, int cid, int to_define, +int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int to_define, esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, unsigned int *pti); int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, @@ -143,7 +143,7 @@ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, un int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue); -int esm_proc_pdn_disconnect_accept(int pti, int *esm_cause); +int esm_proc_pdn_disconnect_accept(esm_pt_data_t *esm_pt_data, int pti, int *esm_cause); int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause); /* diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index fa9adb0b6e..331ac6d8cf 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -37,6 +37,8 @@ Description Defines functions used to handle ESM procedure transactions. *****************************************************************************/ #include "esm_pt.h" +#include "esm_pt_defs.h" +#include "user_defs.h" #include "commonDef.h" #include "nas_log.h" @@ -48,14 +50,6 @@ Description Defines functions used to handle ESM procedure transactions. /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -/* - * Minimal and maximal value of a procedure transaction identity: - * The Procedure Transaction Identity (PTI) identifies bi-directional - * messages flows - */ -#define ESM_PTI_MIN (PROCEDURE_TRANSACTION_IDENTITY_FIRST) -#define ESM_PTI_MAX (PROCEDURE_TRANSACTION_IDENTITY_LAST) - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -66,33 +60,9 @@ static const char *_esm_pt_state_str[ESM_PT_STATE_MAX] = { "PROCEDURE TRANSACTION PENDING" }; -/* - * -------------------------- - * Procedure transaction data - * -------------------------- - */ -typedef struct { - unsigned char pti; /* Procedure transaction identity */ - esm_pt_state status; /* Procedure transaction status */ - struct nas_timer_t timer; /* Retransmission timer */ - esm_pt_timer_data_t *args; /* Retransmission timer parameters data */ -} esm_pt_context_t; - -/* - * ------------------------------ - * List of procedure transactions - * ------------------------------ - */ -static struct { - unsigned char index; /* Index of the next procedure transaction - * identity to be used */ -#define ESM_PT_DATA_SIZE (ESM_PTI_MAX - ESM_PTI_MIN + 1) - esm_pt_context_t *context[ESM_PT_DATA_SIZE + 1]; -} _esm_pt_data; - /* Return the index of the next available entry in the list of procedure * transaction data */ -static int _esm_pt_get_available_entry(void); +static int _esm_pt_get_available_entry(esm_pt_data_t *esm_pt_data); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -109,22 +79,27 @@ static int _esm_pt_get_available_entry(void); ** ** ** Outputs: None ** ** Return: None ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -void esm_pt_initialize(void) +esm_pt_data_t *esm_pt_initialize(void) { LOG_FUNC_IN; - + esm_pt_data_t *esm_pt_data = calloc(1, sizeof(esm_pt_data_t)); int i; - _esm_pt_data.index = 0; + if ( esm_pt_data == NULL ) { + LOG_TRACE(ERROR, "ESM-PT - Can't alloc esm_pt_data"); + // FIXME Stop here !!! + } + + esm_pt_data->index = 0; for (i = 0; i < ESM_PT_DATA_SIZE + 1; i++) { - _esm_pt_data.context[i] = NULL; + esm_pt_data->context[i] = NULL; } LOG_FUNC_OUT; + return esm_pt_data; } /**************************************************************************** @@ -140,43 +115,42 @@ void esm_pt_initialize(void) ** Return: The identity of the new procedure transac- ** ** tion when successfully assigned; ** ** the unassigned PTI (0) otherwise. ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_assign(void) +int esm_pt_assign(esm_pt_data_t *esm_pt_data) { LOG_FUNC_IN; /* Search for an available procedure transaction identity */ - int i = _esm_pt_get_available_entry(); + int i = _esm_pt_get_available_entry(esm_pt_data); if (i < 0) { LOG_FUNC_RETURN (ESM_PT_UNASSIGNED); } /* Assign new procedure transaction */ - _esm_pt_data.context[i] = + esm_pt_data->context[i] = (esm_pt_context_t *)malloc(sizeof(esm_pt_context_t)); - if (_esm_pt_data.context[i] == NULL) { + if (esm_pt_data->context[i] == NULL) { LOG_FUNC_RETURN (ESM_PT_UNASSIGNED); } /* Store the index of the next available procedure transaction identity */ - _esm_pt_data.index = i + 1; + esm_pt_data->index = i + 1; /* An available procedure transaction identity is found */ - _esm_pt_data.context[i]->pti = i + ESM_PTI_MIN; + esm_pt_data->context[i]->pti = i + ESM_PTI_MIN; /* Set the procedure transaction status to INACTIVE */ - _esm_pt_data.context[i]->status = ESM_PT_INACTIVE; + esm_pt_data->context[i]->status = ESM_PT_INACTIVE; /* Disable the retransmission timer */ - _esm_pt_data.context[i]->timer.id = NAS_TIMER_INACTIVE_ID; + esm_pt_data->context[i]->timer.id = NAS_TIMER_INACTIVE_ID; /* Setup retransmission timer parameters */ - _esm_pt_data.context[i]->args = NULL; + esm_pt_data->context[i]->args = NULL; LOG_TRACE(INFO, "ESM-FSM - Procedure transaction identity %d assigned", - _esm_pt_data.context[i]->pti); - LOG_FUNC_RETURN (_esm_pt_data.context[i]->pti); + esm_pt_data->context[i]->pti); + LOG_FUNC_RETURN (esm_pt_data->context[i]->pti); } /**************************************************************************** @@ -193,10 +167,9 @@ int esm_pt_assign(void) ** Return: RETURNok if the procedure transaction iden-** ** tity has been successfully released; ** ** RETURNerror otherwise. ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_release(int pti) +int esm_pt_release(esm_pt_data_t *esm_pt_data, int pti) { LOG_FUNC_IN; @@ -205,7 +178,7 @@ int esm_pt_release(int pti) } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -236,8 +209,8 @@ int esm_pt_release(int pti) } /* Release transaction procedure data */ - free(_esm_pt_data.context[pti - ESM_PTI_MIN]); - _esm_pt_data.context[pti - ESM_PTI_MIN] = NULL; + free(esm_pt_data->context[pti - ESM_PTI_MIN]); + esm_pt_data->context[pti - ESM_PTI_MIN] = NULL; LOG_TRACE(INFO, "ESM-FSM - Procedure transaction %d released", pti); @@ -261,20 +234,20 @@ int esm_pt_release(int pti) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ int esm_pt_start_timer(nas_user_t *user, int pti, const OctetString *msg, long sec, nas_timer_callback_t cb) { LOG_FUNC_IN; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; if ( (pti < ESM_PTI_MIN) || (pti > ESM_PTI_MAX) ) { LOG_FUNC_RETURN (RETURNerror); } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -333,10 +306,9 @@ int esm_pt_start_timer(nas_user_t *user, int pti, const OctetString *msg, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_stop_timer(int pti) +int esm_pt_stop_timer(esm_pt_data_t *esm_pt_data, int pti) { LOG_FUNC_IN; @@ -345,7 +317,7 @@ int esm_pt_stop_timer(int pti) } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -385,10 +357,9 @@ int esm_pt_stop_timer(int pti) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_pt_data ** ** ** ***************************************************************************/ -int esm_pt_set_status(int pti, esm_pt_state status) +int esm_pt_set_status(esm_pt_data_t *esm_pt_data, int pti, esm_pt_state status) { LOG_FUNC_IN; @@ -399,7 +370,7 @@ int esm_pt_set_status(int pti, esm_pt_state status) } /* Get procedure transaction data */ - esm_pt_context_t *ctx = _esm_pt_data.context[pti - ESM_PTI_MIN]; + esm_pt_context_t *ctx = esm_pt_data->context[pti - ESM_PTI_MIN]; if ( (ctx == NULL) || (ctx->pti != pti) ) { /* Procedure transaction not assigned */ @@ -432,7 +403,6 @@ int esm_pt_set_status(int pti, esm_pt_state status) ** transaction ** ** ** ** Inputs: pti: The identity of the procedure transaction ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: The current value of the ESM procedure ** @@ -440,23 +410,23 @@ int esm_pt_set_status(int pti, esm_pt_state status) ** Others: None ** ** ** ***************************************************************************/ -esm_pt_state esm_pt_get_status(int pti) +esm_pt_state esm_pt_get_status(esm_pt_data_t *esm_pt_data, int pti) { if ( (pti < ESM_PTI_MIN) || (pti > ESM_PTI_MAX) ) { return (ESM_PT_INACTIVE); } - if (_esm_pt_data.context[pti - ESM_PTI_MIN] == NULL) { + if (esm_pt_data->context[pti - ESM_PTI_MIN] == NULL) { /* Procedure transaction not allocated */ return (ESM_PT_INACTIVE); } - if (_esm_pt_data.context[pti - ESM_PTI_MIN]->pti != pti) { + if (esm_pt_data->context[pti - ESM_PTI_MIN]->pti != pti) { /* Procedure transaction not assigned */ return (ESM_PT_INACTIVE); } - return (_esm_pt_data.context[pti - ESM_PTI_MIN]->status); + return (esm_pt_data->context[pti - ESM_PTI_MIN]->status); } /**************************************************************************** @@ -468,7 +438,6 @@ esm_pt_state esm_pt_get_status(int pti) ** given state ** ** ** ** Inputs: status: The PDN connection status ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: The procedure transaction identity of the ** @@ -477,18 +446,18 @@ esm_pt_state esm_pt_get_status(int pti) ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_get_pending_pti(esm_pt_state status) +int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status) { LOG_FUNC_IN; int i; for (i = 0; i < ESM_PT_DATA_SIZE; i++) { - if (_esm_pt_data.context[i] == NULL) { + if (esm_pt_data->context[i] == NULL) { continue; } - if (_esm_pt_data.context[i]->status != status) { + if (esm_pt_data->context[i]->status != status) { continue; } @@ -497,7 +466,7 @@ int esm_pt_get_pending_pti(esm_pt_state status) } if (i < ESM_PT_DATA_SIZE) { - LOG_FUNC_RETURN (_esm_pt_data.context[i]->pti); + LOG_FUNC_RETURN (esm_pt_data->context[i]->pti); } /* PDN connection entry not found */ @@ -512,18 +481,17 @@ int esm_pt_get_pending_pti(esm_pt_state status) ** does not match an assigned PTI value currently in use ** ** ** ** Inputs: pti: The identity of the procedure transaction ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: TRUE, FALSE ** ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_is_not_in_use(int pti) +int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) { return ( (pti == ESM_PT_UNASSIGNED) || - (_esm_pt_data.context[pti - ESM_PTI_MIN] == NULL) || - (_esm_pt_data.context[pti - ESM_PTI_MIN]->pti) != pti); + (esm_pt_data->context[pti - ESM_PTI_MIN] == NULL) || + (esm_pt_data->context[pti - ESM_PTI_MIN]->pti) != pti); } /**************************************************************************** @@ -558,7 +526,6 @@ int esm_pt_is_reserved(int pti) ** of procedure transaction data ** ** ** ** Inputs: None ** - ** Others: _esm_pt_data ** ** ** ** Outputs: None ** ** Return: The index of the next available procedure ** @@ -567,20 +534,20 @@ int esm_pt_is_reserved(int pti) ** Others: None ** ** ** ***************************************************************************/ -static int _esm_pt_get_available_entry(void) +static int _esm_pt_get_available_entry(esm_pt_data_t *esm_pt_data) { int i; - for (i = _esm_pt_data.index; i < ESM_PT_DATA_SIZE; i++) { - if (_esm_pt_data.context[i] != NULL) { + for (i = esm_pt_data->index; i < ESM_PT_DATA_SIZE; i++) { + if (esm_pt_data->context[i] != NULL) { continue; } return i; } - for (i = 0; i < _esm_pt_data.index; i++) { - if (_esm_pt_data.context[i] != NULL) { + for (i = 0; i < esm_pt_data->index; i++) { + if (esm_pt_data->context[i] != NULL) { continue; } diff --git a/openair3/NAS/UE/ESM/esm_pt.h b/openair3/NAS/UE/ESM/esm_pt.h index a4a3de7651..8b8693efda 100644 --- a/openair3/NAS/UE/ESM/esm_pt.h +++ b/openair3/NAS/UE/ESM/esm_pt.h @@ -41,6 +41,7 @@ Description Defines functions used to handle ESM procedure transactions. #include "OctetString.h" #include "nas_timer.h" #include "user_defs.h" +#include "esm_pt_defs.h" #include "ProcedureTransactionIdentity.h" @@ -55,22 +56,6 @@ Description Defines functions used to handle ESM procedure transactions. /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ -/* Procedure transaction states */ -typedef enum { - ESM_PT_INACTIVE, /* No procedure transaction exists */ - ESM_PT_PENDING, /* The UE has initiated a procedure transaction - * towards the network */ - ESM_PT_STATE_MAX -} esm_pt_state; - -/* ESM message timer retransmission data */ -typedef struct { - unsigned char pti; /* Procedure transaction identity */ - unsigned int count; /* Retransmission counter */ - OctetString msg; /* Encoded ESM message to re-transmit */ - nas_user_t *user; /* user reference */ -} esm_pt_timer_data_t; - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -81,19 +66,19 @@ typedef struct { int esm_pt_is_reserved(int pti); -void esm_pt_initialize(void); +esm_pt_data_t *esm_pt_initialize(void); -int esm_pt_assign(void); -int esm_pt_release(int pti); +int esm_pt_assign(esm_pt_data_t *esm_pt_data); +int esm_pt_release(esm_pt_data_t *esm_pt_data, int pti); int esm_pt_start_timer(nas_user_t *user, int pti, const OctetString *msg, long sec, nas_timer_callback_t cb); -int esm_pt_stop_timer(int pti); +int esm_pt_stop_timer(esm_pt_data_t *esm_pt_data, int pti); -int esm_pt_set_status(int pti, esm_pt_state status); -esm_pt_state esm_pt_get_status(int pti); -int esm_pt_get_pending_pti(esm_pt_state status); +int esm_pt_set_status(esm_pt_data_t *esm_pt_data, int pti, esm_pt_state status); +esm_pt_state esm_pt_get_status(esm_pt_data_t *esm_pt_data, int pti); +int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status); -int esm_pt_is_not_in_use(int pti); +int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti); #endif /* __ESM_PT_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_pt_defs.h b/openair3/NAS/UE/ESM/esm_pt_defs.h new file mode 100644 index 0000000000..36cc52dda9 --- /dev/null +++ b/openair3/NAS/UE/ESM/esm_pt_defs.h @@ -0,0 +1,63 @@ +#ifndef _ESM_PT_DEFS_H +#define _ESM_PT_DEFS_H + +#include "UTIL/nas_timer.h" +#include "IES/ProcedureTransactionIdentity.h" + +/****************************************************************************/ +/********************* G L O B A L C O N S T A N T S *******************/ +/****************************************************************************/ + +/* + * Minimal and maximal value of a procedure transaction identity: + * The Procedure Transaction Identity (PTI) identifies bi-directional + * messages flows + */ +#define ESM_PTI_MIN (PROCEDURE_TRANSACTION_IDENTITY_FIRST) +#define ESM_PTI_MAX (PROCEDURE_TRANSACTION_IDENTITY_LAST) + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* Procedure transaction states */ +typedef enum { + ESM_PT_INACTIVE, /* No procedure transaction exists */ + ESM_PT_PENDING, /* The UE has initiated a procedure transaction + * towards the network */ + ESM_PT_STATE_MAX +} esm_pt_state; + +/* ESM message timer retransmission data */ +typedef struct { + unsigned char pti; /* Procedure transaction identity */ + unsigned int count; /* Retransmission counter */ + OctetString msg; /* Encoded ESM message to re-transmit */ + void *user; /* user reference - void to avoid cyclic dependency */ +} esm_pt_timer_data_t; + +/* + * -------------------------- + * Procedure transaction data + * -------------------------- + */ +typedef struct { + unsigned char pti; /* Procedure transaction identity */ + esm_pt_state status; /* Procedure transaction status */ + struct nas_timer_t timer; /* Retransmission timer */ + esm_pt_timer_data_t *args; /* Retransmission timer parameters data */ +} esm_pt_context_t; + +/* + * ------------------------------ + * List of procedure transactions + * ------------------------------ + */ +typedef struct { + unsigned char index; /* Index of the next procedure transaction + * identity to be used */ +#define ESM_PT_DATA_SIZE (ESM_PTI_MAX - ESM_PTI_MIN + 1) + esm_pt_context_t *context[ESM_PT_DATA_SIZE + 1]; +} esm_pt_data_t; + +#endif diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index fc52843df9..9d4d3625ff 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -101,7 +101,7 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, emm_main_initialize(user, emm_cb, imei); /* Initialize the ESM procedure manager */ - user->esm_data = esm_main_initialize(esm_cb); + esm_main_initialize(user, esm_cb); LOG_FUNC_OUT; } diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index f4be31e187..38cac9d1a6 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -47,11 +47,13 @@ Description NAS type definition to manage a user equipment #include "nas_proc_defs.h" #include "esmData.h" +#include "esm_pt_defs.h" typedef struct { int fd; proc_data_t proc; esm_data_t *esm_data; // ESM internal data (used within ESM only) + esm_pt_data_t *esm_pt_data; } nas_user_t; #endif From 7ff4939da64c3f5c49488b720c7f03d78765aa49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 11:55:48 +0200 Subject: [PATCH 146/571] UE/EMM/SAP: move _emm_fsm_status to nas_user_t --- openair3/NAS/UE/EMM/SAP/EmmDeregistered.c | 14 +-- .../UE/EMM/SAP/EmmDeregisteredAttachNeeded.c | 5 +- .../SAP/EmmDeregisteredAttemptingToAttach.c | 6 +- .../NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c | 11 +-- .../EMM/SAP/EmmDeregisteredLimitedService.c | 8 +- .../EMM/SAP/EmmDeregisteredNoCellAvailable.c | 5 +- .../NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c | 4 +- .../UE/EMM/SAP/EmmDeregisteredNormalService.c | 10 +-- .../UE/EMM/SAP/EmmDeregisteredPlmnSearch.c | 8 +- openair3/NAS/UE/EMM/SAP/EmmNull.c | 5 +- openair3/NAS/UE/EMM/SAP/EmmRegistered.c | 6 +- .../EMM/SAP/EmmRegisteredAttemptingToUpdate.c | 4 +- .../SAP/EmmRegisteredImsiDetachInitiated.c | 4 +- .../NAS/UE/EMM/SAP/EmmRegisteredInitiated.c | 24 +++--- .../UE/EMM/SAP/EmmRegisteredLimitedService.c | 4 +- .../UE/EMM/SAP/EmmRegisteredNoCellAvailable.c | 4 +- .../UE/EMM/SAP/EmmRegisteredNormalService.c | 4 +- .../NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c | 37 +------- .../UE/EMM/SAP/EmmRegisteredUpdateNeeded.c | 4 +- .../UE/EMM/SAP/EmmServiceRequestInitiated.c | 4 +- .../SAP/EmmTrackingAreaUpdatingInitiated.c | 4 +- openair3/NAS/UE/EMM/SAP/emm_fsm.c | 85 ++++++++----------- openair3/NAS/UE/EMM/SAP/emm_fsm.h | 47 ++-------- openair3/NAS/UE/EMM/SAP/emm_reg.c | 8 +- openair3/NAS/UE/EMM/SAP/emm_reg.h | 5 +- openair3/NAS/UE/EMM/SAP/emm_sap.c | 4 +- openair3/NAS/UE/EMM/emm_fsm_defs.h | 42 +++++++++ openair3/NAS/UE/user_defs.h | 2 + 28 files changed, 169 insertions(+), 199 deletions(-) create mode 100644 openair3/NAS/UE/EMM/emm_fsm_defs.h diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c index b92e7a0c60..f2dd7e6821 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c @@ -54,6 +54,7 @@ Description Implements the EPS Mobility Management procedures executed #include "nas_log.h" #include "emm_proc.h" +#include "user_defs.h" #include @@ -92,10 +93,11 @@ int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED); /* Delete the authentication data RAND and RES */ + // FIXME REVIEW rc = emm_proc_authentication_delete(); if (rc != RETURNok) { @@ -116,7 +118,7 @@ int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) /* * The UE was powered on without a valid USIM application present */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_NO_IMSI); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NO_IMSI); break; case _EMMREG_REGISTER_REQ: @@ -124,11 +126,11 @@ int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) * The default EMM primary substate when the UE is switched on * with valid USIM application shall be PLMN-SEARCH */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -142,9 +144,9 @@ int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) /* Move to the corresponding initial EMM state */ if (evt->u.attach.is_emergency) { - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); } if (rc != RETURNerror) { diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c index 4f8cbc862b..cbdc470a0b 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttachNeeded.c @@ -47,6 +47,7 @@ Description Implements the EPS Mobility Management procedures executed #include "emm_fsm.h" #include "commonDef.h" #include "nas_log.h" +#include "user_defs.h" #include @@ -77,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredAttachNeeded(const emm_reg_t *evt) +int EmmDeregisteredAttachNeeded(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_ATTACH_NEEDED); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_ATTACH_NEEDED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c index 42476fd24d..3415eee99f 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c @@ -85,7 +85,7 @@ int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); switch (evt->primitive) { case _EMMREG_ATTACH_INIT: @@ -97,9 +97,9 @@ int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *evt) /* Move to the corresponding initial EMM state */ if (evt->u.attach.is_emergency) { - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); } if (rc != RETURNerror) { diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c index 220e666aa7..6706d144b6 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c @@ -78,13 +78,13 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredInitiated(const emm_reg_t *evt) +int EmmDeregisteredInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_INITIATED); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_INITIATED); switch (evt->primitive) { @@ -94,7 +94,7 @@ int EmmDeregisteredInitiated(const emm_reg_t *evt) * bearer contexts have been deactivated as UE initiated * detach procedure successfully completed) */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); break; case _EMMREG_DETACH_FAILED: @@ -103,9 +103,9 @@ int EmmDeregisteredInitiated(const emm_reg_t *evt) * The detach procedure failed */ if (evt->u.detach.type == EMM_DETACH_TYPE_IMSI) { - rc = emm_fsm_set_status(EMM_REGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_REGISTERED_NORMAL_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); } break; @@ -123,6 +123,7 @@ int EmmDeregisteredInitiated(const emm_reg_t *evt) * Lower layer failure or release of the NAS signalling connection * before the Detach Accept is received */ + // FIXME review rc = emm_proc_lowerlayer_release(); break; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c index 31b52469fa..04c60aef01 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c @@ -89,18 +89,18 @@ int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_LIMITED_SERVICE); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_LIMITED_SERVICE); switch (evt->primitive) { case _EMMREG_REGISTER_REQ: /* * The user manually re-selected a PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -118,7 +118,7 @@ int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) * (Attach Request message successfully delivered to the network); * enter state EMM-REGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_REGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_REGISTERED_INITIATED); break; case _EMMREG_LOWERLAYER_SUCCESS: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c index 517d574dc7..7974f7c3c6 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c @@ -90,7 +90,7 @@ int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_NO_CELL_AVAILABLE); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_NO_CELL_AVAILABLE); switch (evt->primitive) { /* TODO: network re-selection is not allowed when in No Cell @@ -101,13 +101,14 @@ int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) /* * The user manually re-selected a PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* * Notify EMM that the MT is currently searching an operator * to register to */ + // FIXME REVIEW rc = emm_proc_registration_notify(NET_REG_STATE_ON); if (rc != RETURNok) { diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c index 059c1f551b..0f883c8109 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoImsi.c @@ -78,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmDeregisteredNoImsi(const emm_reg_t *evt) +int EmmDeregisteredNoImsi(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_NO_IMSI); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_NO_IMSI); LOG_TRACE(ERROR, "EMM-FSM - USIM is not present or not valid"); diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index a3ac3bbdab..fd31eaf6dc 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -90,18 +90,18 @@ int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_NORMAL_SERVICE); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_NORMAL_SERVICE); switch (evt->primitive) { case _EMMREG_REGISTER_REQ: /* * The user manually re-selected a PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -126,7 +126,7 @@ int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) * message successfully delivered to the network); * enter state EMM-REGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_REGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_REGISTERED_INITIATED); break; case _EMMREG_LOWERLAYER_SUCCESS: @@ -157,7 +157,7 @@ int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) * context activated; * enter state EMM-REGISTERED. */ - rc = emm_fsm_set_status(EMM_REGISTERED); + rc = emm_fsm_set_status(user, EMM_REGISTERED); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c index 692e9a9e85..cea39a5456 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c @@ -88,7 +88,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_DEREGISTERED_PLMN_SEARCH); + assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_PLMN_SEARCH); switch (evt->primitive) { case _EMMREG_NO_CELL: @@ -102,7 +102,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) "Failed to notify registration update"); } - rc = emm_fsm_set_status(EMM_DEREGISTERED_NO_CELL_AVAILABLE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NO_CELL_AVAILABLE); break; case _EMMREG_REGISTER_REQ: @@ -130,14 +130,14 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) * The selected cell is known not to be able to provide normal * service */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); break; case _EMMREG_REGISTER_CNF: /* * A suitable cell of the selected PLMN has been found to camp on */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmNull.c b/openair3/NAS/UE/EMM/SAP/EmmNull.c index 5da067bfe8..4fe8853b35 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmNull.c +++ b/openair3/NAS/UE/EMM/SAP/EmmNull.c @@ -46,6 +46,7 @@ Description Implements the EPS Mobility Management procedures executed #include "nas_log.h" #include "emm_proc.h" +#include "user_defs.h" #include @@ -82,7 +83,7 @@ int EmmNull(nas_user_t *user, const emm_reg_t *evt) int rc; - assert(emm_fsm_get_status() == EMM_NULL); + assert(emm_fsm_get_status(user) == EMM_NULL); /* Delete the authentication data RAND and RES */ rc = emm_proc_authentication_delete(); @@ -97,7 +98,7 @@ int EmmNull(nas_user_t *user, const emm_reg_t *evt) * The EPS capability has been enabled in the UE: * Move to the DEREGISTERED state; */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); /* * And initialize the EMM procedure call manager in order to diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c index 83bb9ea37a..cb1db33985 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c @@ -87,7 +87,7 @@ int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_REGISTERED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED); switch (evt->primitive) { @@ -105,7 +105,7 @@ int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) * message successfully delivered to the network); * enter state EMM-DEREGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_INITIATED); break; case _EMMREG_DETACH_CNF: @@ -113,7 +113,7 @@ int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) * The UE implicitly detached from the network (all EPS * bearer contexts may have been deactivated) */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); break; case _EMMREG_TAU_REQ: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c index 59d8f45df9..21654123d1 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c @@ -78,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredAttemptingToUpdate(const emm_reg_t *evt) +int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_ATTEMPTING_TO_UPDATE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_ATTEMPTING_TO_UPDATE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c index c522d5ec5c..6855843a25 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c @@ -78,11 +78,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredImsiDetachInitiated(const emm_reg_t *evt) +int EmmRegisteredImsiDetachInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_IMSI_DETACH_INITIATED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_IMSI_DETACH_INITIATED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index 71c9eb0a1d..27b6979e04 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -84,7 +84,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) int rc = RETURNerror; - assert(emm_fsm_get_status() == EMM_REGISTERED_INITIATED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_INITIATED); switch (evt->primitive) { case _EMMREG_ATTACH_INIT: @@ -96,9 +96,9 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) /* Move to the corresponding initial EMM state */ if (evt->u.attach.is_emergency) { - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); } else { - rc = emm_fsm_set_status(EMM_DEREGISTERED_NORMAL_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NORMAL_SERVICE); } if (rc != RETURNerror) { @@ -114,7 +114,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * timer T3410 expired). The network attach procedure shall be * restarted when timer T3411 expires. */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); break; case _EMMREG_ATTACH_EXCEEDED: @@ -126,7 +126,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * SEARCH in order to perform a PLMN selection. */ /* TODO: ATTEMPTING-TO-ATTACH or PLMN-SEARCH ??? */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH); break; case _EMMREG_ATTACH_CNF: @@ -134,7 +134,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * EPS network attach accepted by the network; * enter state EMM-REGISTERED. */ - rc = emm_fsm_set_status(EMM_REGISTERED); + rc = emm_fsm_set_status(user, EMM_REGISTERED); if (rc != RETURNerror) { /* @@ -161,7 +161,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * EPS network attach rejected by the network; * enter state EMM-DEREGISTERED. */ - rc = emm_fsm_set_status(EMM_DEREGISTERED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED); if (rc != RETURNerror) { /* @@ -181,11 +181,11 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) /* * The UE has to select a new PLMN to register to */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_PLMN_SEARCH); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_PLMN_SEARCH); if (rc != RETURNerror) { /* Process the network registration request */ - rc = emm_fsm_process(evt); + rc = emm_fsm_process(user, evt); } break; @@ -194,7 +194,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) /* * The UE failed to register to the network for normal EPS service */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_LIMITED_SERVICE); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_LIMITED_SERVICE); break; case _EMMREG_NO_IMSI: @@ -202,7 +202,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * The UE failed to register to the network for emergency * bearer services */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_NO_IMSI); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_NO_IMSI); break; case _EMMREG_DETACH_INIT: @@ -218,7 +218,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * message successfully delivered to the network); * enter state EMM-DEREGISTERED-INITIATED */ - rc = emm_fsm_set_status(EMM_DEREGISTERED_INITIATED); + rc = emm_fsm_set_status(user, EMM_DEREGISTERED_INITIATED); break; case _EMMREG_LOWERLAYER_SUCCESS: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c index 280252b8ed..b4ea68f689 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredLimitedService.c @@ -74,11 +74,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredLimitedService(const emm_reg_t *evt) +int EmmRegisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_LIMITED_SERVICE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_LIMITED_SERVICE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c index a22f3d76c6..0328ae8192 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNoCellAvailable.c @@ -75,11 +75,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredNoCellAvailable(const emm_reg_t *evt) +int EmmRegisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_NO_CELL_AVAILABLE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_NO_CELL_AVAILABLE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c index bc25a1e4be..8b1c8721f2 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredNormalService.c @@ -74,11 +74,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredNormalService(const emm_reg_t *evt) +int EmmRegisteredNormalService(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_NORMAL_SERVICE); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_NORMAL_SERVICE); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c index 453e39558e..8ee92c4454 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredPlmnSearch.c @@ -74,46 +74,13 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredPlmnSearch(const emm_reg_t *evt) +int EmmRegisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_PLMN_SEARCH); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_PLMN_SEARCH); /* TODO */ LOG_FUNC_RETURN (RETURNok); } - -#if 0 -/**************************************************************************** - ** ** - ** Name: EmmRegisteredPlmnSearch_xxx() ** - ** ** - ** Description: Procedure executed when xxx ** - ** while the EMM-SAP is in EMM-REGISTERED.PLMN-SEARCH state. ** - ** ** - ** Inputs: evt: The received EMM-SAP event ** - ** Others: emm_fsm_status ** - ** ** - ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: emm_fsm_status ** - ** ** - ***************************************************************************/ -int EmmRegisteredPlmnSearch_xxx(const emm_reg_t *evt) -{ - LOG_FUNC_IN; - - assert(emm_fsm_get_status() == EMM_REGISTERED_PLMN_SEARCH); - - /* TODO */ - - LOG_FUNC_RETURN (RETURNok); -} -#endif - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c index 36f35fe351..2a81b488dc 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredUpdateNeeded.c @@ -80,11 +80,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmRegisteredUpdateNeeded(const emm_reg_t *evt) +int EmmRegisteredUpdateNeeded(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_REGISTERED_UPDATE_NEEDED); + assert(emm_fsm_get_status(user) == EMM_REGISTERED_UPDATE_NEEDED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c index a72b2d6003..b556efb7f4 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmServiceRequestInitiated.c @@ -76,11 +76,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmServiceRequestInitiated(const emm_reg_t *evt) +int EmmServiceRequestInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_SERVICE_REQUEST_INITIATED); + assert(emm_fsm_get_status(user) == EMM_SERVICE_REQUEST_INITIATED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c index 69699cc117..91bb660ee1 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c @@ -76,11 +76,11 @@ Description Implements the EPS Mobility Management procedures executed ** Others: emm_fsm_status ** ** ** ***************************************************************************/ -int EmmTrackingAreaUpdatingInitiated(const emm_reg_t *evt) +int EmmTrackingAreaUpdatingInitiated(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; - assert(emm_fsm_get_status() == EMM_TRACKING_AREA_UPDATING_INITIATED); + assert(emm_fsm_get_status(user) == EMM_TRACKING_AREA_UPDATING_INITIATED); /* TODO */ diff --git a/openair3/NAS/UE/EMM/SAP/emm_fsm.c b/openair3/NAS/UE/EMM/SAP/emm_fsm.c index a76b101119..be1517a7cc 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_fsm.c +++ b/openair3/NAS/UE/EMM/SAP/emm_fsm.c @@ -43,6 +43,7 @@ Description Defines the EPS Mobility Management procedures executed at #include "nas_log.h" #include "emmData.h" +#include "user_defs.h" @@ -127,30 +128,30 @@ static const char *_emm_fsm_status_str[EMM_STATE_MAX] = { */ /* Type of the EPS Mobility Management state machine handler */ -typedef int(*emm_fsm_handler_t)(const emm_reg_t *); +typedef int(*emm_fsm_handler_t)(nas_user_t *user, const emm_reg_t *); -int EmmNull(const emm_reg_t *); -int EmmDeregistered(const emm_reg_t *); -int EmmRegistered(const emm_reg_t *); -int EmmDeregisteredInitiated(const emm_reg_t *); -int EmmDeregisteredNormalService(const emm_reg_t *); -int EmmDeregisteredLimitedService(const emm_reg_t *); -int EmmDeregisteredAttemptingToAttach(const emm_reg_t *); -int EmmDeregisteredPlmnSearch(const emm_reg_t *); -int EmmDeregisteredNoImsi(const emm_reg_t *); -int EmmDeregisteredAttachNeeded(const emm_reg_t *); -int EmmDeregisteredNoCellAvailable(const emm_reg_t *); -int EmmRegisteredInitiated(const emm_reg_t *); -int EmmRegisteredNormalService(const emm_reg_t *); -int EmmRegisteredAttemptingToUpdate(const emm_reg_t *); -int EmmRegisteredLimitedService(const emm_reg_t *); -int EmmRegisteredPlmnSearch(const emm_reg_t *); -int EmmRegisteredUpdateNeeded(const emm_reg_t *); -int EmmRegisteredNoCellAvailable(const emm_reg_t *); -int EmmRegisteredAttemptingToUpdate(const emm_reg_t *); -int EmmRegisteredImsiDetachInitiated(const emm_reg_t *); -int EmmTrackingAreaUpdatingInitiated(const emm_reg_t *); -int EmmServiceRequestInitiated(const emm_reg_t *); +int EmmNull(nas_user_t *user, const emm_reg_t *); +int EmmDeregistered(nas_user_t *user, const emm_reg_t *); +int EmmRegistered(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredInitiated(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredNoImsi(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredAttachNeeded(nas_user_t *user, const emm_reg_t *); +int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredNormalService(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredLimitedService(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredPlmnSearch(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredUpdateNeeded(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *); +int EmmRegisteredImsiDetachInitiated(nas_user_t *user, const emm_reg_t *); +int EmmTrackingAreaUpdatingInitiated(nas_user_t *user, const emm_reg_t *); +int EmmServiceRequestInitiated(nas_user_t *user, const emm_reg_t *); /* EMM state machine handlers */ @@ -180,14 +181,6 @@ static const emm_fsm_handler_t _emm_fsm_handlers[EMM_STATE_MAX] = { EmmServiceRequestInitiated, }; -/* - * ----------------------------------------------------------------------------- - * Current EPS Mobility Management status - * ----------------------------------------------------------------------------- - */ - -emm_fsm_state_t _emm_fsm_status[EMM_FSM_NB_UE_MAX]; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -206,14 +199,12 @@ emm_fsm_state_t _emm_fsm_status[EMM_FSM_NB_UE_MAX]; ** Others: _emm_fsm_status ** ** ** ***************************************************************************/ -void emm_fsm_initialize(void) +emm_fsm_state_t emm_fsm_initialize() { - //int ueid; LOG_FUNC_IN; - _emm_fsm_status[0] = EMM_NULL; - LOG_FUNC_OUT; + return EMM_NULL; } /**************************************************************************** @@ -231,22 +222,18 @@ void emm_fsm_initialize(void) ** Others: _emm_fsm_status ** ** ** ***************************************************************************/ -int emm_fsm_set_status( +int emm_fsm_set_status(nas_user_t *user, emm_fsm_state_t status) { LOG_FUNC_IN; - unsigned int ueid = 0; - - - - if ( (status < EMM_STATE_MAX) && (ueid < EMM_FSM_NB_UE_MAX) ) { + if ( status < EMM_STATE_MAX ) { LOG_TRACE(INFO, "EMM-FSM - Status changed: %s ===> %s", - _emm_fsm_status_str[_emm_fsm_status[ueid]], + _emm_fsm_status_str[user->emm_fsm_status], _emm_fsm_status_str[status]); - if (status != _emm_fsm_status[ueid]) { - _emm_fsm_status[ueid] = status; + if (status != user->emm_fsm_status) { + user->emm_fsm_status = status; } LOG_FUNC_RETURN (RETURNok); @@ -270,9 +257,9 @@ int emm_fsm_set_status( ** Others: None ** ** ** ***************************************************************************/ -emm_fsm_state_t emm_fsm_get_status(void) +emm_fsm_state_t emm_fsm_get_status(nas_user_t *user) { - return (_emm_fsm_status[0]); + return user->emm_fsm_status; } /**************************************************************************** @@ -289,7 +276,7 @@ emm_fsm_state_t emm_fsm_get_status(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_fsm_process(const emm_reg_t *evt) +int emm_fsm_process(nas_user_t *user, const emm_reg_t *evt) { int rc; emm_fsm_state_t status; @@ -299,7 +286,7 @@ int emm_fsm_process(const emm_reg_t *evt) primitive = evt->primitive; - status = _emm_fsm_status[0]; + status = user->emm_fsm_status; LOG_TRACE(INFO, "EMM-FSM - Received event %s (%d) in state %s", _emm_fsm_event_str[primitive - _EMMREG_START - 1], primitive, @@ -307,7 +294,7 @@ int emm_fsm_process(const emm_reg_t *evt) /* Execute the EMM state machine */ - rc = (_emm_fsm_handlers[status])(evt); + rc = (_emm_fsm_handlers[status])(user, evt); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/SAP/emm_fsm.h b/openair3/NAS/UE/EMM/SAP/emm_fsm.h index ea7d4ed622..aba1ef327c 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_fsm.h +++ b/openair3/NAS/UE/EMM/SAP/emm_fsm.h @@ -41,48 +41,13 @@ Description Defines the EPS Mobility Management procedures executed at #define __EMM_FSM_H__ #include "emm_regDef.h" +#include "emm_fsm_defs.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* - * States of the EPS Mobility Management sublayer - * ---------------------------------------------- - * The EMM protocol of the UE and the network is described by means of two - * different state machines. - */ -typedef enum { - EMM_INVALID, - EMM_NULL, - EMM_DEREGISTERED, - EMM_REGISTERED, - EMM_DEREGISTERED_INITIATED, - EMM_DEREGISTERED_NORMAL_SERVICE, - EMM_DEREGISTERED_LIMITED_SERVICE, - EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH, - EMM_DEREGISTERED_PLMN_SEARCH, - EMM_DEREGISTERED_NO_IMSI, - EMM_DEREGISTERED_ATTACH_NEEDED, - EMM_DEREGISTERED_NO_CELL_AVAILABLE, - EMM_REGISTERED_INITIATED, - EMM_REGISTERED_NORMAL_SERVICE, - EMM_REGISTERED_ATTEMPTING_TO_UPDATE, - EMM_REGISTERED_LIMITED_SERVICE, - EMM_REGISTERED_PLMN_SEARCH, - EMM_REGISTERED_UPDATE_NEEDED, - EMM_REGISTERED_NO_CELL_AVAILABLE, - EMM_REGISTERED_ATTEMPTING_TO_UPDATE_MM, - EMM_REGISTERED_IMSI_DETACH_INITIATED, - EMM_TRACKING_AREA_UPDATING_INITIATED, - EMM_SERVICE_REQUEST_INITIATED, - EMM_STATE_MAX -} emm_fsm_state_t; - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -91,12 +56,12 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_fsm_initialize(void); +emm_fsm_state_t emm_fsm_initialize(void); -int emm_fsm_set_status(emm_fsm_state_t status); -emm_fsm_state_t emm_fsm_get_status(void); +int emm_fsm_set_status(nas_user_t *user, emm_fsm_state_t status); +emm_fsm_state_t emm_fsm_get_status(nas_user_t *user); -int emm_fsm_process(const emm_reg_t *evt); +int emm_fsm_process(nas_user_t *user, const emm_reg_t *evt); #endif /* __EMM_FSM_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_reg.c b/openair3/NAS/UE/EMM/SAP/emm_reg.c index 065b91bd3b..6cda066b58 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_reg.c +++ b/openair3/NAS/UE/EMM/SAP/emm_reg.c @@ -73,12 +73,12 @@ Description Defines the EMMREG Service Access Point that provides ** Others: NONE ** ** ** ***************************************************************************/ -void emm_reg_initialize(void) +void emm_reg_initialize(nas_user_t *user) { LOG_FUNC_IN; /* Initialize the EMM state machine */ - emm_fsm_initialize(); + user->emm_fsm_status = emm_fsm_initialize(); LOG_FUNC_OUT; } @@ -97,7 +97,7 @@ void emm_reg_initialize(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_reg_send(const emm_reg_t *msg) +int emm_reg_send(nas_user_t *user, const emm_reg_t *msg) { LOG_FUNC_IN; @@ -111,7 +111,7 @@ int emm_reg_send(const emm_reg_t *msg) (void)primitive; /* Execute the EMM procedure */ - rc = emm_fsm_process(msg); + rc = emm_fsm_process(user, msg); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/SAP/emm_reg.h b/openair3/NAS/UE/EMM/SAP/emm_reg.h index 08d28b67db..9cd1132c7a 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_reg.h +++ b/openair3/NAS/UE/EMM/SAP/emm_reg.h @@ -42,6 +42,7 @@ Description Defines the EMMREG Service Access Point that provides #define __EMM_REG_H__ #include "emm_regDef.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -59,8 +60,8 @@ Description Defines the EMMREG Service Access Point that provides /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -void emm_reg_initialize(void); +void emm_reg_initialize(nas_user_t *user); -int emm_reg_send(const emm_reg_t *msg); +int emm_reg_send(nas_user_t *user, const emm_reg_t *msg); #endif /* __EMM_REG_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_sap.c b/openair3/NAS/UE/EMM/SAP/emm_sap.c index 6887982786..429518d475 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_sap.c +++ b/openair3/NAS/UE/EMM/SAP/emm_sap.c @@ -78,7 +78,7 @@ void emm_sap_initialize(nas_user_t *user) { LOG_FUNC_IN; - emm_reg_initialize(); + emm_reg_initialize(user); emm_esm_initialize(); emm_as_initialize(user); @@ -112,7 +112,7 @@ int emm_sap_send(nas_user_t *user, emm_sap_t *msg) (primitive < (emm_primitive_t)EMMREG_PRIMITIVE_MAX) ) { /* Forward to the EMMREG-SAP */ msg->u.emm_reg.primitive = primitive; - rc = emm_reg_send(&msg->u.emm_reg); + rc = emm_reg_send(user, &msg->u.emm_reg); } else if ( (primitive > (emm_primitive_t)EMMESM_PRIMITIVE_MIN) && (primitive < (emm_primitive_t)EMMESM_PRIMITIVE_MAX) ) { /* Forward to the EMMESM-SAP */ diff --git a/openair3/NAS/UE/EMM/emm_fsm_defs.h b/openair3/NAS/UE/EMM/emm_fsm_defs.h new file mode 100644 index 0000000000..4e5b4a8ee6 --- /dev/null +++ b/openair3/NAS/UE/EMM/emm_fsm_defs.h @@ -0,0 +1,42 @@ +#ifndef _EMM_FSM_DEFS_H +#define _EMM_FSM_DEFS_H + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* + * States of the EPS Mobility Management sublayer + * ---------------------------------------------- + * The EMM protocol of the UE and the network is described by means of two + * different state machines. + */ +typedef enum { + EMM_INVALID, + EMM_NULL, + EMM_DEREGISTERED, + EMM_REGISTERED, + EMM_DEREGISTERED_INITIATED, + EMM_DEREGISTERED_NORMAL_SERVICE, + EMM_DEREGISTERED_LIMITED_SERVICE, + EMM_DEREGISTERED_ATTEMPTING_TO_ATTACH, + EMM_DEREGISTERED_PLMN_SEARCH, + EMM_DEREGISTERED_NO_IMSI, + EMM_DEREGISTERED_ATTACH_NEEDED, + EMM_DEREGISTERED_NO_CELL_AVAILABLE, + EMM_REGISTERED_INITIATED, + EMM_REGISTERED_NORMAL_SERVICE, + EMM_REGISTERED_ATTEMPTING_TO_UPDATE, + EMM_REGISTERED_LIMITED_SERVICE, + EMM_REGISTERED_PLMN_SEARCH, + EMM_REGISTERED_UPDATE_NEEDED, + EMM_REGISTERED_NO_CELL_AVAILABLE, + EMM_REGISTERED_ATTEMPTING_TO_UPDATE_MM, + EMM_REGISTERED_IMSI_DETACH_INITIATED, + EMM_TRACKING_AREA_UPDATING_INITIATED, + EMM_SERVICE_REQUEST_INITIATED, + EMM_STATE_MAX +} emm_fsm_state_t; + + +#endif diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 38cac9d1a6..a27d6f5177 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -48,12 +48,14 @@ Description NAS type definition to manage a user equipment #include "nas_proc_defs.h" #include "esmData.h" #include "esm_pt_defs.h" +#include "EMM/emm_fsm_defs.h" typedef struct { int fd; proc_data_t proc; esm_data_t *esm_data; // ESM internal data (used within ESM only) esm_pt_data_t *esm_pt_data; + emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status } nas_user_t; #endif From 84fa851dfa55e5674803f2e27668e69e7764ec60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 12:47:37 +0200 Subject: [PATCH 147/571] UE/ESM: use static buffer per UE to allow reentrancy in esm_sap.c --- openair3/NAS/UE/ESM/SAP/esm_sap.c | 25 ++++++------------------- openair3/NAS/UE/ESM/esmData.h | 2 ++ 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index 3680d9455a..ae895af3e9 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -95,12 +95,6 @@ static const char *_esm_sap_primitive_str[] = { "ESM_UNITDATA_IND", }; -/* - * Buffer used to encode ESM messages before being returned to the EPS - * Mobility Management sublayer in order to be sent onto the network - */ -#define ESM_SAP_BUFFER_SIZE 4096 -static char _esm_sap_buffer[ESM_SAP_BUFFER_SIZE]; /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -148,6 +142,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) { LOG_FUNC_IN; esm_data_t *esm_data = user->esm_data; + msg->send.value = esm_data->send_buffer; int rc = RETURNerror; int pid; @@ -359,7 +354,6 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) ** turned upon ESM procedure completion ** ** err: Error code of the ESM procedure ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_sap_buffer ** ** ** ***************************************************************************/ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, @@ -642,13 +636,10 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, if ( (rc != RETURNerror) && (esm_procedure != NULL) ) { /* Encode the returned ESM response message */ - int size = esm_msg_encode(&esm_msg, (uint8_t *)_esm_sap_buffer, + int size = esm_msg_encode(&esm_msg, rsp->value, ESM_SAP_BUFFER_SIZE); - if (size > 0) { - rsp->length = size; - rsp->value = (uint8_t *)(_esm_sap_buffer); - } + rsp->length = size; /* Complete the relevant ESM procedure */ rc = (*esm_procedure)(user, is_standalone, ebi, rsp, triggered_by_ue); @@ -691,7 +682,6 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, ** Outputs: rsp: The encoded ESM response message to be re- ** ** turned upon ESM procedure completion ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_sap_buffer ** ** ** ***************************************************************************/ static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, @@ -772,18 +762,15 @@ static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, if (rc != RETURNerror) { /* Encode the returned ESM response message */ - int size = esm_msg_encode(&esm_msg, (uint8_t *)_esm_sap_buffer, + int size = esm_msg_encode(&esm_msg, rsp->value, ESM_SAP_BUFFER_SIZE); - if (size > 0) { - rsp->length = size; - rsp->value = (uint8_t *)(_esm_sap_buffer); - } - + rsp->length = size; /* Execute the relevant ESM procedure */ if (esm_procedure) { rc = (*esm_procedure)(user, is_standalone, pti, rsp, sent_by_ue); } + } LOG_FUNC_RETURN(rc); diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index d3088f84b3..75947dabc9 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -52,6 +52,7 @@ Description Defines internal private data handled by EPS Session /* Total number of active EPS bearers */ #define ESM_DATA_EPS_BEARER_TOTAL 11 +#define ESM_SAP_BUFFER_SIZE 4096 /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ @@ -172,6 +173,7 @@ typedef struct esm_data_context_s { } pdn[ESM_DATA_PDN_MAX+1]; esm_ebr_data_t ebr; + uint8_t send_buffer[ESM_SAP_BUFFER_SIZE]; } esm_data_context_t; /* From f99e5e1ff068f7ac41325c70342c42137f739e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 12:54:40 +0200 Subject: [PATCH 148/571] UE/ESM: remove useless #if directive in esm_ebr.c --- openair3/NAS/UE/ESM/esm_ebr.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 878f06c184..57b168930d 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -69,9 +69,7 @@ static const char *_esm_ebr_state_str[ESM_EBR_STATE_MAX] = { * ---------------------------------- */ -#if !defined(NAS_BUILT_IN_EPC) static esm_ebr_data_t _esm_ebr_data[ESM_EBR_NB_UE_MAX]; -#endif /* * ---------------------- @@ -126,7 +124,6 @@ void esm_ebr_initialize( esm_indication_callback_t cb ) { -#if !defined(NAS_BUILT_IN_EPC) int ueid, i; LOG_FUNC_IN; @@ -144,7 +141,6 @@ void esm_ebr_initialize( _esm_ebr_callback = *cb; LOG_FUNC_OUT; -#endif } /**************************************************************************** From 809be889a73b630b720fec99a88f805355bae25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 15:03:12 +0200 Subject: [PATCH 149/571] UE/ESM: move _esm_ebr_data to nas_user_t --- .../ESM/DedicatedEpsBearerContextActivation.c | 10 +- .../ESM/DefaultEpsBearerContextActivation.c | 11 +- .../NAS/UE/ESM/EpsBearerContextDeactivation.c | 10 +- openair3/NAS/UE/ESM/SAP/esm_recv.c | 14 +-- openair3/NAS/UE/ESM/esm_ebr.c | 115 ++++++++---------- openair3/NAS/UE/ESM/esm_ebr.h | 17 +-- openair3/NAS/UE/ESM/esm_ebr_context.c | 11 +- openair3/NAS/UE/ESM/esm_main.c | 11 +- openair3/NAS/UE/ESM/esm_main.h | 2 +- openair3/NAS/UE/nas_proc.c | 6 +- openair3/NAS/UE/nas_proc.h | 2 +- openair3/NAS/UE/nas_user.c | 2 +- openair3/NAS/UE/user_defs.h | 1 + 13 files changed, 100 insertions(+), 112 deletions(-) diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 55008d7dac..c96a40a1b8 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -131,7 +131,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int } /* Assign dedicated EPS bearer context */ - int new_ebi = esm_ebr_assign(ebi, pid+1, FALSE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.2.5, abnormal cases a and b @@ -149,7 +149,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new dedicated EPS bearer context */ - ebi = esm_ebr_assign(ebi, pid+1, FALSE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); } } @@ -229,7 +229,7 @@ int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standa if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_ACTIVE, ue_triggered); + rc = esm_ebr_set_status(user->esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in ACTIVE state */ @@ -276,9 +276,9 @@ int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standa LOG_TRACE(WARNING, "ESM-PROC - Dedicated EPS bearer context activation " "not accepted by the UE (ebi=%d)", ebi); - if ( !esm_ebr_is_not_in_use(ebi) ) { + if ( !esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) { /* Release EPS bearer data currently in use */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(user->esm_ebr_data, ebi); } if (rc != RETURNok) { diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index a5e70703ed..68d1ce8eab 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -116,7 +116,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e "requested by the network (ebi=%d)", ebi); /* Assign default EPS bearer context */ - int new_ebi = esm_ebr_assign(ebi, pid+1, TRUE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.1.5, abnormal cases a and b @@ -134,7 +134,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new default EPS bearer context */ - ebi = esm_ebr_assign(ebi, pid+1, TRUE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); } } @@ -213,7 +213,7 @@ int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalo if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_ACTIVE, ue_triggered); + rc = esm_ebr_set_status(user->esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in ACTIVE state */ @@ -266,9 +266,9 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo LOG_TRACE(WARNING, "ESM-PROC - Default EPS bearer context activation " "not accepted by the UE (ebi=%d)", ebi); - if ( !esm_ebr_is_not_in_use(ebi) ) { + if ( !esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) { /* Release EPS bearer data currently in use */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(user->esm_ebr_data, ebi); } if (rc != RETURNok) { @@ -280,6 +280,7 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; + // FIXME REVIEW emm_sap.u.emm_esm.ueid = 0; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index fdba605f1e..c92ce2c582 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -281,6 +281,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand LOG_FUNC_IN; int rc = RETURNok; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; LOG_TRACE(INFO,"ESM-PROC - EPS bearer context deactivation accepted"); @@ -298,7 +299,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand if (rc != RETURNerror) { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_INACTIVE, ue_triggered); + rc = esm_ebr_set_status(esm_ebr_data, ebi, ESM_EBR_INACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ @@ -309,7 +310,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand } /* Release EPS bearer data */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(esm_ebr_data, ebi); } LOG_FUNC_RETURN (rc); @@ -357,6 +358,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) LOG_FUNC_IN; int rc = RETURNerror; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; /* Release the EPS bearer context entry */ ebi = esm_ebr_context_release(user, ebi, pid, bid); @@ -365,14 +367,14 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); } else { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(ebi, ESM_EBR_INACTIVE, FALSE); + rc = esm_ebr_set_status(esm_ebr_data, ebi, ESM_EBR_INACTIVE, FALSE); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ LOG_TRACE(WARNING, "ESM-PROC - EBI %d was already INACTIVE", ebi); } else { /* Release EPS bearer data */ - rc = esm_ebr_release(ebi); + rc = esm_ebr_release(esm_ebr_data, ebi); if (rc != RETURNok) { LOG_TRACE(WARNING, diff --git a/openair3/NAS/UE/ESM/SAP/esm_recv.c b/openair3/NAS/UE/ESM/SAP/esm_recv.c index ba8fafaf1c..03a4215581 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_recv.c +++ b/openair3/NAS/UE/ESM/SAP/esm_recv.c @@ -74,7 +74,7 @@ Description Defines functions executed at the ESM Service Access ** ** ** Description: Processes ESM status message ** ** ** - ** Inputs: ueid: UE local identifier ** + ** Inputs: ** ** pti: Procedure transaction identity ** ** ebi: EPS bearer identity ** ** msg: The received ESM message ** @@ -164,7 +164,7 @@ int esm_recv_pdn_connectivity_reject(nas_user_t *user, int pti, int ebi, /* * EPS bearer identity checking */ - else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case a * Assigned or reserved EPS bearer identity value */ LOG_TRACE(WARNING, "ESM-SAP - Invalid EPS bearer identity (ebi=%d)", @@ -235,7 +235,7 @@ int esm_recv_pdn_disconnect_reject(nas_user_t *user, int pti, int ebi, /* * EPS bearer identity checking */ - else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi != ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case b * Assigned or reserved EPS bearer identity value */ LOG_TRACE(WARNING, "ESM-SAP - Invalid EPS bearer identity (ebi=%d)", @@ -308,7 +308,7 @@ int esm_recv_activate_default_eps_bearer_context_request(nas_user_t *user, int p /* * EPS bearer identity checking */ - else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case g * Reserved or unassigned EPS bearer identity value */ @@ -439,7 +439,7 @@ int esm_recv_activate_dedicated_eps_bearer_context_request(nas_user_t *user, int /* * EPS bearer identity checking */ - else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) ) { + else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case h * Reserved or unassigned EPS bearer identity value */ @@ -647,8 +647,8 @@ int esm_recv_deactivate_eps_bearer_context_request(nas_user_t *user, int pti, in /* * EPS bearer identity checking */ - else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(ebi) || - esm_ebr_is_not_in_use(ebi) ) { + else if ( (ebi == ESM_EBI_UNASSIGNED) || esm_ebr_is_reserved(user->esm_ebr_data, ebi) || + esm_ebr_is_not_in_use(user->esm_ebr_data, ebi) ) { /* 3GPP TS 24.301, section 7.3.2, case j * Reserved or unassigned EPS bearer identity value or, * assigned value that does not match an existing EPS bearer context diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 57b168930d..81d3ff3270 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -50,9 +50,6 @@ Description Defines functions used to handle state of EPS bearer contexts /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -#define ESM_EBR_NB_UE_MAX 1 - - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -63,14 +60,6 @@ static const char *_esm_ebr_state_str[ESM_EBR_STATE_MAX] = { "BEARER CONTEXT ACTIVE", }; -/* - * ---------------------------------- - * List of EPS bearer contexts per UE - * ---------------------------------- - */ - -static esm_ebr_data_t _esm_ebr_data[ESM_EBR_NB_UE_MAX]; - /* * ---------------------- * User notification data @@ -100,7 +89,7 @@ static const network_pdn_state_t _esm_ebr_pdn_state[2][2][2] = { /* Returns the index of the next available entry in the list of EPS bearer * context data */ -static int _esm_ebr_get_available_entry(unsigned int ueid); +static int _esm_ebr_get_available_entry(esm_ebr_data_t *esm_ebr_data); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -117,39 +106,51 @@ static int _esm_ebr_get_available_entry(unsigned int ueid); ** ** ** Outputs: None ** ** Return: None ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -void esm_ebr_initialize( - esm_indication_callback_t cb -) + +esm_ebr_data_t *esm_ebr_initialize(void) { - int ueid, i; LOG_FUNC_IN; - for (ueid = 0; ueid < ESM_EBR_NB_UE_MAX; ueid++) { - _esm_ebr_data[ueid].index = 0; + int i; + esm_ebr_data_t *esm_ebr_data = calloc(1, sizeof(esm_ebr_data_t)); - /* Initialize EPS bearer context data */ - for (i = 0; i < ESM_EBR_DATA_SIZE + 1; i++) { - _esm_ebr_data[ueid].context[i] = NULL; - } + if ( esm_ebr_data == NULL ) { + LOG_TRACE(ERROR, "ESM-EBR - Can't malloc esm_ebr_data"); + // FIXME Stop here !!! } + esm_ebr_data->index = 0; + + /* Initialize EPS bearer context data */ + for (i = 0; i < ESM_EBR_DATA_SIZE + 1; i++) { + esm_ebr_data->context[i] = NULL; + } + + LOG_FUNC_OUT; + return esm_ebr_data; +} + +void esm_ebr_register_callback(esm_indication_callback_t cb) +{ + + LOG_FUNC_IN; + /* Initialize the user notification callback */ _esm_ebr_callback = *cb; LOG_FUNC_OUT; } + /**************************************************************************** ** ** ** Name: esm_ebr_assign() ** ** ** ** Description: Assigns a new EPS bearer context ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: Identity of the new EPS bearer context ** ** cid: Identifier of the PDN context the EPS bea- ** ** rer context is associated to ** @@ -161,18 +162,16 @@ void esm_ebr_initialize( ** Return: The identity of the new EPS bearer context ** ** if successfully assigned; ** ** the not assigned EBI (0) otherwise. ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -int esm_ebr_assign(int ebi, int cid, int default_ebr) +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr) { esm_ebr_context_t *ebr_ctx = NULL; - unsigned int ueid = 0; int i; LOG_FUNC_IN; - ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]; + ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN]; if (ebi != ESM_EBI_UNASSIGNED) { @@ -188,7 +187,7 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) i = ebi - ESM_EBI_MIN; } else { /* Search for an available EPS bearer identity */ - i = _esm_ebr_get_available_entry(ueid); + i = _esm_ebr_get_available_entry(esm_ebr_data); if (i < 0) { LOG_FUNC_RETURN(ESM_EBI_UNASSIGNED); @@ -207,10 +206,10 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) } - _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] = ebr_ctx; + esm_ebr_data->context[ebi - ESM_EBI_MIN] = ebr_ctx; /* Store the index of the next available EPS bearer identity */ - _esm_ebr_data[ueid].index = i + 1; + esm_ebr_data->index = i + 1; /* Set the EPS bearer identity */ ebr_ctx->ebi = ebi; @@ -231,7 +230,7 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) ** ** ** Description: Release the given EPS bearer identity ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** + ** Inputs: ** ** ebi: The identity of the EPS bearer context to ** ** be released ** ** Others: None ** @@ -240,13 +239,11 @@ int esm_ebr_assign(int ebi, int cid, int default_ebr) ** Return: RETURNok if the EPS bearer context has ** ** been successfully released; ** ** RETURNerror otherwise. ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -int esm_ebr_release( +int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi) { - unsigned int ueid = 0; esm_ebr_context_t *ebr_ctx; LOG_FUNC_IN; @@ -256,7 +253,7 @@ int esm_ebr_release( } /* Get EPS bearer context data */ - ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]; + ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN]; if ( (ebr_ctx == NULL) || (ebr_ctx->ebi != ebi) ) { /* EPS bearer context not assigned */ @@ -286,7 +283,6 @@ int esm_ebr_release( ** Description: Set the status of the specified EPS bearer context to the ** ** given state ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: The identity of the EPS bearer ** ** status: The new EPS bearer context status ** ** ue_requested: TRUE/FALSE if the modification of the EPS ** @@ -296,10 +292,9 @@ int esm_ebr_release( ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _esm_ebr_data ** ** ** ***************************************************************************/ -int esm_ebr_set_status( +int esm_ebr_set_status(esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested) { esm_ebr_context_t *ebr_ctx; @@ -307,19 +302,13 @@ int esm_ebr_set_status( LOG_FUNC_IN; - unsigned int ueid = 0; - - if (ueid >= ESM_EBR_NB_UE_MAX) { - LOG_FUNC_RETURN (RETURNerror); - } - if ( (ebi < ESM_EBI_MIN) || (ebi > ESM_EBI_MAX) ) { LOG_FUNC_RETURN (RETURNerror); } /* Get EPS bearer context data */ - ebr_ctx = _esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]; + ebr_ctx = esm_ebr_data->context[ebi - ESM_EBI_MIN]; if ( (ebr_ctx == NULL) || (ebr_ctx->ebi != ebi) ) { /* EPS bearer context not assigned */ @@ -356,9 +345,7 @@ int esm_ebr_set_status( ** Description: Get the current status value of the specified EPS bearer ** ** context ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: The identity of the EPS bearer ** - ** Others: _esm_ebr_data ** ** ** ** Outputs: None ** ** Return: The current value of the EPS bearer con- ** @@ -367,26 +354,25 @@ int esm_ebr_set_status( ** ** ***************************************************************************/ -esm_ebr_state esm_ebr_get_status( +esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi) { - unsigned int ueid = 0; if ( (ebi < ESM_EBI_MIN) || (ebi > ESM_EBI_MAX) ) { return (ESM_EBR_INACTIVE); } - if (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] == NULL) { + if (esm_ebr_data->context[ebi - ESM_EBI_MIN] == NULL) { /* EPS bearer context not allocated */ return (ESM_EBR_INACTIVE); } - if (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->ebi != ebi) { + if (esm_ebr_data->context[ebi - ESM_EBI_MIN]->ebi != ebi) { /* EPS bearer context not assigned */ return (ESM_EBR_INACTIVE); } - return (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->status); + return (esm_ebr_data->context[ebi - ESM_EBI_MIN]->status); } /**************************************************************************** @@ -404,7 +390,7 @@ esm_ebr_state esm_ebr_get_status( ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_reserved(int ebi) +int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) { return ( (ebi != ESM_EBI_UNASSIGNED) && (ebi < ESM_EBI_MIN) ); } @@ -416,23 +402,20 @@ int esm_ebr_is_reserved(int ebi) ** Description: Check whether the given EPS bearer identity does not ** ** match an assigned EBI value currently in use ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** ** ebi: The identity of the EPS bearer ** - ** Others: _esm_ebr_data ** ** ** ** Outputs: None ** ** Return: TRUE, FALSE ** ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_not_in_use( +int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi) { - unsigned int ueid = 0; return ( (ebi == ESM_EBI_UNASSIGNED) || - (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN] == NULL) || - (_esm_ebr_data[ueid].context[ebi - ESM_EBI_MIN]->ebi) != ebi); + (esm_ebr_data->context[ebi - ESM_EBI_MIN] == NULL) || + (esm_ebr_data->context[ebi - ESM_EBI_MIN]->ebi) != ebi); } /****************************************************************************/ @@ -446,8 +429,6 @@ int esm_ebr_is_not_in_use( ** Description: Returns the index of the next available entry in the list ** ** of EPS bearer context data ** ** ** - ** Inputs: ueid: Lower layers UE identifier ** - ** Others: _esm_ebr_data ** ** ** ** Outputs: None ** ** Return: The index of the next available EPS bearer ** @@ -456,20 +437,20 @@ int esm_ebr_is_not_in_use( ** Others: None ** ** ** ***************************************************************************/ -static int _esm_ebr_get_available_entry(unsigned int ueid) +static int _esm_ebr_get_available_entry(esm_ebr_data_t *esm_ebr_data) { int i; - for (i = _esm_ebr_data[ueid].index; i < ESM_EBR_DATA_SIZE; i++) { - if (_esm_ebr_data[ueid].context[i] != NULL) { + for (i = esm_ebr_data->index; i < ESM_EBR_DATA_SIZE; i++) { + if (esm_ebr_data->context[i] != NULL) { continue; } return i; } - for (i = 0; i < _esm_ebr_data[ueid].index; i++) { - if (_esm_ebr_data[ueid].context[i] != NULL) { + for (i = 0; i < esm_ebr_data->index; i++) { + if (esm_ebr_data->context[i] != NULL) { continue; } diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h index af31e95676..adc10de0c4 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.h +++ b/openair3/NAS/UE/ESM/esm_ebr.h @@ -45,6 +45,7 @@ Description Defines functions used to handle state of EPS bearer contexts #include "esmData.h" #include "nas_timer.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -72,15 +73,17 @@ typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_ebr_is_reserved(int ebi); +void esm_ebr_register_callback(esm_indication_callback_t cb); -void esm_ebr_initialize(esm_indication_callback_t cb); -int esm_ebr_assign(int ebi, int cid, int default_ebr); -int esm_ebr_release(int ebi); +int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_set_status(int ebi, esm_ebr_state status, int ue_requested); -esm_ebr_state esm_ebr_get_status(int ebi); +esm_ebr_data_t *esm_ebr_initialize(void); +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr); +int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_is_not_in_use(int ebi); +int esm_ebr_set_status(esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested); +esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi); + +int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi); #endif /* __ESM_EBR_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 00950428bb..1f7707c5c3 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -82,7 +82,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ** Description: Creates a new EPS bearer context to the PDN with the spe- ** ** cified PDN connection identifier ** ** ** - ** Inputs: ueid: UE identifier ** + ** Inputs: ** ** pid: PDN connection identifier ** ** ebi: EPS bearer identity ** ** is_default: TRUE if the new bearer is a default EPS ** @@ -105,7 +105,6 @@ int esm_ebr_context_create( int bid = 0; esm_data_context_t *esm_ctx = NULL; esm_pdn_t *pdn = NULL; - //unsigned int ueid = 0; LOG_FUNC_IN; @@ -314,7 +313,7 @@ int esm_ebr_context_create( ** Description: Releases EPS bearer context entry previously allocated ** ** to the EPS bearer with the specified EPS bearer identity ** ** ** - ** Inputs: ueid: UE identifier ** + ** Inputs: ** ** ebi: EPS bearer identity ** ** ** ** Outputs: pid: Identifier of the PDN connection entry the ** @@ -333,8 +332,6 @@ int esm_ebr_context_release(nas_user_t *user, esm_pdn_t *pdn = NULL; esm_data_context_t *esm_ctx; - //unsigned int ueid = 0; - LOG_FUNC_IN; esm_ctx = user->esm_data; @@ -451,11 +448,11 @@ int esm_ebr_context_release(nas_user_t *user, } /* Set the EPS bearer context state to INACTIVE */ - (void) esm_ebr_set_status(pdn->bearer[i]->ebi, + esm_ebr_set_status(user->esm_ebr_data, pdn->bearer[i]->ebi, ESM_EBR_INACTIVE, TRUE); /* Release EPS bearer data */ - (void) esm_ebr_release(pdn->bearer[i]->ebi); + esm_ebr_release(user->esm_ebr_data, pdn->bearer[i]->ebi); // esm_ebr_release() /* Release dedicated EPS bearer data */ diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index b14dd3e471..f79b40cfec 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -102,8 +102,9 @@ void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) user->esm_pt_data = esm_pt_initialize(); /* Initialize the EPS bearer context manager */ - esm_ebr_initialize(cb); - + user->esm_ebr_data = esm_ebr_initialize(); + // FIXME only one callback for all user or many for many ? + esm_ebr_register_callback(cb); LOG_FUNC_OUT; } @@ -247,11 +248,13 @@ int esm_main_has_emergency(esm_data_t *esm_data) ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state) +int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) { LOG_FUNC_IN; unsigned int pid = cid - 1; + esm_data_t *esm_data = user->esm_data; + esm_ebr_data_t *esm_ebr_data = user-> esm_ebr_data; if (pid >= ESM_DATA_PDN_MAX) { return (FALSE); @@ -268,7 +271,7 @@ int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state) /* The status of a PDN connection is the status of the default EPS bearer * that has been assigned to this PDN connection at activation time */ int ebi = esm_data->pdn[pid].data->bearer[0]->ebi; - *state = (esm_ebr_get_status(ebi) == ESM_EBR_ACTIVE); + *state = (esm_ebr_get_status(esm_ebr_data, ebi) == ESM_EBR_ACTIVE); } /* The PDN connection has not been activated yet */ diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h index 99fe4ba38f..42381c8d5b 100644 --- a/openair3/NAS/UE/ESM/esm_main.h +++ b/openair3/NAS/UE/ESM/esm_main.h @@ -70,7 +70,7 @@ void esm_main_cleanup(esm_data_t *esm_data); int esm_main_get_nb_pdns_max(esm_data_t *esm_data); int esm_main_get_nb_pdns(esm_data_t *esm_data); int esm_main_has_emergency(esm_data_t *esm_data); -int esm_main_get_pdn_status(esm_data_t *esm_data, int cid, int *state); +int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state); int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency, int *is_active); int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 9d4d3625ff..68304f0879 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -674,7 +674,7 @@ int nas_proc_get_pdn_range(esm_data_t *esm_data) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_pdn_max) +int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max) { LOG_FUNC_IN; @@ -682,13 +682,13 @@ int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_ int n_defined_pdn = 0; /* Get the maximum number of supported PDN contexts */ - int n_pdn = esm_main_get_nb_pdns_max(esm_data); + int n_pdn = esm_main_get_nb_pdns_max(user->esm_data); /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get the status of this PDN */ int state = FALSE; - int is_defined = esm_main_get_pdn_status(esm_data, cid, &state); + int is_defined = esm_main_get_pdn_status(user, cid, &state); if (is_defined != FALSE) { /* This PDN has been defined */ diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index 6851746d38..ec1ca3f3c7 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -98,7 +98,7 @@ int nas_proc_reset_pdn(nas_user_t *user, int cid); int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, int emergency, int p_cscf, int im_cn_signal); int nas_proc_get_pdn_range(esm_data_t *esm_data); -int nas_proc_get_pdn_status(esm_data_t *esm_data, int *cids, int *states, int n_pdn_max); +int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_max); int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const char **apns, int n_pdn_max); int nas_proc_get_pdn_addr(nas_user_t *user, int cid, int *cids, const char **addr1, diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 909c82a393..827003699c 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -2184,7 +2184,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) * The read command returns the current activation states for * all the defined PDN/EPS bearer contexts */ - cgact->n_pdns = nas_proc_get_pdn_status(user->esm_data, cgact->cid, cgact->state, + cgact->n_pdns = nas_proc_get_pdn_status(user, cgact->cid, cgact->state, AT_CGACT_RESP_SIZE); if (cgact->n_pdns == 0) { diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index a27d6f5177..a963960f4f 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -56,6 +56,7 @@ typedef struct { esm_data_t *esm_data; // ESM internal data (used within ESM only) esm_pt_data_t *esm_pt_data; emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status + esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts } nas_user_t; #endif From 5665b05c7cd2bdec55e8316617a6a544ddcf503b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 16:13:10 +0200 Subject: [PATCH 150/571] UE/EMM: move _emm_data to nas_user_t --- openair3/NAS/UE/EMM/Attach.c | 150 ++++---- openair3/NAS/UE/EMM/Authentication.c | 54 +-- openair3/NAS/UE/EMM/Detach.c | 10 +- openair3/NAS/UE/EMM/EmmStatusHdl.c | 4 +- openair3/NAS/UE/EMM/Identification.c | 16 +- openair3/NAS/UE/EMM/IdleMode.c | 161 +++++---- openair3/NAS/UE/EMM/IdleMode.h | 4 +- openair3/NAS/UE/EMM/LowerLayer.c | 8 +- .../EMM/SAP/EmmDeregisteredNoCellAvailable.c | 3 +- .../UE/EMM/SAP/EmmDeregisteredPlmnSearch.c | 4 +- .../NAS/UE/EMM/SAP/EmmRegisteredInitiated.c | 4 +- openair3/NAS/UE/EMM/SAP/emm_as.c | 38 +- openair3/NAS/UE/EMM/SAP/emm_esm.c | 2 +- openair3/NAS/UE/EMM/SecurityModeControl.c | 75 ++-- openair3/NAS/UE/EMM/emmData.h | 7 - openair3/NAS/UE/EMM/emm_main.c | 337 ++++++++---------- openair3/NAS/UE/EMM/emm_main.h | 26 +- openair3/NAS/UE/EMM/emm_proc.h | 8 +- openair3/NAS/UE/nas_proc.c | 34 +- openair3/NAS/UE/nas_proc.h | 2 +- openair3/NAS/UE/nas_user.c | 2 +- openair3/NAS/UE/user_defs.h | 4 +- 22 files changed, 452 insertions(+), 501 deletions(-) diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 7084c69f92..3204e5f2da 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -133,7 +133,7 @@ static struct { ** INITIATED. ** ** ** ** Inputs: type: Type of the requested attach ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -154,7 +154,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) /* Update the emergency bearer service indicator */ if (type == EMM_ATTACH_TYPE_EMERGENCY) { - _emm_data.is_emergency = TRUE; + user->emm_data->is_emergency = TRUE; } /* Setup initial NAS information message to transfer */ @@ -163,7 +163,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) emm_as->type = type; /* Set the RRC connection establishment cause */ - if (_emm_data.is_emergency) { + if (user->emm_data->is_emergency) { emm_as->RRCcause = NET_ESTABLISH_CAUSE_EMERGENCY; emm_as->RRCtype = NET_ESTABLISH_TYPE_EMERGENCY_CALLS; } else { @@ -172,7 +172,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) } /* Set the PLMN identifier of the selected PLMN */ - emm_as->plmnID = &_emm_data.splmn; + emm_as->plmnID = &user->emm_data->splmn; /* * Process the EPS mobile identity */ @@ -182,55 +182,55 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) emm_as->UEid.imei = NULL; /* Check whether the UE is configured for "AttachWithIMSI" */ - if (_emm_data.AttachWithImsi) { + if (user->emm_data->AttachWithImsi) { /* Check whether the selected PLMN is neither the registered PLMN * nor in the list of equivalent PLMNs */ - if ( (!_emm_data.is_rplmn) && (!_emm_data.is_eplmn) ) { + if ( (!user->emm_data->is_rplmn) && (!user->emm_data->is_eplmn) ) { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI"); /* Include the IMSI */ - emm_as->UEid.imsi = _emm_data.imsi; + emm_as->UEid.imsi = user->emm_data->imsi; } else { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with NO IMSI, is registered PLMN %d, is equivalent PLMN %d", - _emm_data.is_rplmn, - _emm_data.is_eplmn); + user->emm_data->is_rplmn, + user->emm_data->is_eplmn); } - } else if (_emm_data.guti) { + } else if (user->emm_data->guti) { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with GUTI"); /* Include a valid GUTI and the last visited registered TAI */ - emm_as->UEid.guti = _emm_data.guti; - emm_as->UEid.tai = _emm_data.tai; - } else if (!_emm_data.is_emergency) { + emm_as->UEid.guti = user->emm_data->guti; + emm_as->UEid.tai = user->emm_data->tai; + } else if (!user->emm_data->is_emergency) { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI cause is no emergency and no GUTI"); /* Include the IMSI if no valid GUTI is available */ - emm_as->UEid.imsi = _emm_data.imsi; + emm_as->UEid.imsi = user->emm_data->imsi; } else { /* The UE is attaching for emergency bearer services and * does not hold a valid GUTI */ - if (_emm_data.imsi) { + if (user->emm_data->imsi) { /* Include the IMSI if valid (USIM is present) */ LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI cause is emergency and no GUTI"); - emm_as->UEid.imsi = _emm_data.imsi; + emm_as->UEid.imsi = user->emm_data->imsi; } else { LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach with IMSI cause is emergency and no GUTI and no IMSI"); /* Include the IMEI if the IMSI is not valid */ - emm_as->UEid.imei = _emm_data.imei; + emm_as->UEid.imei = user->emm_data->imei; } } /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, FALSE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, FALSE); emm_as->ksi = EMM_AS_NO_KEY_AVAILABLE; - if (_emm_data.security) { - if (_emm_data.security->type != EMM_KSI_NOT_AVAILABLE) { - emm_as->ksi = _emm_data.security->eksi; + if (user->emm_data->security) { + if (user->emm_data->security->type != EMM_KSI_NOT_AVAILABLE) { + emm_as->ksi = user->emm_data->security->eksi; } - LOG_TRACE(INFO, "EMM-PROC - eps_encryption 0x%X", _emm_data.security->capability.eps_encryption); - LOG_TRACE(INFO, "EMM-PROC - eps_integrity 0x%X", _emm_data.security->capability.eps_integrity); - emm_as->encryption = _emm_data.security->capability.eps_encryption; - emm_as->integrity = _emm_data.security->capability.eps_integrity; + LOG_TRACE(INFO, "EMM-PROC - eps_encryption 0x%X", user->emm_data->security->capability.eps_encryption); + LOG_TRACE(INFO, "EMM-PROC - eps_integrity 0x%X", user->emm_data->security->capability.eps_integrity); + emm_as->encryption = user->emm_data->security->capability.eps_encryption; + emm_as->integrity = user->emm_data->security->capability.eps_integrity; } /* @@ -244,7 +244,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) /* TODO: PDN type should be set according to the IP capability of the UE */ esm_sap.data.pdn_connect.pdn_type = NET_PDN_TYPE_IPV4; esm_sap.data.pdn_connect.apn = NULL; - esm_sap.data.pdn_connect.is_emergency = _emm_data.is_emergency; + esm_sap.data.pdn_connect.is_emergency = user->emm_data->is_emergency; rc = esm_sap_send(user, &esm_sap); if (rc != RETURNerror) { @@ -342,7 +342,7 @@ int emm_proc_attach_request(void *args) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, T3412, T3402, T3423 ** + ** Others: user->emm_data-> T3412, T3402, T3423 ** ** ** ***************************************************************************/ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, @@ -365,10 +365,10 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, T3410.id = nas_timer_stop(T3410.id); /* Delete old TAI list and store the received TAI list */ - _emm_data.ltai.n_tais = n_tais; + user->emm_data->ltai.n_tais = n_tais; for (i = 0; (i < n_tais) && (i < EMM_DATA_TAI_MAX); i++) { - _emm_data.ltai.tai[i] = tai[i]; + user->emm_data->ltai.tai[i] = tai[i]; } /* Update periodic tracking area update timer value */ @@ -386,22 +386,22 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, /* Delete old GUTI and store the new assigned GUTI if provided */ if (guti) { - *_emm_data.guti = *guti; + *user->emm_data->guti = *guti; } /* Update the stored list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; if (n_eplmns > 0) { for (i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) { int is_forbidden = FALSE; - if (!_emm_data.is_emergency) { + if (!user->emm_data->is_emergency) { /* If the attach procedure is not for emergency bearer * services, the UE shall remove from the list any PLMN * code that is already in the list of forbidden PLMNs */ - for (j = 0; j < _emm_data.fplmn.n_plmns; j++) { - if (PLMNS_ARE_EQUAL(eplmn[i], _emm_data.fplmn.plmn[j])) { + for (j = 0; j < user->emm_data->fplmn.n_plmns; j++) { + if (PLMNS_ARE_EQUAL(eplmn[i], user->emm_data->fplmn.plmn[j])) { is_forbidden = TRUE; break; } @@ -409,15 +409,15 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, } if ( !is_forbidden ) { - _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = + user->emm_data->nvdata.eplmn.plmn[user->emm_data->nvdata.eplmn.n_plmns++] = eplmn[i]; } } /* Add the PLMN code of the registered PLMN that sent the list */ - if (_emm_data.nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) { - _emm_data.nvdata.eplmn.plmn[_emm_data.nvdata.eplmn.n_plmns++] = - _emm_data.splmn; + if (user->emm_data->nvdata.eplmn.n_plmns < EMM_DATA_EPLMN_MAX) { + user->emm_data->nvdata.eplmn.plmn[user->emm_data->nvdata.eplmn.n_plmns++] = + user->emm_data->splmn; } } @@ -448,11 +448,11 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, * be sent to the network */ emm_sap.primitive = EMMAS_DATA_REQ; - emm_sap.u.emm_as.u.data.guti = _emm_data.guti; + emm_sap.u.emm_as.u.data.guti = user->emm_data->guti; emm_sap.u.emm_as.u.data.ueid = 0; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, - _emm_data.security, FALSE, TRUE); + user->emm_data->security, FALSE, TRUE); /* Get the activate default EPS bearer context accept message * to be transfered within the ESM container of the attach * complete message */ @@ -497,7 +497,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _emm_attach_data, T3410 ** + ** Others: user->emm_data-> _emm_attach_data, T3410 ** ** ** ***************************************************************************/ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg_pP) @@ -528,15 +528,15 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e case EMM_CAUSE_ROAMING_NOT_ALLOWED: case EMM_CAUSE_NO_SUITABLE_CELLS: /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */ - _emm_data.status = EU3_ROAMING_NOT_ALLOWED; + user->emm_data->status = EU3_ROAMING_NOT_ALLOWED; /* Delete the GUTI */ - _emm_data.guti = NULL; + user->emm_data->guti = NULL; /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; + user->emm_data->tai = NULL; /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + if (user->emm_data->security) { + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } break; @@ -552,16 +552,16 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e case EMM_CAUSE_EPS_NOT_ALLOWED: case EMM_CAUSE_BOTH_NOT_ALLOWED: /* Consider the USIM as invalid for EPS services */ - _emm_data.usim_is_valid = FALSE; + user->emm_data->usim_is_valid = FALSE; /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; break; case EMM_CAUSE_PLMN_NOT_ALLOWED: case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: case EMM_CAUSE_ROAMING_NOT_ALLOWED: /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; /* Reset the attach attempt counter */ _emm_attach_data.attempt_count = 0; break; @@ -576,7 +576,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e case EMM_CAUSE_ESM_FAILURE: /* 3GPP TS 24.301, section 5.5.1.2.6, case d */ - if (_emm_data.NAS_SignallingPriority != 1) { + if (user->emm_data->NAS_SignallingPriority != 1) { /* The UE is not configured for NAS signalling low priority; * set the attach attempt counter to 5 */ _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; @@ -603,25 +603,25 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e case EMM_CAUSE_PLMN_NOT_ALLOWED: case EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN: /* Store the PLMN identity in the "forbidden PLMN list" */ - _emm_data.fplmn.plmn[_emm_data.fplmn.n_plmns++] = _emm_data.splmn; + user->emm_data->fplmn.plmn[user->emm_data->fplmn.n_plmns++] = user->emm_data->splmn; break; case EMM_CAUSE_TA_NOT_ALLOWED: /* Store the current TAI in the list of "forbidden tracking * areas for regional provision of service" */ - _emm_data.ftai.tai[_emm_data.ftai.n_tais++] = *_emm_data.tai; + user->emm_data->ftai.tai[user->emm_data->ftai.n_tais++] = *user->emm_data->tai; break; case EMM_CAUSE_ROAMING_NOT_ALLOWED: /* Store the current TAI in the list of "forbidden tracking * areas for roaming" */ - _emm_data.ftai_roaming.tai[_emm_data.ftai_roaming.n_tais++] = *_emm_data.tai; + user->emm_data->ftai_roaming.tai[user->emm_data->ftai_roaming.n_tais++] = *user->emm_data->tai; break; case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: /* Store the PLMN identity in the "forbidden PLMNs for GPRS * service" list */ - _emm_data.fplmn_gprs.plmn[_emm_data.fplmn_gprs.n_plmns++] = _emm_data.splmn; + user->emm_data->fplmn_gprs.plmn[user->emm_data->fplmn_gprs.n_plmns++] = user->emm_data->splmn; break; default : @@ -662,7 +662,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e break; case EMM_CAUSE_IMEI_NOT_ACCEPTED: - if (_emm_data.is_emergency) { + if (user->emm_data->is_emergency) { /* * Notify EMM that the UE failed to register to the network * for emergency bearer services because "IMEI not accepted" @@ -714,7 +714,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _emm_attach_data ** + ** Others: user->emm_data-> _emm_attach_data ** ** ** ***************************************************************************/ int emm_proc_attach_complete(void *args) @@ -736,8 +736,8 @@ int emm_proc_attach_complete(void *args) /* TODO: Reset the tracking area updating attempt counter */ /* Set the EPS update status to EU1 UPDATED */ - _emm_data.status = EU1_UPDATED; - _emm_data.is_attached = TRUE; + user->emm_data->status = EU1_UPDATED; + user->emm_data->is_attached = TRUE; /* * Notify EMM that network attach complete message has been delivered @@ -897,7 +897,7 @@ int emm_proc_attach_restart(nas_user_t *user) * Notify EMM that the attach procedure has to be restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; + emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency; rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); @@ -914,17 +914,17 @@ int emm_proc_attach_restart(nas_user_t *user) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_attach_set_emergency(void) +int emm_proc_attach_set_emergency(emm_data_t *emm_data) { LOG_FUNC_IN; LOG_TRACE(WARNING, "EMM-PROC - UE is now attached to the network for " "emergency bearer services only"); - _emm_data.is_emergency = TRUE; + emm_data->is_emergency = TRUE; LOG_FUNC_RETURN(RETURNok); } @@ -941,7 +941,7 @@ int emm_proc_attach_set_emergency(void) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ int emm_proc_attach_set_detach(void *nas_user) @@ -955,7 +955,7 @@ int emm_proc_attach_set_detach(void *nas_user) "EMM-PROC - UE is now locally detached from the network"); /* Reset the network attachment indicator */ - _emm_data.is_attached = FALSE; + user->emm_data->is_attached = FALSE; /* * Notify that the UE is locally detached from the network */ @@ -1016,7 +1016,7 @@ void *_emm_attach_t3410_handler(void *args) if (rc != RETURNerror) { /* Locally release the NAS signalling connection */ - _emm_data.ecm_status = ECM_IDLE; + user->emm_data->ecm_status = ECM_IDLE; } LOG_FUNC_RETURN(NULL); @@ -1056,7 +1056,7 @@ static void *_emm_attach_t3411_handler(void *args) * restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; + emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency; (void) emm_sap_send(user, &emm_sap); @@ -1103,7 +1103,7 @@ static void *_emm_attach_t3402_handler(void *args) * restarted */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = _emm_data.is_emergency; + emm_sap.u.emm_reg.u.attach.is_emergency = user->emm_data->is_emergency; (void) emm_sap_send(user, &emm_sap); @@ -1133,7 +1133,7 @@ static void *_emm_attach_t3402_handler(void *args) ** ** ** Outputs: emm_sap: EMM service access point ** ** Return: None ** - ** Others: _emm_data, _emm_attach_data, T3402, T3410, ** + ** Others: user->emm_data-> _emm_attach_data, T3402, T3410, ** ** T3411 ** ** ** ***************************************************************************/ @@ -1165,21 +1165,21 @@ static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap) emm_sap->primitive = EMMREG_ATTACH_FAILED; } else { /* Delete the GUTI */ - _emm_data.guti = NULL; + user->emm_data->guti = NULL; /* Delete the TAI list */ - _emm_data.ltai.n_tais = 0; + user->emm_data->ltai.n_tais = 0; /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; + user->emm_data->tai = NULL; /* Delete the list of equivalent PLMNs */ - _emm_data.nvdata.eplmn.n_plmns = 0; + user->emm_data->nvdata.eplmn.n_plmns = 0; /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + if (user->emm_data->security) { + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } /* Set the EPS update status to EU2 NOT UPDATED */ - _emm_data.status = EU2_NOT_UPDATED; + user->emm_data->status = EU2_NOT_UPDATED; /* Start T3402 timer */ T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, user); diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 7b5672c3bf..daa7f5a1f7 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -163,11 +163,11 @@ static int _authentication_kasme(const OctetString *autn, ** ksi: The NAS ket sey identifier ** ** rand: Authentication parameter RAND ** ** autn: Authentication parameter AUTN ** - ** Others: _emm_data, _authentication_data ** + ** Others: user->emm_data-> _authentication_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _authentication_data, T3416, ** + ** Others: user->emm_data-> _authentication_data, T3416, ** ** T3418, T3420 ** ** ** ***************************************************************************/ @@ -185,7 +185,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, * The UE shall proceed with an EPS authentication challenge only if a * USIM is present */ - if (!_emm_data.usim_is_valid) { + if (!user->emm_data->usim_is_valid) { LOG_TRACE(WARNING, "EMM-PROC - USIM is not present or not valid"); LOG_FUNC_RETURN (RETURNerror); } @@ -327,14 +327,14 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; emm_sap.u.emm_as.u.security.ueid = 0; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.emm_cause = EMM_CAUSE_SUCCESS; emm_sap.u.emm_as.u.security.res = &res; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); + user->emm_data->security, FALSE, TRUE); rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { @@ -344,29 +344,29 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, _authentication_data.sync_count = 0; /* Create non-current EPS security context */ - if (_emm_data.non_current == NULL) { - _emm_data.non_current = + if (user->emm_data->non_current == NULL) { + user->emm_data->non_current = (emm_security_context_t *)malloc(sizeof(emm_security_context_t)); } - if (_emm_data.non_current) { - memset(_emm_data.non_current, 0, sizeof(emm_security_context_t)); + if (user->emm_data->non_current) { + memset(user->emm_data->non_current, 0, sizeof(emm_security_context_t)); /* Set the security context type */ if (native_ksi) { - _emm_data.non_current->type = EMM_KSI_NATIVE; + user->emm_data->non_current->type = EMM_KSI_NATIVE; } else { - _emm_data.non_current->type = EMM_KSI_MAPPED; + user->emm_data->non_current->type = EMM_KSI_MAPPED; } /* Set the EPS key set identifier */ - _emm_data.non_current->eksi = ksi; + user->emm_data->non_current->eksi = ksi; /* Derive the Kasme from the authentication challenge using * the PLMN identity of the selected PLMN */ - _emm_data.non_current->kasme.length = AUTH_KASME_SIZE; - _emm_data.non_current->kasme.value = malloc(32); - _authentication_kasme(autn, &ck, &ik, &_emm_data.splmn, - &_emm_data.non_current->kasme); + user->emm_data->non_current->kasme.length = AUTH_KASME_SIZE; + user->emm_data->non_current->kasme.value = malloc(32); + _authentication_kasme(autn, &ck, &ik, &user->emm_data->splmn, + &user->emm_data->non_current->kasme); /* NAS integrity and cyphering keys are not yet available */ } } @@ -392,7 +392,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data, _authentication_data, T3410, ** + ** Others: user->emm_data-> _authentication_data, T3410, ** ** T3417, T3430 ** ** ** ***************************************************************************/ @@ -409,21 +409,21 @@ int emm_proc_authentication_reject(nas_user_t *user) (void) emm_proc_authentication_delete(); /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */ - _emm_data.status = EU3_ROAMING_NOT_ALLOWED; + user->emm_data->status = EU3_ROAMING_NOT_ALLOWED; /* Delete the stored GUTI */ - _emm_data.guti = NULL; + user->emm_data->guti = NULL; /* Delete the TAI list */ - _emm_data.ltai.n_tais = 0; + user->emm_data->ltai.n_tais = 0; /* Delete the last visited registered TAI */ - _emm_data.tai = NULL; + user->emm_data->tai = NULL; /* Delete the eKSI */ - if (_emm_data.security) { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + if (user->emm_data->security) { + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } /* Consider the USIM invalid */ - _emm_data.usim_is_valid = FALSE; + user->emm_data->usim_is_valid = FALSE; /* Stop timer T3410 */ if (T3410.id != NAS_TIMER_INACTIVE_ID) { @@ -664,14 +664,14 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; emm_sap.u.emm_as.u.security.ueid = 0; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.emm_cause = emm_cause; emm_sap.u.emm_as.u.security.auts = auts; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); + user->emm_data->security, FALSE, TRUE); rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { @@ -787,7 +787,7 @@ static int _authentication_abnormal_case_f(nas_user_t *user) */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_RELEASE_REQ; - emm_sap.u.emm_as.u.release.guti = _emm_data.guti; + emm_sap.u.emm_as.u.release.guti = user->emm_data->guti; emm_sap.u.emm_as.u.release.cause = EMM_AS_CAUSE_AUTHENTICATION; rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index 7ea4220cae..480e24448a 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -124,7 +124,7 @@ static struct { ** Inputs: type: Type of the requested detach ** ** switch_off: Indicates whether the detach is required ** ** because the UE is switched off or not ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -167,10 +167,10 @@ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_of /* Set the switch-off indicator */ emm_as->switch_off = switch_off; /* Set the EPS mobile identity */ - emm_as->guti = _emm_data.guti; + emm_as->guti = user->emm_data->guti; emm_as->ueid = 0; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, _emm_data.security, FALSE, TRUE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); /* * Notify EMM-AS SAP that Detach Request message has to @@ -413,10 +413,10 @@ void *_emm_detach_t3421_handler(void *args) /* Set the switch-off indicator */ emm_as->switch_off = _emm_detach_data.switch_off; /* Set the EPS mobile identity */ - emm_as->guti = _emm_data.guti; + emm_as->guti = user->emm_data->guti; emm_as->ueid = 0; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, _emm_data.security, + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); /* diff --git a/openair3/NAS/UE/EMM/EmmStatusHdl.c b/openair3/NAS/UE/EMM/EmmStatusHdl.c index c0c1fc24de..320ca985ff 100644 --- a/openair3/NAS/UE/EMM/EmmStatusHdl.c +++ b/openair3/NAS/UE/EMM/EmmStatusHdl.c @@ -134,8 +134,8 @@ int emm_proc_status(nas_user_t *user, unsigned int ueid, int emm_cause) emm_sap.u.emm_as.u.status.emm_cause = emm_cause; emm_sap.u.emm_as.u.status.ueid = ueid; - emm_sap.u.emm_as.u.status.guti = _emm_data.guti; - sctx = _emm_data.security; + emm_sap.u.emm_as.u.status.guti = user->emm_data->guti; + sctx = user->emm_data->security; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, FALSE, TRUE); diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c index ce64e65850..53bc008cab 100644 --- a/openair3/NAS/UE/EMM/Identification.c +++ b/openair3/NAS/UE/EMM/Identification.c @@ -130,8 +130,8 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t imsi_t modified_imsi; /* International Mobile Subscriber Identity is requested */ - if (_emm_data.imsi) { - memcpy (&modified_imsi, _emm_data.imsi, sizeof (modified_imsi)); + if (user->emm_data->imsi) { + memcpy (&modified_imsi, user->emm_data->imsi, sizeof (modified_imsi)); /* LW: Eventually replace the 0xF value set in MNC digit 3 by a 0 to avoid IMSI to be truncated before reaching HSS */ if (modified_imsi.u.num.digit6 == 0xF) { @@ -167,9 +167,9 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t case EMM_IDENT_TYPE_IMEI: /* International Mobile Equipment Identity is requested */ - if (_emm_data.imei) { + if (user->emm_data->imei) { emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_IMEI; - emm_sap.u.emm_as.u.security.imei = _emm_data.imei; + emm_sap.u.emm_as.u.security.imei = user->emm_data->imei; } break; @@ -177,9 +177,9 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t case EMM_IDENT_TYPE_TMSI: /* Temporary Mobile Subscriber Identity is requested */ - if (_emm_data.guti) { + if (user->emm_data->guti) { emm_sap.u.emm_as.u.security.identType = EMM_IDENT_TYPE_TMSI; - emm_sap.u.emm_as.u.security.tmsi = _emm_data.guti->m_tmsi; + emm_sap.u.emm_as.u.security.tmsi = user->emm_data->guti->m_tmsi; } break; @@ -194,12 +194,12 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t * to the MME */ emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; emm_sap.u.emm_as.u.security.ueid = 0; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, FALSE, TRUE); + user->emm_data->security, FALSE, TRUE); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index f7e3274614..8570a58789 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -269,10 +269,9 @@ int IdleMode_get_splmn_index(void) ** ** ** Outputs: None ** ** Return: The size of the list in bytes ** - ** Others: _emm_data.plist ** ** ** ***************************************************************************/ -int IdleMode_update_plmn_list(int i) +int IdleMode_update_plmn_list(emm_data_t *emm_data, int i) { int offset = 0; int n = 1; @@ -281,22 +280,22 @@ int IdleMode_update_plmn_list(int i) struct plmn_param_t *plmn = &(_emm_plmn_list.param[i++]); if (n++ > 1) { - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, ","); } - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, "(%d,%s,%s,%s", plmn->stat, plmn->fullname, plmn->shortname, plmn->num); if (plmn->rat != NET_ACCESS_UNAVAILABLE) { - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, ",%d", plmn->rat); } - offset += snprintf(_emm_data.plist.buffer + offset, + offset += snprintf(emm_data->plist.buffer + offset, EMM_DATA_BUFFER_SIZE - offset, ")"); } @@ -503,7 +502,7 @@ int IdleMode_get_plmn_id_index(const char *plmn) ** to PLMN selection procedure. ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -518,21 +517,21 @@ int emm_proc_initialize(nas_user_t *user) int rc; int i; - if (!_emm_data.usim_is_valid) { + if (!user->emm_data->usim_is_valid) { /* The USIM application is not present or not valid */ LOG_TRACE(WARNING, "EMM-IDLE - USIM is not valid"); emm_sap.primitive = EMMREG_NO_IMSI; } else { /* The highest priority is given to either the "equivalent PLMNs" * if available, or the last registered PLMN */ - if (_emm_data.nvdata.eplmn.n_plmns > 0) { - for (i=0; i < _emm_data.nvdata.eplmn.n_plmns; i++) { + if (user->emm_data->nvdata.eplmn.n_plmns > 0) { + for (i=0; i < user->emm_data->nvdata.eplmn.n_plmns; i++) { _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.nvdata.eplmn.plmn[i]; + &user->emm_data->nvdata.eplmn.plmn[i]; } - } else if ( PLMN_IS_VALID(_emm_data.nvdata.rplmn) ) { + } else if ( PLMN_IS_VALID(user->emm_data->nvdata.rplmn) ) { _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.nvdata.rplmn; + &user->emm_data->nvdata.rplmn; } /* Update the index of the HPLMN or EHPLM of highest priority. @@ -544,25 +543,25 @@ int emm_proc_initialize(nas_user_t *user) /* Add the highest priority PLMN in the list of "equivalent HPLMNs" if present and not empty, or the HPLMN derived from the IMSI */ - if (_emm_data.ehplmn.n_plmns > 0) { + if (user->emm_data->ehplmn.n_plmns > 0) { _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.ehplmn.plmn[0]; + &user->emm_data->ehplmn.plmn[0]; } else { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &_emm_data.hplmn; + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &user->emm_data->hplmn; } /* Each PLMN/access technology combination in the "User * Controlled PLMN Selector with Access Technology" */ - for (i=0; i < _emm_data.plmn.n_plmns; i++) { + for (i=0; i < user->emm_data->plmn.n_plmns; i++) { _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.plmn.plmn[i]; + &user->emm_data->plmn.plmn[i]; } /* Each PLMN/access technology combination in the "Operator * Controlled PLMN Selector with Access Technology" */ - for (i=0; i < _emm_data.oplmn.n_plmns; i++) { + for (i=0; i < user->emm_data->oplmn.n_plmns; i++) { _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = - &_emm_data.oplmn.plmn[i]; + &user->emm_data->oplmn.plmn[i]; } /* Other PLMN/access technology combinations with received @@ -582,9 +581,9 @@ int emm_proc_initialize(nas_user_t *user) plmn->fullname[0] = '\0'; plmn->shortname[0] = '\0'; } else { - strncpy(plmn->fullname, _emm_data.opnn[id].fullname, + strncpy(plmn->fullname, user->emm_data->opnn[id].fullname, NET_FORMAT_LONG_SIZE); - strncpy(plmn->shortname, _emm_data.opnn[id].shortname, + strncpy(plmn->shortname, user->emm_data->opnn[id].shortname, NET_FORMAT_SHORT_SIZE); } @@ -627,7 +626,7 @@ int emm_proc_initialize(nas_user_t *user) ** mode. ** ** ** ** Inputs: None ** - ** Others: _emm_plmn_list, _emm_data ** + ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ** Outputs: None ** ** Return: None ** @@ -640,7 +639,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) int rc = RETURNok; - if (_emm_data.plmn_mode != EMM_DATA_PLMN_AUTO) { + if (user->emm_data->plmn_mode != EMM_DATA_PLMN_AUTO) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- @@ -649,13 +648,13 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) /* * Selection of the last registered or equivalent PLMNs failed */ - if (_emm_data.plmn_index < 0) { + if (user->emm_data->plmn_index < 0) { /* * The user did not select any PLMN yet; display the ordered * list of available PLMNs to the user */ index = -1; - rc = emm_proc_network_notify(_emm_plmn_list.hplmn); + rc = emm_proc_network_notify(user->emm_data, _emm_plmn_list.hplmn); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify " @@ -665,7 +664,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) /* * Try to register to the PLMN manually selected by the user */ - index = _emm_data.plmn_index; + index = user->emm_data->plmn_index; } } } @@ -714,11 +713,11 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) ** ci: The identifier of the cell ** ** rat: The radio access technology supported by ** ** the cell ** - ** Others: _emm_plmn_list, _emm_data ** + ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_plmn_list, _emm_data ** + ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ***************************************************************************/ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat) @@ -732,15 +731,15 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode", (found)? "One" : "No", index, - (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); if (found) { int is_forbidden = FALSE; /* Select the PLMN of which a suitable cell has been found */ - _emm_data.splmn = *_emm_plmn_list.plmn[index]; + user->emm_data->splmn = *_emm_plmn_list.plmn[index]; /* Update the selected PLMN's parameters */ _emm_plmn_list.param[index].tac = tac; @@ -748,13 +747,13 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, _emm_plmn_list.param[index].rat = rat; /* Update the location data and notify EMM that data have changed */ - rc = emm_proc_location_notify(tac, ci , rat); + rc = emm_proc_location_notify(user->emm_data, tac, ci , rat); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update"); } - if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) { + if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -762,17 +761,17 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, int i; /* Check if the selected PLMN is in the forbidden list */ - for (i = 0; i < _emm_data.fplmn.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(_emm_data.splmn, _emm_data.fplmn.plmn[i])) { + for (i = 0; i < user->emm_data->fplmn.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(user->emm_data->splmn, user->emm_data->fplmn.plmn[i])) { is_forbidden = TRUE; break; } } if (!is_forbidden) { - for (i = 0; i < _emm_data.fplmn_gprs.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(_emm_data.splmn, - _emm_data.fplmn_gprs.plmn[i])) { + for (i = 0; i < user->emm_data->fplmn_gprs.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(user->emm_data->splmn, + user->emm_data->fplmn_gprs.plmn[i])) { is_forbidden = TRUE; break; } @@ -782,12 +781,12 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, /* Check if the selected PLMN belongs to a forbidden * tracking area */ tai_t tai; - tai.plmn = _emm_data.splmn; + tai.plmn = user->emm_data->splmn; tai.tac = tac; if (!is_forbidden) { - for (i = 0; i < _emm_data.ftai.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, _emm_data.ftai.tai[i])) { + for (i = 0; i < user->emm_data->ftai.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai.tai[i])) { is_forbidden = TRUE; break; } @@ -795,8 +794,8 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, } if (!is_forbidden) { - for (i = 0; i < _emm_data.ftai_roaming.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, _emm_data.ftai_roaming.tai[i])) { + for (i = 0; i < user->emm_data->ftai_roaming.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai_roaming.tai[i])) { is_forbidden = TRUE; break; } @@ -825,10 +824,10 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, } /* Duplicate the new selected PLMN at the end of the ordered list */ - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &_emm_data.splmn; + _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &user->emm_data->splmn; } - else if (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO) { + else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -844,7 +843,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, } } - else if (_emm_data.plmn_index < 0) { + else if (user->emm_data->plmn_index < 0) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- @@ -855,7 +854,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, select_next_plmn = TRUE; } - else if (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL) { + else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { /* * Manual mode of operation * ------------------------ @@ -871,7 +870,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Attempt to find a suitable cell of the PLMN selected by the user * failed; Try to automatically select another PLMN */ - _emm_data.plmn_mode = EMM_DATA_PLMN_AUTO; + user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; index = _emm_plmn_list.hplmn; select_next_plmn = TRUE; } @@ -938,11 +937,11 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) { /* The selected PLMN is the registered PLMN */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is the registered PLMN"); - _emm_data.is_rplmn = TRUE; + user->emm_data->is_rplmn = TRUE; } else if (_emm_plmn_list.splmn < _emm_plmn_list.hplmn) { /* The selected PLMN is in the list of equivalent PLMNs */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is in the list of equivalent PLMNs"); - _emm_data.is_eplmn = TRUE; + user->emm_data->is_eplmn = TRUE; } /* @@ -976,20 +975,20 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_registration_notify(Stat_t status) +int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status) { LOG_FUNC_IN; int rc = RETURNok; /* Update the network registration status */ - if (_emm_data.stat != status) { - _emm_data.stat = status; + if (emm_data->stat != status) { + emm_data->stat = status; /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(1); + rc = (*_emm_indication_notify)(emm_data, 1); } LOG_FUNC_RETURN (rc); @@ -1010,24 +1009,24 @@ int emm_proc_registration_notify(Stat_t status) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat) +int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat) { LOG_FUNC_IN; int rc = RETURNok; /* Update the location information */ - if ( (_emm_data.tac != tac) || - (_emm_data.ci != ci) || - (_emm_data.rat != rat) ) { - _emm_data.tac = tac; - _emm_data.ci = ci; - _emm_data.rat = rat; + if ( (emm_data->tac != tac) || + (emm_data->ci != ci) || + (emm_data->rat != rat) ) { + emm_data->tac = tac; + emm_data->ci = ci; + emm_data->rat = rat; /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(0); + rc = (*_emm_indication_notify)(emm_data, 0); } LOG_FUNC_RETURN (rc); @@ -1047,17 +1046,17 @@ int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_network_notify(int index) +int emm_proc_network_notify(emm_data_t *emm_data, int index) { LOG_FUNC_IN; /* Update the list of operators present in the network */ - int size = IdleMode_update_plmn_list(index); + int size = IdleMode_update_plmn_list(emm_data, index); /* Notify EMM that data has changed */ - int rc = (*_emm_indication_notify)(size); + int rc = (*_emm_indication_notify)(emm_data, size); LOG_FUNC_RETURN (rc); } @@ -1126,7 +1125,7 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** tor network name records ** ** ** ** Inputs: plmn: The PLMN identifier ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: The index of the PLMN if found in the list ** @@ -1139,28 +1138,28 @@ static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) { int i; - for (i = 0; i < _emm_data.n_opnns; i++) { - if (plmn->MCCdigit1 != _emm_data.opnn[i].plmn->MCCdigit1) { + for (i = 0; i < user->emm_data->n_opnns; i++) { + if (plmn->MCCdigit1 != user->emm_data->opnn[i].plmn->MCCdigit1) { continue; } - if (plmn->MCCdigit2 != _emm_data.opnn[i].plmn->MCCdigit2) { + if (plmn->MCCdigit2 != user->emm_data->opnn[i].plmn->MCCdigit2) { continue; } - if (plmn->MCCdigit3 != _emm_data.opnn[i].plmn->MCCdigit3) { + if (plmn->MCCdigit3 != user->emm_data->opnn[i].plmn->MCCdigit3) { continue; } - if (plmn->MNCdigit1 != _emm_data.opnn[i].plmn->MNCdigit1) { + if (plmn->MNCdigit1 != user->emm_data->opnn[i].plmn->MNCdigit1) { continue; } - if (plmn->MNCdigit2 != _emm_data.opnn[i].plmn->MNCdigit2) { + if (plmn->MNCdigit2 != user->emm_data->opnn[i].plmn->MNCdigit2) { continue; } - if (plmn->MNCdigit3 != _emm_data.opnn[i].plmn->MNCdigit3) { + if (plmn->MNCdigit3 != user->emm_data->opnn[i].plmn->MNCdigit3) { continue; } @@ -1195,8 +1194,8 @@ static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) LOG_TRACE(INFO, "EMM-IDLE - Trying to search a suitable cell " "of PLMN %d in %s mode", index, - (_emm_data.plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (_emm_data.plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); /* * Notify EMM-AS SAP that cell information related to the given @@ -1206,8 +1205,8 @@ static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) emm_sap.u.emm_as.u.cell_info.plmnIDs.n_plmns = 1; emm_sap.u.emm_as.u.cell_info.plmnIDs.plmn[0] = *plmn; - if (_emm_data.plmn_rat != NET_ACCESS_UNAVAILABLE) { - emm_sap.u.emm_as.u.cell_info.rat = (1 << _emm_data.plmn_rat); + if (user->emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) { + emm_sap.u.emm_as.u.cell_info.rat = (1 << user->emm_data->plmn_rat); } else { emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE; } diff --git a/openair3/NAS/UE/EMM/IdleMode.h b/openair3/NAS/UE/EMM/IdleMode.h index f602cb37b0..17b0eabee5 100644 --- a/openair3/NAS/UE/EMM/IdleMode.h +++ b/openair3/NAS/UE/EMM/IdleMode.h @@ -51,7 +51,7 @@ Description Defines the functions used to get information from the list /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ -typedef int (*IdleMode_callback_t) (int); +typedef int (*IdleMode_callback_t) (emm_data_t *emm_data, int); /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ @@ -68,7 +68,7 @@ int IdleMode_get_hplmn_index(void); int IdleMode_get_rplmn_index(void); int IdleMode_get_splmn_index(void); -int IdleMode_update_plmn_list(int index); +int IdleMode_update_plmn_list(emm_data_t *emm_data, int i); const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, size_t *len); diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c index afe8f37c1b..ab1d5c6cf8 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.c +++ b/openair3/NAS/UE/EMM/LowerLayer.c @@ -160,7 +160,7 @@ int lowerlayer_establish(nas_user_t *user) LOG_FUNC_IN; /* Update the EPS Connection Management status */ - _emm_data.ecm_status = ECM_CONNECTED; + user->emm_data->ecm_status = ECM_CONNECTED; LOG_FUNC_RETURN (RETURNok); } @@ -188,7 +188,7 @@ int lowerlayer_release(nas_user_t *user, int cause) int rc; /* Update the EPS Connection Management status */ - _emm_data.ecm_status = ECM_IDLE; + user->emm_data->ecm_status = ECM_IDLE; emm_sap.primitive = EMMREG_LOWERLAYER_RELEASE; emm_sap.u.emm_reg.ueid = 0; @@ -257,9 +257,9 @@ int lowerlayer_data_req(nas_user_t *user, unsigned int ueid, const OctetString * //struct emm_data_context_s *ctx = NULL; emm_sap.primitive = EMMAS_DATA_REQ; - emm_sap.u.emm_as.u.data.guti = _emm_data.guti; + emm_sap.u.emm_as.u.data.guti = user->emm_data->guti; emm_sap.u.emm_as.u.data.ueid = 0; - sctx = _emm_data.security; + sctx = user->emm_data->security; emm_sap.u.emm_as.u.data.NASinfo = 0; emm_sap.u.emm_as.u.data.NASmsg.length = data->length; diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c index 7974f7c3c6..0ea25dbe5f 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c @@ -108,8 +108,7 @@ int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) * Notify EMM that the MT is currently searching an operator * to register to */ - // FIXME REVIEW - rc = emm_proc_registration_notify(NET_REG_STATE_ON); + rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_ON); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c index cea39a5456..bcf089e3cc 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c @@ -95,7 +95,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) /* * No suitable cell of the selected PLMN has been found to camp on */ - rc = emm_proc_registration_notify(NET_REG_STATE_DENIED); + rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_DENIED); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -112,7 +112,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) * may be selected either automatically or manually. * Or the user manually re-selected a PLMN to register to. */ - rc = emm_proc_registration_notify(NET_REG_STATE_ON); + rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_ON); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index 27b6979e04..1072e31319 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -140,7 +140,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) /* * Notify EMM that the MT is registered */ - rc = emm_proc_registration_notify(NET_REG_STATE_HN); + rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_HN); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -167,7 +167,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) /* * Notify EMM that the MT's registration is denied */ - rc = emm_proc_registration_notify(NET_REG_STATE_DENIED); + rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_DENIED); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 8e0c661b09..09a0397055 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -135,16 +135,16 @@ static int _emm_as_encrypt( static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg); -static int _emm_as_security_res(const emm_as_security_t *, +static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *, ul_info_transfer_req_t *); -static int _emm_as_establish_req(const emm_as_establish_t *, +static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *, nas_establish_req_t *); static int _emm_as_cell_info_req(const emm_as_cell_info_t *, cell_info_req_t *); -static int _emm_as_data_req(const emm_as_data_t *msg, ul_info_transfer_req_t *); -static int _emm_as_status_ind(const emm_as_status_t *, ul_info_transfer_req_t *); +static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, ul_info_transfer_req_t *); +static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *, ul_info_transfer_req_t *); static int _emm_as_release_req(const emm_as_release_t *, nas_release_req_t *); /****************************************************************************/ @@ -321,7 +321,7 @@ static int _emm_as_recv(nas_user_t *user, unsigned int ueid, const char *msg, in emm_security_context_t *security = NULL; /* Current EPS NAS security context */ - security = _emm_data.security; + security = user->emm_data->security; /* Decode the received message */ decoder_rc = nas_message_decode(msg, &nas_msg, len, security); @@ -428,7 +428,7 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm memset(&header, 0, sizeof(header)); /* Decrypt the received security protected message */ - security = _emm_data.security; + security = user->emm_data->security; int bytes = nas_message_decrypt((char *)(msg->NASmsg.value), plain_msg, &header, @@ -509,7 +509,7 @@ static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg decoder_rc = nas_message_decode((char *)(msg->NASmsg.value), &nas_msg, msg->NASmsg.length, - _emm_data.security); + user->emm_data->security); if (decoder_rc < 0) { LOG_TRACE(WARNING, "EMMAS-SAP - Failed to decode initial NAS message" @@ -937,13 +937,13 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) switch (msg->primitive) { case _EMMAS_DATA_REQ: - as_msg.msgID = _emm_as_data_req( + as_msg.msgID = _emm_as_data_req(user->emm_data, &msg->u.data, &as_msg.msg.ul_info_transfer_req); break; case _EMMAS_STATUS_IND: - as_msg.msgID = _emm_as_status_ind( + as_msg.msgID = _emm_as_status_ind(user->emm_data, &msg->u.status, &as_msg.msg.ul_info_transfer_req); break; @@ -956,13 +956,13 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) case _EMMAS_SECURITY_RES: - as_msg.msgID = _emm_as_security_res( + as_msg.msgID = _emm_as_security_res(user->emm_data, &msg->u.security, &as_msg.msg.ul_info_transfer_req); break; case _EMMAS_ESTABLISH_REQ: - as_msg.msgID = _emm_as_establish_req( + as_msg.msgID = _emm_as_establish_req(user->emm_data, &msg->u.establish, &as_msg.msg.nas_establish_req); break; @@ -1065,7 +1065,7 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_data_req(const emm_as_data_t *msg, +static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg, ul_info_transfer_req_t *as_msg) { LOG_FUNC_IN; @@ -1112,7 +1112,7 @@ static int _emm_as_data_req(const emm_as_data_t *msg, int bytes; emm_security_context_t *emm_security_context = NULL; - emm_security_context = _emm_data.security; + emm_security_context = emm_data->security; if (emm_security_context) { @@ -1161,7 +1161,7 @@ static int _emm_as_data_req(const emm_as_data_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_status_ind(const emm_as_status_t *msg, +static int _emm_as_status_ind(const emm_data_t *emm_data, const emm_as_status_t *msg, ul_info_transfer_req_t *as_msg) { LOG_FUNC_IN; @@ -1193,7 +1193,7 @@ static int _emm_as_status_ind(const emm_as_status_t *msg, if (size > 0) { emm_security_context_t *emm_security_context = NULL; - emm_security_context = _emm_data.security; + emm_security_context = emm_data->security; if (emm_security_context) { @@ -1275,7 +1275,7 @@ static int _emm_as_release_req(const emm_as_release_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_security_res(const emm_as_security_t *msg, +static int _emm_as_security_res(const emm_data_t *emm_data, const emm_as_security_t *msg, ul_info_transfer_req_t *as_msg) { LOG_FUNC_IN; @@ -1340,7 +1340,7 @@ static int _emm_as_security_res(const emm_as_security_t *msg, int bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size, - _emm_data.security); + emm_data->security); if (bytes > 0) { LOG_FUNC_RETURN (AS_UL_INFO_TRANSFER_REQ); @@ -1369,7 +1369,7 @@ static int _emm_as_security_res(const emm_as_security_t *msg, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_establish_req(const emm_as_establish_t *msg, +static int _emm_as_establish_req(const emm_data_t *emm_data, const emm_as_establish_t *msg, nas_establish_req_t *as_msg) { LOG_FUNC_IN; @@ -1433,7 +1433,7 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg, &as_msg->initialNasMsg, &nas_msg, size, - _emm_data.security); + emm_data->security); if (bytes > 0) { LOG_FUNC_RETURN (AS_NAS_ESTABLISH_REQ); diff --git a/openair3/NAS/UE/EMM/SAP/emm_esm.c b/openair3/NAS/UE/EMM/SAP/emm_esm.c index 10b34f0a1d..b3a494ad49 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esm.c +++ b/openair3/NAS/UE/EMM/SAP/emm_esm.c @@ -134,7 +134,7 @@ int emm_esm_send(nas_user_t *user, const emm_esm_t *msg) if (msg->u.establish.is_emergency) { /* Consider the UE attached for emergency bearer services * only */ - rc = emm_proc_attach_set_emergency(); + rc = emm_proc_attach_set_emergency(user->emm_data); } } else { /* Consider the UE locally detached from the network */ diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 05f094b22d..1126f087dd 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -163,8 +163,8 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, /* * Check the replayed UE security capabilities */ - uint8_t eea = (0x80 >> _emm_data.security->capability.eps_encryption); - uint8_t eia = (0x80 >> _emm_data.security->capability.eps_integrity); + uint8_t eea = (0x80 >> user->emm_data->security->capability.eps_encryption); + uint8_t eia = (0x80 >> user->emm_data->security->capability.eps_integrity); if ( (reea != eea) || (reia != eia) ) { LOG_TRACE(WARNING, "EMM-PROC - Replayed UE security capabilities " @@ -180,7 +180,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, /* * Check the non-current EPS security context */ - else if (_emm_data.non_current == NULL) { + else if (user->emm_data->non_current == NULL) { LOG_TRACE(WARNING, "EMM-PROC - Non-current EPS security context " "is not valid"); emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; @@ -191,37 +191,37 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, else { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context seea=%u seia=%u", seea, seia); /* Update selected cyphering and integrity algorithms */ - //LG COMENTED _emm_data.non_current->capability.encryption = seea; - //LG COMENTED _emm_data.non_current->capability.integrity = seia; + //LG COMENTED user->emm_data->non_current->capability.encryption = seea; + //LG COMENTED user->emm_data->non_current->capability.integrity = seia; - _emm_data.non_current->selected_algorithms.encryption = seea; - _emm_data.non_current->selected_algorithms.integrity = seia; + user->emm_data->non_current->selected_algorithms.encryption = seea; + user->emm_data->non_current->selected_algorithms.integrity = seia; /* Derive the NAS cyphering key */ - if (_emm_data.non_current->knas_enc.value == NULL) { - _emm_data.non_current->knas_enc.value = + if (user->emm_data->non_current->knas_enc.value == NULL) { + user->emm_data->non_current->knas_enc.value = (uint8_t *)calloc(1,AUTH_KNAS_ENC_SIZE); - _emm_data.non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE; + user->emm_data->non_current->knas_enc.length = AUTH_KNAS_ENC_SIZE; } - if (_emm_data.non_current->knas_enc.value != NULL) { + if (user->emm_data->non_current->knas_enc.value != NULL) { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context knas_enc"); - rc = _security_knas_enc(&_emm_data.non_current->kasme, - &_emm_data.non_current->knas_enc, seea); + rc = _security_knas_enc(&user->emm_data->non_current->kasme, + &user->emm_data->non_current->knas_enc, seea); } /* Derive the NAS integrity key */ - if (_emm_data.non_current->knas_int.value == NULL) { - _emm_data.non_current->knas_int.value = + if (user->emm_data->non_current->knas_int.value == NULL) { + user->emm_data->non_current->knas_int.value = (uint8_t *)calloc(1,AUTH_KNAS_INT_SIZE); - _emm_data.non_current->knas_int.length = AUTH_KNAS_INT_SIZE; + user->emm_data->non_current->knas_int.length = AUTH_KNAS_INT_SIZE; } - if (_emm_data.non_current->knas_int.value != NULL) { + if (user->emm_data->non_current->knas_int.value != NULL) { if (rc != RETURNerror) { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context knas_int"); - rc = _security_knas_int(&_emm_data.non_current->kasme, - &_emm_data.non_current->knas_int, seia); + rc = _security_knas_int(&user->emm_data->non_current->kasme, + &user->emm_data->non_current->knas_int, seia); } } @@ -234,10 +234,10 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, if (_security_data.kenb.value != NULL) { if (rc != RETURNerror) { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context kenb"); - // LG COMMENT rc = _security_kenb(&_emm_data.security->kasme, - rc = _security_kenb(&_emm_data.non_current->kasme, + // LG COMMENT rc = _security_kenb(&user->emm_data->security->kasme, + rc = _security_kenb(&user->emm_data->non_current->kasme, &_security_data.kenb, - *(uint32_t *)(&_emm_data.non_current->ul_count)); + *(uint32_t *)(&user->emm_data->non_current->ul_count)); } } @@ -248,13 +248,13 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, LOG_TRACE(INFO, "EMM-PROC - NAS security mode command accepted by the UE"); /* Update the current EPS security context */ - if ( native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { + if ( native_ksi && (user->emm_data->security->type != EMM_KSI_NATIVE) ) { /* The type of security context flag included in the SECURITY * MODE COMMAND message is set to "native security context" and * the UE has a mapped EPS security context as the current EPS * security context */ - if ( (_emm_data.non_current->type == EMM_KSI_NATIVE) && - (_emm_data.non_current->eksi == ksi) ) { + if ( (user->emm_data->non_current->type == EMM_KSI_NATIVE) && + (user->emm_data->non_current->eksi == ksi) ) { /* The KSI matches the non-current native EPS security * context; the UE shall take the non-current native EPS * security context into use which then becomes the @@ -263,36 +263,37 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, LOG_TRACE(INFO, "EMM-PROC - Update Current security context"); /* Release non-current security context */ - _security_release(_emm_data.security); - _emm_data.security = _emm_data.non_current; + _security_release(user->emm_data->security); + user->emm_data->security = user->emm_data->non_current; /* Reset the uplink NAS COUNT counter */ - _emm_data.security->ul_count.overflow = 0; - _emm_data.security->ul_count.seq_num = 0; + user->emm_data->security->ul_count.overflow = 0; + user->emm_data->security->ul_count.seq_num = 0; /* Set new security context indicator */ security_context_is_new = TRUE; } } - if ( !native_ksi && (_emm_data.security->type != EMM_KSI_NATIVE) ) { + if ( !native_ksi && (user->emm_data->security->type != EMM_KSI_NATIVE) ) { /* The type of security context flag included in the SECURITY * MODE COMMAND message is set to "mapped security context" and * the UE has a mapped EPS security context as the current EPS * security context */ - if (ksi != _emm_data.security->eksi) { + if (ksi != user->emm_data->security->eksi) { /* The KSI does not match the current EPS security context; * the UE shall reset the uplink NAS COUNT counter */ LOG_TRACE(INFO, "EMM-PROC - Reset uplink NAS COUNT counter"); - _emm_data.security->ul_count.overflow = 0; - _emm_data.security->ul_count.seq_num = 0; + user->emm_data->security->ul_count.overflow = 0; + user->emm_data->security->ul_count.seq_num = 0; } } - _emm_data.security->selected_algorithms.encryption = seea; - _emm_data.security->selected_algorithms.integrity = seia; + user->emm_data->security->selected_algorithms.encryption = seea; + user->emm_data->security->selected_algorithms.integrity = seia; #if defined(NAS_BUILT_IN_UE) nas_itti_kenb_refresh_req(_security_data.kenb.value); #endif + } /* * NAS security mode command not accepted by the UE @@ -326,14 +327,14 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, */ emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; - emm_sap.u.emm_as.u.security.guti = _emm_data.guti; + emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; emm_sap.u.emm_as.u.security.ueid = 0; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_SMC; emm_sap.u.emm_as.u.security.imeisv_request = imeisv_request; emm_sap.u.emm_as.u.security.emm_cause = emm_cause; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - _emm_data.security, security_context_is_new, TRUE); + user->emm_data->security, security_context_is_new, TRUE); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index df89fb0c8e..2618c44b83 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -333,13 +333,6 @@ typedef struct emm_data_s { /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ -/* - * -------------------------------------------------------------------------- - * EPS mobility management data (used within EMM only) - * -------------------------------------------------------------------------- - */ -emm_data_t _emm_data; - /* * -------------------------------------------------------------------------- * EPS mobility management timers – UE side diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index e3342ed3ba..591c9e6b0f 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -78,7 +78,7 @@ static usim_data_t _usim_data; * to the user application */ static emm_indication_callback_t _emm_main_user_callback; -static int _emm_main_callback(int); +static int _emm_main_callback(emm_data_t *emm_data, int); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -97,66 +97,70 @@ static int _emm_main_callback(int); ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei) { LOG_FUNC_IN; - + user->emm_data = calloc(1, sizeof(emm_data_t)); + if ( user->emm_data == NULL ) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to get allocate emm_data"); + // FIXME stop here + } /* USIM validity indicator */ - _emm_data.usim_is_valid = FALSE; + user->emm_data->usim_is_valid = FALSE; /* The IMEI read from the UE's non-volatile memory */ - _emm_data.imei = (imei_t *)malloc(sizeof(imei_t)); - _emm_data.imei->length = _emm_main_get_imei(_emm_data.imei, imei); + user->emm_data->imei = (imei_t *)malloc(sizeof(imei_t)); + user->emm_data->imei->length = _emm_main_get_imei(user->emm_data->imei, imei); /* The IMSI, valid only if USIM is present */ - _emm_data.imsi = NULL; + user->emm_data->imsi = NULL; /* EPS location information */ - _emm_data.guti = NULL; - _emm_data.tai = NULL; - _emm_data.ltai.n_tais = 0; + user->emm_data->guti = NULL; + user->emm_data->tai = NULL; + user->emm_data->ltai.n_tais = 0; /* EPS Connection Management status */ - _emm_data.ecm_status = ECM_IDLE; + user->emm_data->ecm_status = ECM_IDLE; /* Network selection mode of operation */ - _emm_data.plmn_mode = EMM_DATA_PLMN_AUTO; + user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; /* Index of the PLMN manually selected by the user */ - _emm_data.plmn_index = -1; + user->emm_data->plmn_index = -1; /* Selected Radio Access Technology */ - _emm_data.plmn_rat = NET_ACCESS_UNAVAILABLE; + user->emm_data->plmn_rat = NET_ACCESS_UNAVAILABLE; /* Selected PLMN */ - memset(&_emm_data.splmn, 0xFF, sizeof(plmn_t)); - _emm_data.is_rplmn = FALSE; - _emm_data.is_eplmn = FALSE; + memset(&user->emm_data->splmn, 0xFF, sizeof(plmn_t)); + user->emm_data->is_rplmn = FALSE; + user->emm_data->is_eplmn = FALSE; /* Radio Access Technology of the serving cell */ - _emm_data.rat = NET_ACCESS_UNAVAILABLE; + user->emm_data->rat = NET_ACCESS_UNAVAILABLE; /* Network registration status */ - _emm_data.stat = NET_REG_STATE_OFF; - _emm_data.is_attached = FALSE; - _emm_data.is_emergency = FALSE; + user->emm_data->stat = NET_REG_STATE_OFF; + user->emm_data->is_attached = FALSE; + user->emm_data->is_emergency = FALSE; /* Location/Tracking area code */ - _emm_data.tac = 0; // two byte in hexadecimal format + user->emm_data->tac = 0; // two byte in hexadecimal format /* Identifier of the serving cell */ - _emm_data.ci = 0; // four byte in hexadecimal format + user->emm_data->ci = 0; // four byte in hexadecimal format /* List of operators present in the network */ - memset(_emm_data.plist.buffer, 0, EMM_DATA_BUFFER_SIZE + 1); + memset(user->emm_data->plist.buffer, 0, EMM_DATA_BUFFER_SIZE + 1); /* Home PLMN */ - memset(&_emm_data.hplmn, 0xFF, sizeof(plmn_t)); + memset(&user->emm_data->hplmn, 0xFF, sizeof(plmn_t)); /* List of Forbidden PLMNs */ - _emm_data.fplmn.n_plmns = 0; + user->emm_data->fplmn.n_plmns = 0; /* List of Forbidden PLMNs for GPRS service */ - _emm_data.fplmn_gprs.n_plmns = 0; + user->emm_data->fplmn_gprs.n_plmns = 0; /* List of Equivalent HPLMNs */ - _emm_data.ehplmn.n_plmns = 0; + user->emm_data->ehplmn.n_plmns = 0; /* List of user controlled PLMNs */ - _emm_data.plmn.n_plmns = 0; + user->emm_data->plmn.n_plmns = 0; /* List of operator controlled PLMNs */ - _emm_data.oplmn.n_plmns = 0; + user->emm_data->oplmn.n_plmns = 0; /* List of operator network name records */ - _emm_data.n_opnns = 0; + user->emm_data->n_opnns = 0; /* List of Forbidden Tracking Areas */ - _emm_data.ftai.n_tais = 0; + user->emm_data->ftai.n_tais = 0; /* List of Forbidden Tracking Areas for roaming */ - _emm_data.ftai_roaming.n_tais = 0; + user->emm_data->ftai_roaming.n_tais = 0; /* * Get USIM application data @@ -170,47 +174,47 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* The USIM application is present and valid */ LOG_TRACE(INFO, "EMM-MAIN - USIM application data successfully read"); - _emm_data.usim_is_valid = TRUE; + user->emm_data->usim_is_valid = TRUE; /* Get the Home PLMN derived from the IMSI */ - _emm_data.hplmn.MCCdigit1 = _usim_data.imsi.u.num.digit1; - _emm_data.hplmn.MCCdigit2 = _usim_data.imsi.u.num.digit2; - _emm_data.hplmn.MCCdigit3 = _usim_data.imsi.u.num.digit3; - _emm_data.hplmn.MNCdigit1 = _usim_data.imsi.u.num.digit4; - _emm_data.hplmn.MNCdigit2 = _usim_data.imsi.u.num.digit5; - _emm_data.hplmn.MNCdigit3 = _usim_data.imsi.u.num.digit6; + user->emm_data->hplmn.MCCdigit1 = _usim_data.imsi.u.num.digit1; + user->emm_data->hplmn.MCCdigit2 = _usim_data.imsi.u.num.digit2; + user->emm_data->hplmn.MCCdigit3 = _usim_data.imsi.u.num.digit3; + user->emm_data->hplmn.MNCdigit1 = _usim_data.imsi.u.num.digit4; + user->emm_data->hplmn.MNCdigit2 = _usim_data.imsi.u.num.digit5; + user->emm_data->hplmn.MNCdigit3 = _usim_data.imsi.u.num.digit6; /* Get the list of forbidden PLMNs */ for (i=0; (i < EMM_DATA_FPLMN_MAX) && (i < USIM_FPLMN_MAX); i++) { if ( PLMN_IS_VALID(_usim_data.fplmn[i]) ) { - _emm_data.fplmn.plmn[i] = _usim_data.fplmn[i]; - _emm_data.fplmn.n_plmns += 1; + user->emm_data->fplmn.plmn[i] = _usim_data.fplmn[i]; + user->emm_data->fplmn.n_plmns += 1; } } /* Get the list of Equivalent HPLMNs */ for (i=0; (i < EMM_DATA_EHPLMN_MAX) && (i < USIM_EHPLMN_MAX); i++) { if ( PLMN_IS_VALID(_usim_data.ehplmn[i]) ) { - _emm_data.ehplmn.plmn[i] = _usim_data.ehplmn[i]; - _emm_data.ehplmn.n_plmns += 1; + user->emm_data->ehplmn.plmn[i] = _usim_data.ehplmn[i]; + user->emm_data->ehplmn.n_plmns += 1; } } /* Get the list of User controlled PLMN Selector */ for (i=0; (i < EMM_DATA_PLMN_MAX) && (i < USIM_PLMN_MAX); i++) { if ( PLMN_IS_VALID(_usim_data.plmn[i].plmn) ) { - _emm_data.plmn.plmn[i] = _usim_data.plmn[i].plmn; - _emm_data.userAcT[i] = _usim_data.plmn[i].AcT; - _emm_data.plmn.n_plmns += 1; + user->emm_data->plmn.plmn[i] = _usim_data.plmn[i].plmn; + user->emm_data->userAcT[i] = _usim_data.plmn[i].AcT; + user->emm_data->plmn.n_plmns += 1; } } /* Get the list of Operator controlled PLMN Selector */ for (i=0; (i < EMM_DATA_OPLMN_MAX) && (i < USIM_OPLMN_MAX); i++) { if ( PLMN_IS_VALID(_usim_data.oplmn[i].plmn) ) { - _emm_data.oplmn.plmn[i] = _usim_data.oplmn[i].plmn; - _emm_data.operAcT[i] = _usim_data.oplmn[i].AcT; - _emm_data.oplmn.n_plmns += 1; + user->emm_data->oplmn.plmn[i] = _usim_data.oplmn[i].plmn; + user->emm_data->operAcT[i] = _usim_data.oplmn[i].AcT; + user->emm_data->oplmn.n_plmns += 1; } } @@ -218,10 +222,10 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c for (i=0; (i < EMM_DATA_OPNN_MAX) && (i < USIM_OPL_MAX); i++) { if ( PLMN_IS_VALID(_usim_data.opl[i].plmn) ) { int pnn_id = _usim_data.opl[i].record_id; - _emm_data.opnn[i].plmn = &_usim_data.opl[i].plmn; - _emm_data.opnn[i].fullname = (char *)_usim_data.pnn[pnn_id].fullname.value; - _emm_data.opnn[i].shortname = (char *)_usim_data.pnn[pnn_id].shortname.value; - _emm_data.n_opnns += 1; + user->emm_data->opnn[i].plmn = &_usim_data.opl[i].plmn; + user->emm_data->opnn[i].fullname = (char *)_usim_data.pnn[pnn_id].fullname.value; + user->emm_data->opnn[i].shortname = (char *)_usim_data.pnn[pnn_id].shortname.value; + user->emm_data->n_opnns += 1; } } @@ -229,78 +233,78 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* Get the EPS location information */ if (PLMN_IS_VALID(_usim_data.epsloci.guti.gummei.plmn)) { - _emm_data.guti = &_usim_data.epsloci.guti; + user->emm_data->guti = &_usim_data.epsloci.guti; } if (TAI_IS_VALID(_usim_data.epsloci.tai)) { - _emm_data.tai = &_usim_data.epsloci.tai; + user->emm_data->tai = &_usim_data.epsloci.tai; } - _emm_data.status = _usim_data.epsloci.status; + user->emm_data->status = _usim_data.epsloci.status; /* Get NAS configuration parameters */ - _emm_data.NAS_SignallingPriority = + user->emm_data->NAS_SignallingPriority = _usim_data.nasconfig.NAS_SignallingPriority.value[0]; - _emm_data.NMO_I_Behaviour = _usim_data.nasconfig.NMO_I_Behaviour.value[0]; - _emm_data.AttachWithImsi = _usim_data.nasconfig.AttachWithImsi.value[0]; - _emm_data.MinimumPeriodicSearchTimer = + user->emm_data->NMO_I_Behaviour = _usim_data.nasconfig.NMO_I_Behaviour.value[0]; + user->emm_data->AttachWithImsi = _usim_data.nasconfig.AttachWithImsi.value[0]; + user->emm_data->MinimumPeriodicSearchTimer = _usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0]; - _emm_data.ExtendedAccessBarring = + user->emm_data->ExtendedAccessBarring = _usim_data.nasconfig.ExtendedAccessBarring.value[0]; - _emm_data.Timer_T3245_Behaviour = + user->emm_data->Timer_T3245_Behaviour = _usim_data.nasconfig.Timer_T3245_Behaviour.value[0]; /* * Get EPS NAS security context */ /* Create NAS security context */ - _emm_data.security = + user->emm_data->security = (emm_security_context_t *)malloc(sizeof(emm_security_context_t)); - if (_emm_data.security != NULL) { - memset(_emm_data.security, 0, sizeof(emm_security_context_t)); + if (user->emm_data->security != NULL) { + memset(user->emm_data->security, 0, sizeof(emm_security_context_t)); /* Type of security context */ if (_usim_data.securityctx.KSIasme.value[0] != USIM_KSI_NOT_AVAILABLE) { - _emm_data.security->type = EMM_KSI_NATIVE; + user->emm_data->security->type = EMM_KSI_NATIVE; } else { - _emm_data.security->type = EMM_KSI_NOT_AVAILABLE; + user->emm_data->security->type = EMM_KSI_NOT_AVAILABLE; } /* EPS key set identifier */ - _emm_data.security->eksi = _usim_data.securityctx.KSIasme.value[0]; + user->emm_data->security->eksi = _usim_data.securityctx.KSIasme.value[0]; /* ASME security key */ - _emm_data.security->kasme.length = + user->emm_data->security->kasme.length = _usim_data.securityctx.Kasme.length; - _emm_data.security->kasme.value = - (uint8_t *)malloc(_emm_data.security->kasme.length); + user->emm_data->security->kasme.value = + (uint8_t *)malloc(user->emm_data->security->kasme.length); - if (_emm_data.security->kasme.value) { - memcpy(_emm_data.security->kasme.value, + if (user->emm_data->security->kasme.value) { + memcpy(user->emm_data->security->kasme.value, _usim_data.securityctx.Kasme.value, - _emm_data.security->kasme.length); + user->emm_data->security->kasme.length); } /* Downlink count parameter */ if (_usim_data.securityctx.dlNAScount.length <= sizeof(uint32_t)) { - memcpy(&_emm_data.security->dl_count, + memcpy(&user->emm_data->security->dl_count, _usim_data.securityctx.dlNAScount.value, _usim_data.securityctx.dlNAScount.length); } /* Uplink count parameter */ if (_usim_data.securityctx.ulNAScount.length <= sizeof(uint32_t)) { - memcpy(&_emm_data.security->ul_count, + memcpy(&user->emm_data->security->ul_count, _usim_data.securityctx.ulNAScount.value, _usim_data.securityctx.ulNAScount.length); } /* Ciphering algorithm */ - _emm_data.security->capability.eps_encryption = + user->emm_data->security->capability.eps_encryption = ((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); /* Identity protection algorithm */ - _emm_data.security->capability.eps_integrity = + user->emm_data->security->capability.eps_integrity = (_usim_data.securityctx.algorithmID.value[0] & 0xf); /* NAS integrity and cyphering keys are not available */ } else { @@ -311,8 +315,8 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* * Get EMM data from the UE's non-volatile memory */ - memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); - _emm_data.nvdata.eplmn.n_plmns = 0; + memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); + user->emm_data->nvdata.eplmn.n_plmns = 0; /* Get EMM data pathname */ char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); @@ -320,29 +324,29 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); } else { /* Get EMM data stored in the non-volatile memory device */ - int rc = memory_read(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); + int rc = memory_read(path, &user->emm_data->nvdata, sizeof(emm_nvdata_t)); if (rc != RETURNok) { LOG_TRACE(ERROR, "EMM-MAIN - Failed to read %s", path); } else { /* Check the IMSI */ LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); - _emm_data.imsi = &_usim_data.imsi; - int imsi_ok = _emm_main_imsi_cmp(&_emm_data.nvdata.imsi, + user->emm_data->imsi = &_usim_data.imsi; + int imsi_ok = _emm_main_imsi_cmp(&user->emm_data->nvdata.imsi, &_usim_data.imsi); if (!imsi_ok) { LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed nvram: " "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x, " "usim: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", - _emm_data.nvdata.imsi.u.value[0], - _emm_data.nvdata.imsi.u.value[1], - _emm_data.nvdata.imsi.u.value[2], - _emm_data.nvdata.imsi.u.value[3], - _emm_data.nvdata.imsi.u.value[4], - _emm_data.nvdata.imsi.u.value[5], - _emm_data.nvdata.imsi.u.value[6], - _emm_data.nvdata.imsi.u.value[7], + user->emm_data->nvdata.imsi.u.value[0], + user->emm_data->nvdata.imsi.u.value[1], + user->emm_data->nvdata.imsi.u.value[2], + user->emm_data->nvdata.imsi.u.value[3], + user->emm_data->nvdata.imsi.u.value[4], + user->emm_data->nvdata.imsi.u.value[5], + user->emm_data->nvdata.imsi.u.value[6], + user->emm_data->nvdata.imsi.u.value[7], _usim_data.imsi.u.value[0], _usim_data.imsi.u.value[1], _usim_data.imsi.u.value[2], @@ -351,8 +355,8 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c _usim_data.imsi.u.value[5], _usim_data.imsi.u.value[6], _usim_data.imsi.u.value[7]); - memset(&_emm_data.nvdata.rplmn, 0xFF, sizeof(plmn_t)); - _emm_data.nvdata.eplmn.n_plmns = 0; + memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); + user->emm_data->nvdata.eplmn.n_plmns = 0; } } @@ -392,6 +396,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* * Initialize EMM internal data used for UE in idle mode */ + // FIXME REVIEW IdleMode_initialize(user, &_emm_main_callback); LOG_FUNC_OUT; @@ -412,56 +417,14 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c ** Others: None ** ** ** ***************************************************************************/ -void emm_main_cleanup(void) +void emm_main_cleanup(emm_data_t *emm_data) { LOG_FUNC_IN; - if (_emm_data.usim_is_valid) { + if (emm_data->usim_is_valid) { /* * TODO: Update USIM application data */ -#if 0 - int i; - - /* Update the list of Forbidden PLMNs */ - for (i=0; (i < _emm_data.fplmn.n_plmns) && (i < USIM_FPLMN_MAX); i++) { - _usim_data.fplmn[i] = _emm_data.fplmn.plmn[i]; - } - - /* Update the list of Equivalent HPLMNs */ - for (i=0; (i < _emm_data.ehplmn.n_plmns) && (i < USIM_EHPLMN_MAX); i++) { - _usim_data.ehplmn[i] = _emm_data.ehplmn.plmn[i]; - } - - /* Update the GUTI */ - if (_emm_data.guti) { - _usim_data.epsloci.guti = *(_emm_data.guti); - } - - /* Update the last visited registered TAI */ - if (_emm_data.tai) { - _usim_data.epsloci.tai = *(_emm_data.tai); - } - - /* Update the EPS location information */ - _usim_data.epsloci.status = _emm_data.status; - - if (_emm_data.security && (_emm_data.security->type == EMM_KSI_NATIVE)) { - /* TODO: Update the EPS security context parameters from the full - * native EPS security context */ - } - - /* - * Store USIM application data - * - List of forbidden PLMNs - */ - if ( usim_api_write(&_usim_data) != RETURNok ) { - /* The USIM application may not be present or not valid */ - LOG_TRACE(WARNING, "EMM-MAIN - " - "Failed to write USIM application data"); - } - -#endif } /* @@ -474,7 +437,7 @@ void emm_main_cleanup(void) if (path == NULL) { LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); } else { - int rc = memory_write(path, &_emm_data.nvdata, sizeof(emm_nvdata_t)); + int rc = memory_write(path, &emm_data->nvdata, sizeof(emm_nvdata_t)); if (rc != RETURNok) { LOG_TRACE(ERROR, "EMM-MAIN - Failed to write %s", path); @@ -482,13 +445,13 @@ void emm_main_cleanup(void) } /* Release dynamically allocated memory */ - if (_emm_data.imei) { - free(_emm_data.imei); - _emm_data.imei = NULL; + if (emm_data->imei) { + free(emm_data->imei); + emm_data->imei = NULL; } - if (_emm_data.security) { - emm_security_context_t *security = _emm_data.security; + if (emm_data->security) { + emm_security_context_t *security = emm_data->security; if (security->kasme.value) { free(security->kasme.value); @@ -508,8 +471,8 @@ void emm_main_cleanup(void) security->knas_int.length = 0; } - free(_emm_data.security); - _emm_data.security = NULL; + free(emm_data->security); + emm_data->security = NULL; } LOG_FUNC_OUT; } @@ -521,17 +484,17 @@ void emm_main_cleanup(void) ** Description: Get the International Mobile Subscriber Identity number ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: Pointer to the IMSI ** ** Others: None ** ** ** ***************************************************************************/ -const imsi_t *emm_main_get_imsi(void) +const imsi_t *emm_main_get_imsi(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (&_emm_data.nvdata.imsi); + LOG_FUNC_RETURN (&emm_data->nvdata.imsi); } /**************************************************************************** @@ -572,10 +535,10 @@ const msisdn_t *emm_main_get_msisdn(void) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_main_set_plmn_selection_mode(int mode, int format, +int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, const network_plmn_t *plmn, int rat) { LOG_FUNC_IN; @@ -585,7 +548,7 @@ int emm_main_set_plmn_selection_mode(int mode, int format, LOG_TRACE(INFO, "EMM-MAIN - PLMN selection: mode=%d, format=%d, plmn=%s, " "rat=%d", mode, format, (const char *)&plmn->id, rat); - _emm_data.plmn_mode = mode; + emm_data->plmn_mode = mode; if (mode != EMM_DATA_PLMN_AUTO) { /* Get the index of the PLMN in the list of available PLMNs */ @@ -596,8 +559,8 @@ int emm_main_set_plmn_selection_mode(int mode, int format, (const char *)&plmn->id); } else { /* Update the manually selected network selection data */ - _emm_data.plmn_index = index; - _emm_data.plmn_rat = rat; + emm_data->plmn_index = index; + emm_data->plmn_rat = rat; } } else { /* @@ -619,17 +582,17 @@ int emm_main_set_plmn_selection_mode(int mode, int format, ** operation ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: The value of the network selection mode ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_get_plmn_selection_mode(void) +int emm_main_get_plmn_selection_mode(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.plmn_mode); + LOG_FUNC_RETURN (emm_data->plmn_mode); } /**************************************************************************** @@ -639,19 +602,19 @@ int emm_main_get_plmn_selection_mode(void) ** Description: Get the list of available PLMNs ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: plist: Pointer to the list of available PLMNs ** ** Return: The size of the list in bytes ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_get_plmn_list(const char **plist) +int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist) { LOG_FUNC_IN; - int size = IdleMode_update_plmn_list(0); - *plist = _emm_data.plist.buffer; + int size = IdleMode_update_plmn_list(emm_data, 0); + *plist = emm_data->plist.buffer; LOG_FUNC_RETURN (size); } @@ -664,7 +627,6 @@ int emm_main_get_plmn_list(const char **plist) ** ** ** Inputs: format: The requested format of the string repre- ** ** sentation of the PLMN identifier ** - ** Others: _emm_data ** ** ** ** Outputs: plmn: The selected PLMN identifier coded in the ** ** requested format ** @@ -673,7 +635,7 @@ int emm_main_get_plmn_list(const char **plist) ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) +const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -684,7 +646,7 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) int index = IdleMode_get_splmn_index(); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&_emm_data.splmn, index, + const char *name = _emm_main_get_plmn(&emm_data->splmn, index, format, &size); if (size > 0) { @@ -703,7 +665,6 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) ** ** ** Inputs: format: The requested format of the string repre- ** ** sentation of the PLMN identifier ** - ** Others: _emm_data ** ** ** ** Outputs: plmn: The registered PLMN identifier coded in ** ** the requested format ** @@ -712,7 +673,7 @@ const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format) ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format) +const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -724,7 +685,7 @@ const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format) int index = IdleMode_get_rplmn_index(); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&_emm_data.nvdata.rplmn, + const char *name = _emm_main_get_plmn(&emm_data->nvdata.rplmn, index, format, &size); if (size > 0) { @@ -744,17 +705,16 @@ const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format) ** registration of the UE ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The current network registration status ** ** Others: None ** ** ** ***************************************************************************/ -Stat_t emm_main_get_plmn_status(void) +Stat_t emm_main_get_plmn_status(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.stat); + LOG_FUNC_RETURN (emm_data->stat); } /**************************************************************************** @@ -765,17 +725,16 @@ Stat_t emm_main_get_plmn_status(void) ** belongs to ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The Location/Tracking area code ** ** Others: None ** ** ** ***************************************************************************/ -tac_t emm_main_get_plmn_tac(void) +tac_t emm_main_get_plmn_tac(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.tac); + LOG_FUNC_RETURN (emm_data->tac); } /**************************************************************************** @@ -785,17 +744,16 @@ tac_t emm_main_get_plmn_tac(void) ** Description: Get the identifier of the serving cell ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The serving cell identifier ** ** Others: None ** ** ** ***************************************************************************/ -ci_t emm_main_get_plmn_ci(void) +ci_t emm_main_get_plmn_ci(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.ci); + LOG_FUNC_RETURN (emm_data->ci); } /**************************************************************************** @@ -806,7 +764,6 @@ ci_t emm_main_get_plmn_ci(void) ** ving cell ** ** ** ** Inputs: None ** - ** Others: _emm_data ** ** ** ** Outputs: None ** ** Return: The value of the Radio Access Technology ** @@ -814,10 +771,10 @@ ci_t emm_main_get_plmn_ci(void) ** Others: None ** ** ** ***************************************************************************/ -AcT_t emm_main_get_plmn_rat(void) +AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.rat); + LOG_FUNC_RETURN (emm_data->rat); } /**************************************************************************** @@ -828,7 +785,7 @@ AcT_t emm_main_get_plmn_rat(void) ** network for EPS services or emergency service only ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: TRUE if the UE is currently attached to ** @@ -836,10 +793,10 @@ AcT_t emm_main_get_plmn_rat(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_attached(void) +int emm_main_is_attached(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.is_attached); + LOG_FUNC_RETURN (emm_data->is_attached); } /**************************************************************************** @@ -850,7 +807,7 @@ int emm_main_is_attached(void) ** network for emergency bearer services ** ** ** ** Inputs: None ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: TRUE if the UE is currently attached or is ** @@ -859,10 +816,10 @@ int emm_main_is_attached(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_emergency(void) +int emm_main_is_emergency(emm_data_t *emm_data) { LOG_FUNC_IN; - LOG_FUNC_RETURN (_emm_data.is_attached && _emm_data.is_emergency); + LOG_FUNC_RETURN (emm_data->is_attached && emm_data->is_emergency); } /****************************************************************************/ @@ -881,21 +838,21 @@ int emm_main_is_emergency(void) ** present in the network. The list has to be ** ** displayed to the user application when ** ** size > 0. ** - ** Others: _emm_data ** + ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_callback(int size) +static int _emm_main_callback(emm_data_t *emm_data, int size) { LOG_FUNC_IN; /* Forward the notification to the user API */ - int rc = (*_emm_main_user_callback)(_emm_data.stat, _emm_data.tac, - _emm_data.ci, _emm_data.rat, - _emm_data.plist.buffer, size); + int rc = (*_emm_main_user_callback)(emm_data->stat, emm_data->tac, + emm_data->ci, emm_data->rat, + emm_data->plist.buffer, size); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index 403a87507d..dfb8049f07 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -70,32 +70,32 @@ typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei); -void emm_main_cleanup(void); +void emm_main_cleanup(emm_data_t *emm_data); /* User's getter of UE's identity */ -const imsi_t *emm_main_get_imsi(void); +const imsi_t *emm_main_get_imsi(emm_data_t *emm_data); /* User's getter of the subscriber dialing number */ const msisdn_t *emm_main_get_msisdn(void); /* User's getter/setter for network selection */ -int emm_main_set_plmn_selection_mode(int mode, int format, +int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, const network_plmn_t *plmn, int rat); -int emm_main_get_plmn_selection_mode(void); -int emm_main_get_plmn_list(const char **plist); -const char *emm_main_get_selected_plmn(network_plmn_t *plmn, int format); +int emm_main_get_plmn_selection_mode(emm_data_t *emm_data); +int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist); +const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network registration */ -Stat_t emm_main_get_plmn_status(void); -tac_t emm_main_get_plmn_tac(void); -ci_t emm_main_get_plmn_ci(void); -AcT_t emm_main_get_plmn_rat(void); -const char *emm_main_get_registered_plmn(network_plmn_t *plmn, int format); +Stat_t emm_main_get_plmn_status(emm_data_t *emm_data); +tac_t emm_main_get_plmn_tac(emm_data_t *emm_data); +ci_t emm_main_get_plmn_ci(emm_data_t *emm_data); +AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data); +const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network attachment */ -int emm_main_is_attached(void); -int emm_main_is_emergency(void); +int emm_main_is_attached(emm_data_t *emm_data); +int emm_main_is_emergency(emm_data_t *emm_data); #endif /* __EMM_MAIN_H__*/ diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 8bfe447e50..0aaf76dfa0 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -133,7 +133,7 @@ int emm_proc_attach_failure(int is_initial, void *args); int emm_proc_attach_release(void *args); int emm_proc_attach_restart(nas_user_t *user); -int emm_proc_attach_set_emergency(void); +int emm_proc_attach_set_emergency(emm_data_t *emm_data); // FIXME check prototype int emm_proc_attach_set_detach(void *user); @@ -183,8 +183,8 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, in * Network indication handlers *--------------------------------------------------------------------------- */ -int emm_proc_registration_notify(Stat_t status); -int emm_proc_location_notify(tac_t tac, ci_t ci, AcT_t rat); -int emm_proc_network_notify(int index); +int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status); +int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat); +int emm_proc_network_notify(emm_data_t *emm_data, int index); #endif /* __EMM_PROC_H__*/ diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 68304f0879..ee7b4f52c0 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -134,7 +134,7 @@ void nas_proc_cleanup(nas_user_t *user) /* Perform the EPS Mobility Manager's clean up procedure */ - emm_main_cleanup(); + emm_main_cleanup(user->emm_data); /* Perform the EPS Session Manager's clean up procedure */ esm_main_cleanup(user->esm_data); @@ -251,11 +251,11 @@ int nas_proc_get_eps(nas_user_t *user, int *stat) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_imsi(char *imsi_str) +int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str) { LOG_FUNC_IN; - const imsi_t *imsi = emm_main_get_imsi(); + const imsi_t *imsi = emm_main_get_imsi(emm_data); if (imsi != NULL) { int offset = 0; @@ -386,7 +386,7 @@ int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn /* * Set the PLMN selection mode of operation */ - int index = emm_main_set_plmn_selection_mode(mode, format, oper, AcT); + int index = emm_main_set_plmn_selection_mode(user->emm_data, mode, format, oper, AcT); if ( !(index < 0) ) { /* @@ -452,16 +452,16 @@ int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format LOG_FUNC_IN; /* Get the PLMN selection mode of operation */ - *mode = emm_main_get_plmn_selection_mode(); + *mode = emm_main_get_plmn_selection_mode(user->emm_data); /* Get the currently selected operator */ - const char *oper_name = emm_main_get_selected_plmn(oper, format); + const char *oper_name = emm_main_get_selected_plmn(user->emm_data, oper, format); if (oper_name != NULL) { /* An operator is currently selected */ *selected = TRUE; /* Get the supported Radio Access Technology */ - *AcT = emm_main_get_plmn_rat(); + *AcT = emm_main_get_plmn_rat(user->emm_data); } else { /* No any operator is selected */ *selected = FALSE; @@ -489,7 +489,7 @@ int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list) { LOG_FUNC_IN; - int size = emm_main_get_plmn_list(oper_list); + int size = emm_main_get_plmn_list(user->emm_data, oper_list); LOG_FUNC_RETURN (size); } @@ -514,7 +514,7 @@ int nas_proc_get_reg_status(nas_user_t *user, int *stat) { LOG_FUNC_IN; - *stat = emm_main_get_plmn_status(); + *stat = emm_main_get_plmn_status(user->emm_data); LOG_FUNC_RETURN (RETURNok); } @@ -542,9 +542,9 @@ int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT) { LOG_FUNC_IN; - sprintf(tac, "%.4x", emm_main_get_plmn_tac()); // two byte - sprintf(ci, "%.8x", emm_main_get_plmn_ci()); // four byte - *AcT = emm_main_get_plmn_rat(); // E-UTRAN + sprintf(tac, "%.4x", emm_main_get_plmn_tac(user->emm_data)); // two byte + sprintf(ci, "%.8x", emm_main_get_plmn_ci(user->emm_data)); // four byte + *AcT = emm_main_get_plmn_rat(user->emm_data); // E-UTRAN LOG_FUNC_RETURN (RETURNok); } @@ -570,7 +570,7 @@ int nas_proc_detach(nas_user_t *user, int switch_off) emm_sap_t emm_sap; int rc = RETURNok; - if ( emm_main_is_attached() ) { + if ( emm_main_is_attached(user->emm_data) ) { /* Initiate an Detach procedure */ emm_sap.primitive = EMMREG_DETACH_INIT; emm_sap.u.emm_reg.u.detach.switch_off = switch_off; @@ -601,7 +601,7 @@ int nas_proc_attach(nas_user_t *user) emm_sap_t emm_sap; int rc = RETURNok; - if ( !emm_main_is_attached() ) { + if ( !emm_main_is_attached(user->emm_data) ) { /* Initiate an Attach procedure */ emm_sap.primitive = EMMREG_ATTACH_INIT; emm_sap.u.emm_reg.u.attach.is_emergency = FALSE; @@ -630,7 +630,7 @@ int nas_proc_get_attach_status(nas_user_t *user) { LOG_FUNC_IN; - int is_attached = emm_main_is_attached(); + int is_attached = emm_main_is_attached(user->emm_data); LOG_FUNC_RETURN (is_attached); } @@ -950,14 +950,14 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid) int rc = RETURNok; - if ( !emm_main_is_attached() ) { + if ( !emm_main_is_attached(user->emm_data) ) { /* * If the UE is not attached to the network, perform EPS attach * procedure prior to attempt to request any PDN connectivity */ LOG_TRACE(WARNING, "NAS-PROC - UE is not attached to the network"); rc = nas_proc_attach(user); - } else if (emm_main_is_emergency()) { + } else if (emm_main_is_emergency(user->emm_data)) { /* The UE is attached for emergency bearer services; It shall not * request a PDN connection to any other PDN */ LOG_TRACE(WARNING,"NAS-PROC - Attached for emergency bearer services"); diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index ec1ca3f3c7..672488aee6 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -76,7 +76,7 @@ int nas_proc_enable_s1_mode(nas_user_t *user); int nas_proc_disable_s1_mode(nas_user_t *user); int nas_proc_get_eps(nas_user_t *user, int *stat); -int nas_proc_get_imsi(char *imsi_str); +int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str); int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi); int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp); diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 827003699c..63aae7e8c2 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -652,7 +652,7 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) } /* Get the International Mobile Subscriber Identity (IMSI) */ - ret_code = nas_proc_get_imsi(cimi->IMSI); + ret_code = nas_proc_get_imsi(user->emm_data, cimi->IMSI); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get IMSI number"); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index a963960f4f..05ce952f22 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -49,14 +49,16 @@ Description NAS type definition to manage a user equipment #include "esmData.h" #include "esm_pt_defs.h" #include "EMM/emm_fsm_defs.h" +#include "EMM/emmData.h" typedef struct { int fd; proc_data_t proc; esm_data_t *esm_data; // ESM internal data (used within ESM only) esm_pt_data_t *esm_pt_data; - emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts + emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status + emm_data_t *emm_data; // EPS mobility management data } nas_user_t; #endif From 2d7f557ae9365ac4554afb4dcf7e675527e200d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 16:27:25 +0200 Subject: [PATCH 151/571] UE/EMM: fix buggy condition in IdleMode.c --- openair3/NAS/UE/EMM/IdleMode.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index 8570a58789..c9ebc40b7a 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -902,10 +902,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Or terminate the PLMN selection procedure */ if (!select_next_plmn) { - /* TODO: be sure of this fix */ - LOG_TRACE(WARNING, "%s:%d:%s: be sure!!\n", __FILE__, __LINE__, __FUNCTION__); - //if (!(_emm_plmn_list.fplmn) < 0) { // FIXME this comparison makes no sense (bool < 0) - if (!(_emm_plmn_list.fplmn < 0)) { // FIXME this comparison makes no sense (bool < 0) + if (_emm_plmn_list.fplmn >= 0) { /* There were one or more PLMNs which were available and allowable, * but an LR failure made registration on those PLMNs unsuccessful * or an entry in any of the forbidden area lists prevented a From 7340b5e0713a6f3ea9bc83b64ebf76ea57aee96e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 12 Jul 2016 17:45:16 +0200 Subject: [PATCH 152/571] UE/EMM: move _plmn_list to nas_user_t --- openair3/NAS/UE/EMM/IdleMode.c | 313 ++++++++++++---------------- openair3/NAS/UE/EMM/IdleMode.h | 22 +- openair3/NAS/UE/EMM/IdleMode_defs.h | 52 +++++ openair3/NAS/UE/EMM/emm_main.c | 44 ++-- openair3/NAS/UE/EMM/emm_main.h | 8 +- openair3/NAS/UE/EMM/emm_proc.h | 2 +- openair3/NAS/UE/nas_proc.c | 6 +- openair3/NAS/UE/user_defs.h | 2 + 8 files changed, 232 insertions(+), 217 deletions(-) create mode 100644 openair3/NAS/UE/EMM/IdleMode_defs.h diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index c9ebc40b7a..efecf7d321 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -78,57 +78,9 @@ Description Defines EMM procedures executed by the Non-Access Stratum /****************************************************************************/ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn); -static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn); +static int _IldlMode_get_opnn_id(emm_data_t *emm_data, const plmn_t *plmn); static int _IdleMode_get_suitable_cell(nas_user_t *user, int index); -/* - * A list of PLMN identities in priority order is maintained locally - * to perform the PLMN selection procedure. - * - * In automatic mode of operation, this list is used for PLMN selection when - * the UE is switched on, or upon recovery from lack of coverage, or when the - * user requests the UE to initiate PLMN reselection, and registration. - * In manual mode of operation, this list is displayed to the user that may - * select an available PLMN and initiate registration. - * - * The list may contain PLMN identifiers in the following order: - * - The last registered PLMN or each equivalent PLMN present in the list of - * "equivalent PLMNs" (EPLMN_MAX), when UE is switched on or following - * recovery from lack of coverage; - * - The highest priority PLMN in the list of "equivalent HPLMNs" or the - * HPLMN derived from the IMSI (1) - * - Each PLMN/access technology combination in the "User Controlled PLMN - * Selector with Access Technology" (PLMN_MAX) - * - Each PLMN/access technology combination in the "Operator Controlled PLMN - * Selector with Access Technology" (OPLMN_MAX) - * - Other PLMN/access technology combinations with received high quality - * signal in random order (TODO) - * - Other PLMN/access technology combinations in order of decreasing signal - * quality (TODO) - * - The last selected PLMN again (1) - */ -static struct { - int n_plmns; -#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ - EMM_DATA_OPLMN_MAX + 2) - plmn_t *plmn[EMM_PLMN_LIST_SIZE]; - int index; /* Index of the PLMN for which selection is ongoing */ - int hplmn; /* Index of the home PLMN or the highest priority - * equivalent home PLMN */ - int fplmn; /* Index of the first forbidden PLMN */ - int splmn; /* Index of the currently selected PLMN */ - int rplmn; /* Index of the currently registered PLMN */ - struct plmn_param_t { - char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ - char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ - char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ - int stat; /* Indication of the PLMN availability */ - int tac; /* Location/Tracking Area Code */ - int ci; /* Serving cell identifier */ - int rat; /* Radio Access Technology supported by the serving cell */ - } param[EMM_PLMN_LIST_SIZE]; -} _emm_plmn_list; - /* Callback executed whenever a network indication is received */ static IdleMode_callback_t _emm_indication_notify; @@ -154,13 +106,19 @@ static IdleMode_callback_t _emm_indication_notify; ***************************************************************************/ void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) { + emm_plmn_list_t *emm_plmn_list = calloc(1, sizeof(emm_plmn_list_t)); + if ( emm_plmn_list == NULL ) { + LOG_TRACE(ERROR, "EMM - Can't alloc emm_plmn_list"); + // FIXME stop here + } + user->emm_plmn_list = emm_plmn_list; /* Initialize the list of available PLMNs */ - _emm_plmn_list.n_plmns = 0; - _emm_plmn_list.index = 0; - _emm_plmn_list.hplmn = -1; - _emm_plmn_list.fplmn = -1; - _emm_plmn_list.splmn = -1; - _emm_plmn_list.rplmn = -1; + emm_plmn_list->n_plmns = 0; + emm_plmn_list->index = 0; + emm_plmn_list->hplmn = -1; + emm_plmn_list->fplmn = -1; + emm_plmn_list->splmn = -1; + emm_plmn_list->rplmn = -1; /* Initialize the network notification handler */ _emm_indication_notify = *cb; @@ -190,9 +148,9 @@ void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_nb_plmns(void) +int IdleMode_get_nb_plmns(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.n_plmns; + return emm_plmn_list->n_plmns; } /**************************************************************************** @@ -211,9 +169,9 @@ int IdleMode_get_nb_plmns(void) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_hplmn_index(void) +int IdleMode_get_hplmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.hplmn; + return emm_plmn_list->hplmn; } /**************************************************************************** @@ -232,9 +190,9 @@ int IdleMode_get_hplmn_index(void) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_rplmn_index(void) +int IdleMode_get_rplmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.rplmn; + return emm_plmn_list->rplmn; } /**************************************************************************** @@ -245,16 +203,15 @@ int IdleMode_get_rplmn_index(void) ** available PLMNs. ** ** ** ** Inputs: None ** - ** Others: _emm_plmn_list ** ** ** ** Outputs: None ** ** Return: The index of the selected PLMN in the list ** ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_splmn_index(void) +int IdleMode_get_splmn_index(emm_plmn_list_t *emm_plmn_list) { - return _emm_plmn_list.splmn; + return emm_plmn_list->splmn; } /**************************************************************************** @@ -265,19 +222,18 @@ int IdleMode_get_splmn_index(void) ** tors present in the network ** ** ** ** Inputs: i: Index of the first operator to update ** - ** Others: _emm_plmn_list ** ** ** ** Outputs: None ** ** Return: The size of the list in bytes ** ** ** ***************************************************************************/ -int IdleMode_update_plmn_list(emm_data_t *emm_data, int i) +int IdleMode_update_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int i) { int offset = 0; int n = 1; - while ( (i < _emm_plmn_list.n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) { - struct plmn_param_t *plmn = &(_emm_plmn_list.param[i++]); + while ( (i < emm_plmn_list->n_plmns) && (offset < EMM_DATA_BUFFER_SIZE) ) { + struct plmn_param_t *plmn = &(emm_plmn_list->param[i++]); if (n++ > 1) { offset += snprintf(emm_data->plist.buffer + offset, @@ -319,13 +275,13 @@ int IdleMode_update_plmn_list(emm_data_t *emm_data, int i) ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_fullname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].fullname); - return _emm_plmn_list.param[index].fullname; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].fullname); + return emm_plmn_list->param[index].fullname; } return NULL; @@ -348,13 +304,13 @@ const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_shortname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].shortname); - return _emm_plmn_list.param[index].shortname; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].shortname); + return emm_plmn_list->param[index].shortname; } return NULL; @@ -378,12 +334,12 @@ const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len) +const char *IdleMode_get_plmn_id(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len) { - if (index < _emm_plmn_list.n_plmns) { - assert( PLMNS_ARE_EQUAL(*plmn, *_emm_plmn_list.plmn[index]) ); - *len = strlen(_emm_plmn_list.param[index].num); - return _emm_plmn_list.param[index].num; + if (index < emm_plmn_list->n_plmns) { + assert( PLMNS_ARE_EQUAL(*plmn, *emm_plmn_list->plmn[index]) ); + *len = strlen(emm_plmn_list->param[index].num); + return emm_plmn_list->param[index].num; } return NULL; @@ -405,13 +361,13 @@ const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_fullname_index(const char *plmn) +int IdleMode_get_plmn_fullname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified full name */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( strncmp(plmn, _emm_plmn_list.param[index].fullname, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( strncmp(plmn, emm_plmn_list->param[index].fullname, NET_FORMAT_LONG_SIZE) != 0 ) { continue; } @@ -438,13 +394,13 @@ int IdleMode_get_plmn_fullname_index(const char *plmn) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_shortname_index(const char *plmn) +int IdleMode_get_plmn_shortname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified short name */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( !strncmp(plmn, _emm_plmn_list.param[index].shortname, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( !strncmp(plmn, emm_plmn_list->param[index].shortname, NET_FORMAT_SHORT_SIZE) ) { continue; } @@ -471,13 +427,13 @@ int IdleMode_get_plmn_shortname_index(const char *plmn) ** Others: None ** ** ** ***************************************************************************/ -int IdleMode_get_plmn_id_index(const char *plmn) +int IdleMode_get_plmn_id_index(emm_plmn_list_t *emm_plmn_list, const char *plmn) { int index; /* Get the index of the PLMN identifier with specified numeric identifier */ - for (index = 0; index < _emm_plmn_list.n_plmns; index++) { - if ( !strncmp(plmn, _emm_plmn_list.param[index].num, + for (index = 0; index < emm_plmn_list->n_plmns; index++) { + if ( !strncmp(plmn, emm_plmn_list->param[index].num, NET_FORMAT_LONG_SIZE) ) { continue; } @@ -516,6 +472,7 @@ int emm_proc_initialize(nas_user_t *user) emm_sap_t emm_sap; int rc; int i; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; if (!user->emm_data->usim_is_valid) { /* The USIM application is not present or not valid */ @@ -526,11 +483,11 @@ int emm_proc_initialize(nas_user_t *user) * if available, or the last registered PLMN */ if (user->emm_data->nvdata.eplmn.n_plmns > 0) { for (i=0; i < user->emm_data->nvdata.eplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->nvdata.eplmn.plmn[i]; } } else if ( PLMN_IS_VALID(user->emm_data->nvdata.rplmn) ) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->nvdata.rplmn; } @@ -538,29 +495,29 @@ int emm_proc_initialize(nas_user_t *user) * When switched on, the UE will try to automatically register * to each previous PLMN within the ordered list of available * PLMNs regardless of the network selection mode of operation */ - _emm_plmn_list.hplmn = _emm_plmn_list.n_plmns - 1; - // LG_emm_plmn_list.hplmn = _emm_plmn_list.n_plmns; + emm_plmn_list->hplmn = emm_plmn_list->n_plmns - 1; + // LGemm_plmn_list->hplmn = emm_plmn_list->n_plmns; /* Add the highest priority PLMN in the list of "equivalent HPLMNs" if present and not empty, or the HPLMN derived from the IMSI */ if (user->emm_data->ehplmn.n_plmns > 0) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->ehplmn.plmn[0]; } else { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = &user->emm_data->hplmn; + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->hplmn; } /* Each PLMN/access technology combination in the "User * Controlled PLMN Selector with Access Technology" */ for (i=0; i < user->emm_data->plmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->plmn.plmn[i]; } /* Each PLMN/access technology combination in the "Operator * Controlled PLMN Selector with Access Technology" */ for (i=0; i < user->emm_data->oplmn.n_plmns; i++) { - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns++] = + emm_plmn_list->plmn[emm_plmn_list->n_plmns++] = &user->emm_data->oplmn.plmn[i]; } @@ -573,9 +530,9 @@ int emm_proc_initialize(nas_user_t *user) /* TODO: Schedule periodic network selection attemps (hpplmn timer) */ /* Initialize the PLMNs' parameters */ - for (i=0; i < _emm_plmn_list.n_plmns; i++) { - struct plmn_param_t *plmn = &(_emm_plmn_list.param[i]); - int id = _IldlMode_get_opnn_id(user, _emm_plmn_list.plmn[i]); + for (i=0; i < emm_plmn_list->n_plmns; i++) { + struct plmn_param_t *plmn = &(emm_plmn_list->param[i]); + int id = _IldlMode_get_opnn_id(user->emm_data, emm_plmn_list->plmn[i]); if (id < 0) { plmn->fullname[0] = '\0'; @@ -587,7 +544,7 @@ int emm_proc_initialize(nas_user_t *user) NET_FORMAT_SHORT_SIZE); } - (void)_IdleMode_plmn_str(plmn->num, _emm_plmn_list.plmn[i]); + (void)_IdleMode_plmn_str(plmn->num, emm_plmn_list->plmn[i]); plmn->stat = NET_OPER_UNKNOWN; plmn->tac = 0; plmn->ci = 0; @@ -595,7 +552,7 @@ int emm_proc_initialize(nas_user_t *user) } LOG_TRACE(INFO, "EMM-IDLE - %d PLMNs available for network selection", - _emm_plmn_list.n_plmns); + emm_plmn_list->n_plmns); /* Notify EMM that PLMN selection procedure has to be executed */ emm_sap.primitive = EMMREG_REGISTER_REQ; @@ -630,31 +587,33 @@ int emm_proc_initialize(nas_user_t *user) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_plmn_list.index ** + ** Others: emm_plmn_list->index ** ** ** ***************************************************************************/ int emm_proc_plmn_selection(nas_user_t *user, int index) { LOG_FUNC_IN; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; int rc = RETURNok; - if (user->emm_data->plmn_mode != EMM_DATA_PLMN_AUTO) { + if (emm_data->plmn_mode != EMM_DATA_PLMN_AUTO) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- */ - if (index >= _emm_plmn_list.hplmn) { + if (index >= emm_plmn_list->hplmn) { /* * Selection of the last registered or equivalent PLMNs failed */ - if (user->emm_data->plmn_index < 0) { + if (emm_data->plmn_index < 0) { /* * The user did not select any PLMN yet; display the ordered * list of available PLMNs to the user */ index = -1; - rc = emm_proc_network_notify(user->emm_data, _emm_plmn_list.hplmn); + rc = emm_proc_network_notify(emm_plmn_list, emm_data, emm_plmn_list->hplmn); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify " @@ -664,7 +623,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) /* * Try to register to the PLMN manually selected by the user */ - index = user->emm_data->plmn_index; + index = emm_data->plmn_index; } } } @@ -677,7 +636,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) * or any other PLMN in the ordered list of available PLMNs in * automatic mode. */ - _emm_plmn_list.index = index; + emm_plmn_list->index = index; rc = _IdleMode_get_suitable_cell(user, index); } @@ -713,11 +672,9 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) ** ci: The identifier of the cell ** ** rat: The radio access technology supported by ** ** the cell ** - ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_plmn_list, user->emm_data-> ** ** ** ***************************************************************************/ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, AcT_t rat) @@ -726,34 +683,36 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, emm_sap_t emm_sap; int rc = RETURNerror; - int index = _emm_plmn_list.index; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; + int index = emm_plmn_list->index; int select_next_plmn = FALSE; LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode", (found)? "One" : "No", index, - (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); if (found) { int is_forbidden = FALSE; /* Select the PLMN of which a suitable cell has been found */ - user->emm_data->splmn = *_emm_plmn_list.plmn[index]; + emm_data->splmn = *emm_plmn_list->plmn[index]; /* Update the selected PLMN's parameters */ - _emm_plmn_list.param[index].tac = tac; - _emm_plmn_list.param[index].ci = ci; - _emm_plmn_list.param[index].rat = rat; + emm_plmn_list->param[index].tac = tac; + emm_plmn_list->param[index].ci = ci; + emm_plmn_list->param[index].rat = rat; /* Update the location data and notify EMM that data have changed */ - rc = emm_proc_location_notify(user->emm_data, tac, ci , rat); + rc = emm_proc_location_notify(emm_data, tac, ci , rat); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update"); } - if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { + if (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -761,17 +720,17 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, int i; /* Check if the selected PLMN is in the forbidden list */ - for (i = 0; i < user->emm_data->fplmn.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(user->emm_data->splmn, user->emm_data->fplmn.plmn[i])) { + for (i = 0; i < emm_data->fplmn.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn.plmn[i])) { is_forbidden = TRUE; break; } } if (!is_forbidden) { - for (i = 0; i < user->emm_data->fplmn_gprs.n_plmns; i++) { - if (PLMNS_ARE_EQUAL(user->emm_data->splmn, - user->emm_data->fplmn_gprs.plmn[i])) { + for (i = 0; i < emm_data->fplmn_gprs.n_plmns; i++) { + if (PLMNS_ARE_EQUAL(emm_data->splmn, + emm_data->fplmn_gprs.plmn[i])) { is_forbidden = TRUE; break; } @@ -781,12 +740,12 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, /* Check if the selected PLMN belongs to a forbidden * tracking area */ tai_t tai; - tai.plmn = user->emm_data->splmn; + tai.plmn = emm_data->splmn; tai.tac = tac; if (!is_forbidden) { - for (i = 0; i < user->emm_data->ftai.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai.tai[i])) { + for (i = 0; i < emm_data->ftai.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, emm_data->ftai.tai[i])) { is_forbidden = TRUE; break; } @@ -794,8 +753,8 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, } if (!is_forbidden) { - for (i = 0; i < user->emm_data->ftai_roaming.n_tais; i++) { - if (TAIS_ARE_EQUAL(tai, user->emm_data->ftai_roaming.tai[i])) { + for (i = 0; i < emm_data->ftai_roaming.n_tais; i++) { + if (TAIS_ARE_EQUAL(tai, emm_data->ftai_roaming.tai[i])) { is_forbidden = TRUE; break; } @@ -809,25 +768,25 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this acceptable cell for limited services"); /* Save the index of the first forbidden PLMN */ - if (_emm_plmn_list.fplmn < 0) { - _emm_plmn_list.fplmn = index; + if (emm_plmn_list->fplmn < 0) { + emm_plmn_list->fplmn = index; } - _emm_plmn_list.param[index].stat = NET_OPER_FORBIDDEN; + emm_plmn_list->param[index].stat = NET_OPER_FORBIDDEN; } else { /* A suitable cell has been found and the PLMN or tracking area * is not in the forbidden list */ LOG_TRACE(INFO, "EMM-IDLE - UE may camp on this suitable cell for normal services"); - _emm_plmn_list.fplmn = -1; - _emm_plmn_list.param[index].stat = NET_OPER_CURRENT; + emm_plmn_list->fplmn = -1; + emm_plmn_list->param[index].stat = NET_OPER_CURRENT; emm_sap.primitive = EMMREG_REGISTER_CNF; } /* Duplicate the new selected PLMN at the end of the ordered list */ - _emm_plmn_list.plmn[_emm_plmn_list.n_plmns] = &user->emm_data->splmn; + emm_plmn_list->plmn[emm_plmn_list->n_plmns] = &emm_data->splmn; } - else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { + else if (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO) { /* * Automatic mode of operation * --------------------------- @@ -838,12 +797,12 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, select_next_plmn = TRUE; /* Bypass the previously selected PLMN */ - if (index == _emm_plmn_list.splmn) { + if (index == emm_plmn_list->splmn) { index += 1; } } - else if (user->emm_data->plmn_index < 0) { + else if (emm_data->plmn_index < 0) { /* * Manual or manual/automatic mode of operation * -------------------------------------------- @@ -854,7 +813,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, select_next_plmn = TRUE; } - else if (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { + else if (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { /* * Manual mode of operation * ------------------------ @@ -870,8 +829,8 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Attempt to find a suitable cell of the PLMN selected by the user * failed; Try to automatically select another PLMN */ - user->emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; - index = _emm_plmn_list.hplmn; + emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; + index = emm_plmn_list->hplmn; select_next_plmn = TRUE; } @@ -879,16 +838,16 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Force an attempt to register to the next PLMN */ if (select_next_plmn) { - int last_plmn_index = _emm_plmn_list.n_plmns; + int last_plmn_index = emm_plmn_list->n_plmns; - if (_emm_plmn_list.splmn != -1) { + if (emm_plmn_list->splmn != -1) { /* The last attempt was to register the previously selected PLMN */ last_plmn_index += 1; } if (index < last_plmn_index) { /* Try to select the next PLMN in the list of available PLMNs */ - _emm_plmn_list.index = index; + emm_plmn_list->index = index; rc = emm_proc_plmn_selection(user, index); } else { /* No suitable cell of any PLMN within the ordered list @@ -902,27 +861,27 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Or terminate the PLMN selection procedure */ if (!select_next_plmn) { - if (_emm_plmn_list.fplmn >= 0) { + if (emm_plmn_list->fplmn >= 0) { /* There were one or more PLMNs which were available and allowable, * but an LR failure made registration on those PLMNs unsuccessful * or an entry in any of the forbidden area lists prevented a * registration attempt; select the first such PLMN and enters a * limited service state. */ - index = _emm_plmn_list.fplmn; - _emm_plmn_list.fplmn = -1; + index = emm_plmn_list->fplmn; + emm_plmn_list->fplmn = -1; emm_sap.primitive = EMMREG_REGISTER_REJ; } /* Update the availability indicator of the previously selected PLMN */ - if (_emm_plmn_list.splmn != -1) { - _emm_plmn_list.param[_emm_plmn_list.splmn].stat = NET_OPER_UNKNOWN; + if (emm_plmn_list->splmn != -1) { + emm_plmn_list->param[emm_plmn_list->splmn].stat = NET_OPER_UNKNOWN; } /* Update the index of the new selected PLMN */ if (emm_sap.primitive != EMMREG_NO_CELL) { - _emm_plmn_list.splmn = index; + emm_plmn_list->splmn = index; } else { - _emm_plmn_list.splmn = -1; + emm_plmn_list->splmn = -1; } /* @@ -930,15 +889,15 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, */ rc = emm_sap_send(user, &emm_sap); - if (_emm_plmn_list.splmn != -1) { - if (_emm_plmn_list.splmn == _emm_plmn_list.rplmn) { + if (emm_plmn_list->splmn != -1) { + if (emm_plmn_list->splmn == emm_plmn_list->rplmn) { /* The selected PLMN is the registered PLMN */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is the registered PLMN"); - user->emm_data->is_rplmn = TRUE; - } else if (_emm_plmn_list.splmn < _emm_plmn_list.hplmn) { + emm_data->is_rplmn = TRUE; + } else if (emm_plmn_list->splmn < emm_plmn_list->hplmn) { /* The selected PLMN is in the list of equivalent PLMNs */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is in the list of equivalent PLMNs"); - user->emm_data->is_eplmn = TRUE; + emm_data->is_eplmn = TRUE; } /* @@ -1046,12 +1005,12 @@ int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_network_notify(emm_data_t *emm_data, int index) +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int index) { LOG_FUNC_IN; /* Update the list of operators present in the network */ - int size = IdleMode_update_plmn_list(emm_data, index); + int size = IdleMode_update_plmn_list(emm_plmn_list, emm_data, index); /* Notify EMM that data has changed */ int rc = (*_emm_indication_notify)(emm_data, size); @@ -1122,7 +1081,6 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** tor network name records ** ** ** ** Inputs: plmn: The PLMN identifier ** - ** Others: user->emm_data-> ** ** ** ** Outputs: None ** ** Return: The index of the PLMN if found in the list ** @@ -1131,32 +1089,32 @@ static int _IdleMode_plmn_str(char *plmn_str, const plmn_t *plmn) ** Others: None ** ** ** ***************************************************************************/ -static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) +static int _IldlMode_get_opnn_id(emm_data_t *emm_data, const plmn_t *plmn) { int i; - for (i = 0; i < user->emm_data->n_opnns; i++) { - if (plmn->MCCdigit1 != user->emm_data->opnn[i].plmn->MCCdigit1) { + for (i = 0; i < emm_data->n_opnns; i++) { + if (plmn->MCCdigit1 != emm_data->opnn[i].plmn->MCCdigit1) { continue; } - if (plmn->MCCdigit2 != user->emm_data->opnn[i].plmn->MCCdigit2) { + if (plmn->MCCdigit2 != emm_data->opnn[i].plmn->MCCdigit2) { continue; } - if (plmn->MCCdigit3 != user->emm_data->opnn[i].plmn->MCCdigit3) { + if (plmn->MCCdigit3 != emm_data->opnn[i].plmn->MCCdigit3) { continue; } - if (plmn->MNCdigit1 != user->emm_data->opnn[i].plmn->MNCdigit1) { + if (plmn->MNCdigit1 != emm_data->opnn[i].plmn->MNCdigit1) { continue; } - if (plmn->MNCdigit2 != user->emm_data->opnn[i].plmn->MNCdigit2) { + if (plmn->MNCdigit2 != emm_data->opnn[i].plmn->MNCdigit2) { continue; } - if (plmn->MNCdigit3 != user->emm_data->opnn[i].plmn->MNCdigit3) { + if (plmn->MNCdigit3 != emm_data->opnn[i].plmn->MNCdigit3) { continue; } @@ -1177,7 +1135,6 @@ static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) ** ** ** Inputs: index: Index of the selected PLMN in the ordered ** ** list of available PLMNs ** - ** Others: _emm_plmn_list.plmn ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -1187,12 +1144,14 @@ static int _IldlMode_get_opnn_id(nas_user_t *user, const plmn_t *plmn) static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) { emm_sap_t emm_sap; - const plmn_t *plmn = _emm_plmn_list.plmn[index]; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; + const plmn_t *plmn = emm_plmn_list->plmn[index]; LOG_TRACE(INFO, "EMM-IDLE - Trying to search a suitable cell " "of PLMN %d in %s mode", index, - (user->emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : - (user->emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : + (emm_data->plmn_mode == EMM_DATA_PLMN_AUTO)? "Automatic" : + (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL)? "Manual" : "Automatic/manual"); /* * Notify EMM-AS SAP that cell information related to the given @@ -1202,8 +1161,8 @@ static int _IdleMode_get_suitable_cell(nas_user_t *user, int index) emm_sap.u.emm_as.u.cell_info.plmnIDs.n_plmns = 1; emm_sap.u.emm_as.u.cell_info.plmnIDs.plmn[0] = *plmn; - if (user->emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) { - emm_sap.u.emm_as.u.cell_info.rat = (1 << user->emm_data->plmn_rat); + if (emm_data->plmn_rat != NET_ACCESS_UNAVAILABLE) { + emm_sap.u.emm_as.u.cell_info.rat = (1 << emm_data->plmn_rat); } else { emm_sap.u.emm_as.u.cell_info.rat = NET_ACCESS_UNAVAILABLE; } diff --git a/openair3/NAS/UE/EMM/IdleMode.h b/openair3/NAS/UE/EMM/IdleMode.h index 17b0eabee5..e92e14f5cb 100644 --- a/openair3/NAS/UE/EMM/IdleMode.h +++ b/openair3/NAS/UE/EMM/IdleMode.h @@ -63,21 +63,21 @@ typedef int (*IdleMode_callback_t) (emm_data_t *emm_data, int); void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb); -int IdleMode_get_nb_plmns(void); -int IdleMode_get_hplmn_index(void); -int IdleMode_get_rplmn_index(void); -int IdleMode_get_splmn_index(void); +int IdleMode_get_nb_plmns(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_hplmn_index(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_rplmn_index(emm_plmn_list_t *emm_plmn_list); +int IdleMode_get_splmn_index(emm_plmn_list_t *emm_plmn_list); -int IdleMode_update_plmn_list(emm_data_t *emm_data, int i); +int IdleMode_update_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int i); -const char *IdleMode_get_plmn_fullname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_fullname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -const char *IdleMode_get_plmn_shortname(const plmn_t *plmn, int index, +const char *IdleMode_get_plmn_shortname(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -const char *IdleMode_get_plmn_id(const plmn_t *plmn, int index, size_t *len); +const char *IdleMode_get_plmn_id(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, size_t *len); -int IdleMode_get_plmn_fullname_index(const char *plmn); -int IdleMode_get_plmn_shortname_index(const char *plmn); -int IdleMode_get_plmn_id_index(const char *plmn); +int IdleMode_get_plmn_fullname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); +int IdleMode_get_plmn_shortname_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); +int IdleMode_get_plmn_id_index(emm_plmn_list_t *emm_plmn_list, const char *plmn); #endif /* __IDLEMODE_H__*/ diff --git a/openair3/NAS/UE/EMM/IdleMode_defs.h b/openair3/NAS/UE/EMM/IdleMode_defs.h new file mode 100644 index 0000000000..8ef6c8e86d --- /dev/null +++ b/openair3/NAS/UE/EMM/IdleMode_defs.h @@ -0,0 +1,52 @@ +#ifndef _IDLEMODE_DEFS_H +#define _IDLEMODE_DEFS_H + +/* + * A list of PLMN identities in priority order is maintained locally + * to perform the PLMN selection procedure. + * + * In automatic mode of operation, this list is used for PLMN selection when + * the UE is switched on, or upon recovery from lack of coverage, or when the + * user requests the UE to initiate PLMN reselection, and registration. + * In manual mode of operation, this list is displayed to the user that may + * select an available PLMN and initiate registration. + * + * The list may contain PLMN identifiers in the following order: + * - The last registered PLMN or each equivalent PLMN present in the list of + * "equivalent PLMNs" (EPLMN_MAX), when UE is switched on or following + * recovery from lack of coverage; + * - The highest priority PLMN in the list of "equivalent HPLMNs" or the + * HPLMN derived from the IMSI (1) + * - Each PLMN/access technology combination in the "User Controlled PLMN + * Selector with Access Technology" (PLMN_MAX) + * - Each PLMN/access technology combination in the "Operator Controlled PLMN + * Selector with Access Technology" (OPLMN_MAX) + * - Other PLMN/access technology combinations with received high quality + * signal in random order (TODO) + * - Other PLMN/access technology combinations in order of decreasing signal + * quality (TODO) + * - The last selected PLMN again (1) + */ +typedef struct { + int n_plmns; +#define EMM_PLMN_LIST_SIZE (EMM_DATA_EPLMN_MAX + EMM_DATA_PLMN_MAX + \ + EMM_DATA_OPLMN_MAX + 2) + plmn_t *plmn[EMM_PLMN_LIST_SIZE]; + int index; /* Index of the PLMN for which selection is ongoing */ + int hplmn; /* Index of the home PLMN or the highest priority + * equivalent home PLMN */ + int fplmn; /* Index of the first forbidden PLMN */ + int splmn; /* Index of the currently selected PLMN */ + int rplmn; /* Index of the currently registered PLMN */ + struct plmn_param_t { + char fullname[NET_FORMAT_LONG_SIZE+1]; /* PLMN full identifier */ + char shortname[NET_FORMAT_SHORT_SIZE+1]; /* PLMN short identifier */ + char num[NET_FORMAT_NUM_SIZE+1]; /* PLMN numeric identifier */ + int stat; /* Indication of the PLMN availability */ + int tac; /* Location/Tracking Area Code */ + int ci; /* Serving cell identifier */ + int rat; /* Radio Access Technology supported by the serving cell */ + } param[EMM_PLMN_LIST_SIZE]; +} emm_plmn_list_t; + +#endif diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 591c9e6b0f..a1d4260923 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -63,10 +63,10 @@ static int _emm_main_get_imei(imei_t *imei, const char *imei_str); static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2); -static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, +static const char *_emm_main_get_plmn(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, int format, size_t *size); -static int _emm_main_get_plmn_index(const char *plmn, int format); +static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char *plmn, int format); /* * USIM application data @@ -538,12 +538,14 @@ const msisdn_t *emm_main_get_msisdn(void) ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, +int emm_main_set_plmn_selection_mode(nas_user_t *user, int mode, int format, const network_plmn_t *plmn, int rat) { LOG_FUNC_IN; int index; + emm_data_t *emm_data = user->emm_data; + emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; LOG_TRACE(INFO, "EMM-MAIN - PLMN selection: mode=%d, format=%d, plmn=%s, " "rat=%d", mode, format, (const char *)&plmn->id, rat); @@ -552,7 +554,7 @@ int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, if (mode != EMM_DATA_PLMN_AUTO) { /* Get the index of the PLMN in the list of available PLMNs */ - index = _emm_main_get_plmn_index((const char *)&plmn->id, format); + index = _emm_main_get_plmn_index(emm_plmn_list, (const char *)&plmn->id, format); if (index < 0) { LOG_TRACE(WARNING, "EMM-MAIN - PLMN %s not available", @@ -568,7 +570,7 @@ int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, * register to when switched on; the equivalent PLMNs list shall not be * applied to the user reselection in Automatic Network Selection Mode. */ - index = IdleMode_get_hplmn_index(); + index = IdleMode_get_hplmn_index(emm_plmn_list); } LOG_FUNC_RETURN (index); @@ -609,11 +611,11 @@ int emm_main_get_plmn_selection_mode(emm_data_t *emm_data) ** Others: None ** ** ** ***************************************************************************/ -int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist) +int emm_main_get_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, const char **plist) { LOG_FUNC_IN; - int size = IdleMode_update_plmn_list(emm_data, 0); + int size = IdleMode_update_plmn_list(emm_plmn_list, emm_data, 0); *plist = emm_data->plist.buffer; LOG_FUNC_RETURN (size); @@ -635,7 +637,7 @@ int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist) ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format) +const char *emm_main_get_selected_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -643,10 +645,10 @@ const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plm /* * Get the identifier of the selected PLMN in the list of available PLMNs */ - int index = IdleMode_get_splmn_index(); + int index = IdleMode_get_splmn_index(emm_plmn_list); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&emm_data->splmn, index, + const char *name = _emm_main_get_plmn(emm_plmn_list, &emm_data->splmn, index, format, &size); if (size > 0) { @@ -673,7 +675,7 @@ const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plm ** Others: None ** ** ** ***************************************************************************/ -const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format) +const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format) { LOG_FUNC_IN; @@ -682,10 +684,10 @@ const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *p /* * Get the identifier of the registered PLMN in the list of available PLMNs */ - int index = IdleMode_get_rplmn_index(); + int index = IdleMode_get_rplmn_index(emm_plmn_list); if ( !(index < 0) ) { - const char *name = _emm_main_get_plmn(&emm_data->nvdata.rplmn, + const char *name = _emm_main_get_plmn(emm_plmn_list, &emm_data->nvdata.rplmn, index, format, &size); if (size > 0) { @@ -952,24 +954,24 @@ static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2) ** Others: None ** ** ** ***************************************************************************/ -static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, +static const char *_emm_main_get_plmn(emm_plmn_list_t *emm_plmn_list, const plmn_t *plmn, int index, int format, size_t *size) { if ( PLMN_IS_VALID(*plmn) ) { switch (format) { case NET_FORMAT_LONG: /* Get the long alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_fullname(plmn, index, size); + return IdleMode_get_plmn_fullname(emm_plmn_list, plmn, index, size); break; case NET_FORMAT_SHORT: /* Get the short alpha-numeric representation of the PLMN */ - return IdleMode_get_plmn_shortname(plmn, index, size); + return IdleMode_get_plmn_shortname(emm_plmn_list, plmn, index, size); break; case NET_FORMAT_NUM: /* Get the numeric representation of the PLMN */ - return IdleMode_get_plmn_id(plmn, index, size); + return IdleMode_get_plmn_id(emm_plmn_list, plmn, index, size); break; default: @@ -1002,24 +1004,24 @@ static const char *_emm_main_get_plmn(const plmn_t *plmn, int index, ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_get_plmn_index(const char *plmn, int format) +static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char *plmn, int format) { int index = -1; switch (format) { case NET_FORMAT_LONG: /* Get the index of the long alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_fullname_index(plmn); + index = IdleMode_get_plmn_fullname_index(emm_plmn_list, plmn); break; case NET_FORMAT_SHORT: /* Get the index of the short alpha-numeric PLMN identifier */ - index = IdleMode_get_plmn_shortname_index(plmn); + index = IdleMode_get_plmn_shortname_index(emm_plmn_list, plmn); break; case NET_FORMAT_NUM: /* Get the index of the numeric PLMN identifier */ - index = IdleMode_get_plmn_id_index(plmn); + index = IdleMode_get_plmn_id_index(emm_plmn_list, plmn); break; default: diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index dfb8049f07..90b5be0b8c 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -80,18 +80,18 @@ const imsi_t *emm_main_get_imsi(emm_data_t *emm_data); const msisdn_t *emm_main_get_msisdn(void); /* User's getter/setter for network selection */ -int emm_main_set_plmn_selection_mode(emm_data_t *emm_data, int mode, int format, +int emm_main_set_plmn_selection_mode(nas_user_t *user, int mode, int format, const network_plmn_t *plmn, int rat); int emm_main_get_plmn_selection_mode(emm_data_t *emm_data); -int emm_main_get_plmn_list(emm_data_t *emm_data, const char **plist); -const char *emm_main_get_selected_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format); +int emm_main_get_plmn_list(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, const char **plist); +const char *emm_main_get_selected_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network registration */ Stat_t emm_main_get_plmn_status(emm_data_t *emm_data); tac_t emm_main_get_plmn_tac(emm_data_t *emm_data); ci_t emm_main_get_plmn_ci(emm_data_t *emm_data); AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data); -const char *emm_main_get_registered_plmn(emm_data_t *emm_data, network_plmn_t *plmn, int format); +const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network attachment */ int emm_main_is_attached(emm_data_t *emm_data); diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 0aaf76dfa0..0a58270216 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -185,6 +185,6 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, in */ int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status); int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat); -int emm_proc_network_notify(emm_data_t *emm_data, int index); +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int index); #endif /* __EMM_PROC_H__*/ diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index ee7b4f52c0..f707c983d2 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -386,7 +386,7 @@ int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn /* * Set the PLMN selection mode of operation */ - int index = emm_main_set_plmn_selection_mode(user->emm_data, mode, format, oper, AcT); + int index = emm_main_set_plmn_selection_mode(user, mode, format, oper, AcT); if ( !(index < 0) ) { /* @@ -455,7 +455,7 @@ int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format *mode = emm_main_get_plmn_selection_mode(user->emm_data); /* Get the currently selected operator */ - const char *oper_name = emm_main_get_selected_plmn(user->emm_data, oper, format); + const char *oper_name = emm_main_get_selected_plmn(user->emm_plmn_list, user->emm_data, oper, format); if (oper_name != NULL) { /* An operator is currently selected */ @@ -489,7 +489,7 @@ int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list) { LOG_FUNC_IN; - int size = emm_main_get_plmn_list(user->emm_data, oper_list); + int size = emm_main_get_plmn_list(user->emm_plmn_list, user->emm_data, oper_list); LOG_FUNC_RETURN (size); } diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 05ce952f22..7a2851ae5e 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -50,6 +50,7 @@ Description NAS type definition to manage a user equipment #include "esm_pt_defs.h" #include "EMM/emm_fsm_defs.h" #include "EMM/emmData.h" +#include "EMM/IdleMode_defs.h" typedef struct { int fd; @@ -59,6 +60,7 @@ typedef struct { esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status emm_data_t *emm_data; // EPS mobility management data + emm_plmn_list_t *emm_plmn_list; // list of PLMN identities } nas_user_t; #endif From 576bbd252c1c2dbd147bca4d19a4003ae68f31a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 10:29:13 +0200 Subject: [PATCH 153/571] UE/EMM: move _usim_data to nas_user_t --- openair3/NAS/UE/EMM/emm_main.c | 122 +++++++++++++++------------------ openair3/NAS/UE/EMM/emm_main.h | 2 +- openair3/NAS/UE/nas_proc.c | 4 +- openair3/NAS/UE/nas_proc.h | 2 +- openair3/NAS/UE/nas_user.c | 2 +- openair3/NAS/UE/user_defs.h | 2 + 6 files changed, 64 insertions(+), 70 deletions(-) diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index a1d4260923..b9ffcf4493 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -68,11 +68,6 @@ static const char *_emm_main_get_plmn(emm_plmn_list_t *emm_plmn_list, const plmn static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char *plmn, int format); -/* - * USIM application data - */ -static usim_data_t _usim_data; - /* * Callback executed whenever a change in the network has to be notified * to the user application @@ -93,7 +88,6 @@ static int _emm_main_callback(emm_data_t *emm_data, int); ** Inputs: cb: The user notification callback ** ** imei: The IMEI read from the UE's non-volatile ** ** memory ** - ** Others: _usim_data ** ** ** ** Outputs: None ** ** Return: None ** @@ -165,8 +159,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* * Get USIM application data */ - _usim_data.usimtestmode = usim_test; - if ( usim_api_read(&_usim_data) != RETURNok ) { + if ( usim_api_read(&user->usim_data) != RETURNok ) { /* The USIM application may not be present or not valid */ LOG_TRACE(WARNING, "EMM-MAIN - Failed to read USIM application data"); } else { @@ -177,54 +170,54 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data->usim_is_valid = TRUE; /* Get the Home PLMN derived from the IMSI */ - user->emm_data->hplmn.MCCdigit1 = _usim_data.imsi.u.num.digit1; - user->emm_data->hplmn.MCCdigit2 = _usim_data.imsi.u.num.digit2; - user->emm_data->hplmn.MCCdigit3 = _usim_data.imsi.u.num.digit3; - user->emm_data->hplmn.MNCdigit1 = _usim_data.imsi.u.num.digit4; - user->emm_data->hplmn.MNCdigit2 = _usim_data.imsi.u.num.digit5; - user->emm_data->hplmn.MNCdigit3 = _usim_data.imsi.u.num.digit6; + user->emm_data->hplmn.MCCdigit1 = user->usim_data.imsi.u.num.digit1; + user->emm_data->hplmn.MCCdigit2 = user->usim_data.imsi.u.num.digit2; + user->emm_data->hplmn.MCCdigit3 = user->usim_data.imsi.u.num.digit3; + user->emm_data->hplmn.MNCdigit1 = user->usim_data.imsi.u.num.digit4; + user->emm_data->hplmn.MNCdigit2 = user->usim_data.imsi.u.num.digit5; + user->emm_data->hplmn.MNCdigit3 = user->usim_data.imsi.u.num.digit6; /* Get the list of forbidden PLMNs */ for (i=0; (i < EMM_DATA_FPLMN_MAX) && (i < USIM_FPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.fplmn[i]) ) { - user->emm_data->fplmn.plmn[i] = _usim_data.fplmn[i]; + if ( PLMN_IS_VALID(user->usim_data.fplmn[i]) ) { + user->emm_data->fplmn.plmn[i] = user->usim_data.fplmn[i]; user->emm_data->fplmn.n_plmns += 1; } } /* Get the list of Equivalent HPLMNs */ for (i=0; (i < EMM_DATA_EHPLMN_MAX) && (i < USIM_EHPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.ehplmn[i]) ) { - user->emm_data->ehplmn.plmn[i] = _usim_data.ehplmn[i]; + if ( PLMN_IS_VALID(user->usim_data.ehplmn[i]) ) { + user->emm_data->ehplmn.plmn[i] = user->usim_data.ehplmn[i]; user->emm_data->ehplmn.n_plmns += 1; } } /* Get the list of User controlled PLMN Selector */ for (i=0; (i < EMM_DATA_PLMN_MAX) && (i < USIM_PLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.plmn[i].plmn) ) { - user->emm_data->plmn.plmn[i] = _usim_data.plmn[i].plmn; - user->emm_data->userAcT[i] = _usim_data.plmn[i].AcT; + if ( PLMN_IS_VALID(user->usim_data.plmn[i].plmn) ) { + user->emm_data->plmn.plmn[i] = user->usim_data.plmn[i].plmn; + user->emm_data->userAcT[i] = user->usim_data.plmn[i].AcT; user->emm_data->plmn.n_plmns += 1; } } /* Get the list of Operator controlled PLMN Selector */ for (i=0; (i < EMM_DATA_OPLMN_MAX) && (i < USIM_OPLMN_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.oplmn[i].plmn) ) { - user->emm_data->oplmn.plmn[i] = _usim_data.oplmn[i].plmn; - user->emm_data->operAcT[i] = _usim_data.oplmn[i].AcT; + if ( PLMN_IS_VALID(user->usim_data.oplmn[i].plmn) ) { + user->emm_data->oplmn.plmn[i] = user->usim_data.oplmn[i].plmn; + user->emm_data->operAcT[i] = user->usim_data.oplmn[i].AcT; user->emm_data->oplmn.n_plmns += 1; } } /* Get the list of Operator network name records */ for (i=0; (i < EMM_DATA_OPNN_MAX) && (i < USIM_OPL_MAX); i++) { - if ( PLMN_IS_VALID(_usim_data.opl[i].plmn) ) { - int pnn_id = _usim_data.opl[i].record_id; - user->emm_data->opnn[i].plmn = &_usim_data.opl[i].plmn; - user->emm_data->opnn[i].fullname = (char *)_usim_data.pnn[pnn_id].fullname.value; - user->emm_data->opnn[i].shortname = (char *)_usim_data.pnn[pnn_id].shortname.value; + if ( PLMN_IS_VALID(user->usim_data.opl[i].plmn) ) { + int pnn_id = user->usim_data.opl[i].record_id; + user->emm_data->opnn[i].plmn = &user->usim_data.opl[i].plmn; + user->emm_data->opnn[i].fullname = (char *)user->usim_data.pnn[pnn_id].fullname.value; + user->emm_data->opnn[i].shortname = (char *)user->usim_data.pnn[pnn_id].shortname.value; user->emm_data->n_opnns += 1; } } @@ -232,27 +225,27 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* TODO: Get the Higher Priority PLMN search period parameter */ /* Get the EPS location information */ - if (PLMN_IS_VALID(_usim_data.epsloci.guti.gummei.plmn)) { - user->emm_data->guti = &_usim_data.epsloci.guti; + if (PLMN_IS_VALID(user->usim_data.epsloci.guti.gummei.plmn)) { + user->emm_data->guti = &user->usim_data.epsloci.guti; } - if (TAI_IS_VALID(_usim_data.epsloci.tai)) { - user->emm_data->tai = &_usim_data.epsloci.tai; + if (TAI_IS_VALID(user->usim_data.epsloci.tai)) { + user->emm_data->tai = &user->usim_data.epsloci.tai; } - user->emm_data->status = _usim_data.epsloci.status; + user->emm_data->status = user->usim_data.epsloci.status; /* Get NAS configuration parameters */ user->emm_data->NAS_SignallingPriority = - _usim_data.nasconfig.NAS_SignallingPriority.value[0]; - user->emm_data->NMO_I_Behaviour = _usim_data.nasconfig.NMO_I_Behaviour.value[0]; - user->emm_data->AttachWithImsi = _usim_data.nasconfig.AttachWithImsi.value[0]; + user->usim_data.nasconfig.NAS_SignallingPriority.value[0]; + user->emm_data->NMO_I_Behaviour = user->usim_data.nasconfig.NMO_I_Behaviour.value[0]; + user->emm_data->AttachWithImsi = user->usim_data.nasconfig.AttachWithImsi.value[0]; user->emm_data->MinimumPeriodicSearchTimer = - _usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0]; + user->usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0]; user->emm_data->ExtendedAccessBarring = - _usim_data.nasconfig.ExtendedAccessBarring.value[0]; + user->usim_data.nasconfig.ExtendedAccessBarring.value[0]; user->emm_data->Timer_T3245_Behaviour = - _usim_data.nasconfig.Timer_T3245_Behaviour.value[0]; + user->usim_data.nasconfig.Timer_T3245_Behaviour.value[0]; /* * Get EPS NAS security context @@ -265,7 +258,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c memset(user->emm_data->security, 0, sizeof(emm_security_context_t)); /* Type of security context */ - if (_usim_data.securityctx.KSIasme.value[0] != + if (user->usim_data.securityctx.KSIasme.value[0] != USIM_KSI_NOT_AVAILABLE) { user->emm_data->security->type = EMM_KSI_NATIVE; } else { @@ -273,39 +266,39 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c } /* EPS key set identifier */ - user->emm_data->security->eksi = _usim_data.securityctx.KSIasme.value[0]; + user->emm_data->security->eksi = user->usim_data.securityctx.KSIasme.value[0]; /* ASME security key */ user->emm_data->security->kasme.length = - _usim_data.securityctx.Kasme.length; + user->usim_data.securityctx.Kasme.length; user->emm_data->security->kasme.value = (uint8_t *)malloc(user->emm_data->security->kasme.length); if (user->emm_data->security->kasme.value) { memcpy(user->emm_data->security->kasme.value, - _usim_data.securityctx.Kasme.value, + user->usim_data.securityctx.Kasme.value, user->emm_data->security->kasme.length); } /* Downlink count parameter */ - if (_usim_data.securityctx.dlNAScount.length <= sizeof(uint32_t)) { + if (user->usim_data.securityctx.dlNAScount.length <= sizeof(uint32_t)) { memcpy(&user->emm_data->security->dl_count, - _usim_data.securityctx.dlNAScount.value, - _usim_data.securityctx.dlNAScount.length); + user->usim_data.securityctx.dlNAScount.value, + user->usim_data.securityctx.dlNAScount.length); } /* Uplink count parameter */ - if (_usim_data.securityctx.ulNAScount.length <= sizeof(uint32_t)) { + if (user->usim_data.securityctx.ulNAScount.length <= sizeof(uint32_t)) { memcpy(&user->emm_data->security->ul_count, - _usim_data.securityctx.ulNAScount.value, - _usim_data.securityctx.ulNAScount.length); + user->usim_data.securityctx.ulNAScount.value, + user->usim_data.securityctx.ulNAScount.length); } /* Ciphering algorithm */ user->emm_data->security->capability.eps_encryption = - ((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); + ((user->usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); /* Identity protection algorithm */ user->emm_data->security->capability.eps_integrity = - (_usim_data.securityctx.algorithmID.value[0] & 0xf); + (user->usim_data.securityctx.algorithmID.value[0] & 0xf); /* NAS integrity and cyphering keys are not available */ } else { LOG_TRACE(WARNING, @@ -331,9 +324,9 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c } else { /* Check the IMSI */ LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); - user->emm_data->imsi = &_usim_data.imsi; + user->emm_data->imsi = &user->usim_data.imsi; int imsi_ok = _emm_main_imsi_cmp(&user->emm_data->nvdata.imsi, - &_usim_data.imsi); + &user->usim_data.imsi); if (!imsi_ok) { LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed nvram: " @@ -347,14 +340,14 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data->nvdata.imsi.u.value[5], user->emm_data->nvdata.imsi.u.value[6], user->emm_data->nvdata.imsi.u.value[7], - _usim_data.imsi.u.value[0], - _usim_data.imsi.u.value[1], - _usim_data.imsi.u.value[2], - _usim_data.imsi.u.value[3], - _usim_data.imsi.u.value[4], - _usim_data.imsi.u.value[5], - _usim_data.imsi.u.value[6], - _usim_data.imsi.u.value[7]); + user->usim_data.imsi.u.value[0], + user->usim_data.imsi.u.value[1], + user->usim_data.imsi.u.value[2], + user->usim_data.imsi.u.value[3], + user->usim_data.imsi.u.value[4], + user->usim_data.imsi.u.value[5], + user->usim_data.imsi.u.value[6], + user->usim_data.imsi.u.value[7]); memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); user->emm_data->nvdata.eplmn.n_plmns = 0; } @@ -504,17 +497,16 @@ const imsi_t *emm_main_get_imsi(emm_data_t *emm_data) ** Description: Get the Mobile Subscriber Dialing Number from the USIM ** ** ** ** Inputs: None ** - ** Others: _usim_data ** ** ** ** Outputs: None ** ** Return: Pointer to the subscriber dialing number ** ** Others: None ** ** ** ***************************************************************************/ -const msisdn_t *emm_main_get_msisdn(void) +const msisdn_t *emm_main_get_msisdn(nas_user_t *user) { LOG_FUNC_IN; - LOG_FUNC_RETURN (&_usim_data.msisdn.number); + LOG_FUNC_RETURN (&user->usim_data.msisdn.number); } /**************************************************************************** diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index 90b5be0b8c..fe574f6d3d 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -77,7 +77,7 @@ void emm_main_cleanup(emm_data_t *emm_data); const imsi_t *emm_main_get_imsi(emm_data_t *emm_data); /* User's getter of the subscriber dialing number */ -const msisdn_t *emm_main_get_msisdn(void); +const msisdn_t *emm_main_get_msisdn(nas_user_t *user); /* User's getter/setter for network selection */ int emm_main_set_plmn_selection_mode(nas_user_t *user, int mode, int format, diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index f707c983d2..c00b5677fb 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -299,11 +299,11 @@ int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi) +int nas_proc_get_msisdn(nas_user_t *user, char *msisdn_str, int *ton_npi) { LOG_FUNC_IN; - const msisdn_t *msisdn = emm_main_get_msisdn(); + const msisdn_t *msisdn = emm_main_get_msisdn(user); if (msisdn != NULL) { union { diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index 672488aee6..bf8dec9e58 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -77,7 +77,7 @@ int nas_proc_disable_s1_mode(nas_user_t *user); int nas_proc_get_eps(nas_user_t *user, int *stat); int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str); -int nas_proc_get_msisdn(char *msisdn_str, int *ton_npi); +int nas_proc_get_msisdn(nas_user_t *user, char *msisdn_str, int *ton_npi); int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp); diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 63aae7e8c2..af38c72ee5 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -2587,7 +2587,7 @@ static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) } /* Get the International Mobile Subscriber Identity (IMSI) */ - ret_code = nas_proc_get_msisdn(cnum->number, &cnum->type); + ret_code = nas_proc_get_msisdn(user, cnum->number, &cnum->type); if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get MS dialing number"); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 7a2851ae5e..f3dcbeaab0 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -51,6 +51,7 @@ Description NAS type definition to manage a user equipment #include "EMM/emm_fsm_defs.h" #include "EMM/emmData.h" #include "EMM/IdleMode_defs.h" +#include "API/USIM/usim_api.h" typedef struct { int fd; @@ -61,6 +62,7 @@ typedef struct { emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status emm_data_t *emm_data; // EPS mobility management data emm_plmn_list_t *emm_plmn_list; // list of PLMN identities + usim_data_t usim_data; // USIM application data } nas_user_t; #endif From 5899af2efd6aca8c3b3916e862c74a602145c361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 11:44:43 +0200 Subject: [PATCH 154/571] UE/EMM: move _authentication_data to nas_user_t --- openair3/NAS/UE/EMM/Authentication.c | 128 ++++++++++------------ openair3/NAS/UE/EMM/Authentication.h | 23 ++++ openair3/NAS/UE/EMM/SAP/EmmDeregistered.c | 2 +- openair3/NAS/UE/EMM/SAP/EmmNull.c | 2 +- openair3/NAS/UE/EMM/SecurityModeControl.c | 2 +- openair3/NAS/UE/EMM/emmData.h | 1 + openair3/NAS/UE/EMM/emm_proc.h | 2 +- openair3/NAS/UE/nas_proc.c | 5 + openair3/NAS/UE/user_defs.h | 5 + 9 files changed, 93 insertions(+), 77 deletions(-) create mode 100644 openair3/NAS/UE/EMM/Authentication.h diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index daa7f5a1f7..8061a9d80e 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -65,6 +65,7 @@ Description Defines the authentication EMM procedure executed by the #include "usim_api.h" #include "secu_defs.h" +#include "Authentication.h" /****************************************************************************/ @@ -97,25 +98,6 @@ static void *_authentication_t3416_handler(void *); static void *_authentication_t3418_handler(void *); static void *_authentication_t3420_handler(void *); -/* - * Internal data used for authentication procedure - */ -static struct { - uint8_t rand[AUTH_RAND_SIZE]; /* Random challenge number */ - uint8_t res[AUTH_RES_SIZE]; /* Authentication response */ - uint8_t ck[AUTH_CK_SIZE]; /* Ciphering key */ - uint8_t ik[AUTH_IK_SIZE]; /* Integrity key */ -#define AUTHENTICATION_T3410 0x01 -#define AUTHENTICATION_T3417 0x02 -#define AUTHENTICATION_T3421 0x04 -#define AUTHENTICATION_T3430 0x08 - unsigned char timers; /* Timer restart bitmap */ -#define AUTHENTICATION_COUNTER_MAX 3 - unsigned char mac_count:2; /* MAC failure counter (#20) */ - unsigned char umts_count:2; /* UMTS challenge failure counter (#26) */ - unsigned char sync_count:2; /* Sync failure counter (#21) */ -} _authentication_data; - /* * Abnormal case authentication procedure */ @@ -123,8 +105,8 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, const OctetString *auts); static int _authentication_abnormal_case_f(nas_user_t *user); -static int _authentication_stop_timers(void); -static int _authentication_start_timers(void); +static int _authentication_stop_timers(nas_user_t *user); +static int _authentication_start_timers(nas_user_t *user); static int _authentication_kasme(const OctetString *autn, const OctetString *ck, const OctetString *ik, const plmn_t *plmn, OctetString *kasme); @@ -163,11 +145,9 @@ static int _authentication_kasme(const OctetString *autn, ** ksi: The NAS ket sey identifier ** ** rand: Authentication parameter RAND ** ** autn: Authentication parameter AUTN ** - ** Others: user->emm_data-> _authentication_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: user->emm_data-> _authentication_data, T3416, ** ** T3418, T3420 ** ** ** ***************************************************************************/ @@ -178,6 +158,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, LOG_FUNC_IN; int rc = RETURNerror; + authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(INFO, "EMM-PROC - Authentication requested ksi type = %s, ksi = %d", native_ksi ? "native" : "mapped", ksi); @@ -203,11 +184,11 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, } /* Setup security keys */ - OctetString ck = {AUTH_CK_SIZE, _authentication_data.ck}; - OctetString ik = {AUTH_IK_SIZE, _authentication_data.ik}; - OctetString res = {AUTH_RES_SIZE, _authentication_data.res}; + OctetString ck = {AUTH_CK_SIZE, authentication_data->ck}; + OctetString ik = {AUTH_IK_SIZE, authentication_data->ik}; + OctetString res = {AUTH_RES_SIZE, authentication_data->res}; - if (memcmp(_authentication_data.rand, rand->value, AUTH_CK_SIZE) != 0) { + if (memcmp(authentication_data->rand, rand->value, AUTH_CK_SIZE) != 0) { /* * There is no valid stored RAND in the ME or the stored RAND is * different from the new received value in the AUTHENTICATION @@ -254,7 +235,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, (sbit == 0) ? "Non-EPS authentication unacceptable" : "MAC code failure"); /* Delete any previously stored RAND and RES and stop timer T3416 */ - (void) emm_proc_authentication_delete(); + emm_proc_authentication_delete(user); /* Proceed authentication abnormal cases procedure */ if (auts.length > 0) { @@ -284,7 +265,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, /* Store the new RAND in the volatile memory */ if (rand->length <= AUTH_RAND_SIZE) { - memcpy(_authentication_data.rand, rand->value, rand->length); + memcpy(authentication_data->rand, rand->value, rand->length); } /* Start, or reset and restart timer T3416 */ @@ -304,7 +285,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, * the authenticity of the core network */ /* Start any retransmission timers */ - rc = _authentication_start_timers(); + rc = _authentication_start_timers(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - Failed to start retransmission timers"); @@ -339,9 +320,9 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, if (rc != RETURNerror) { /* Reset the authentication failure counters */ - _authentication_data.mac_count = 0; - _authentication_data.umts_count = 0; - _authentication_data.sync_count = 0; + authentication_data->mac_count = 0; + authentication_data->umts_count = 0; + authentication_data->sync_count = 0; /* Create non-current EPS security context */ if (user->emm_data->non_current == NULL) { @@ -392,7 +373,6 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: user->emm_data-> _authentication_data, T3410, ** ** T3417, T3430 ** ** ** ***************************************************************************/ @@ -402,11 +382,12 @@ int emm_proc_authentication_reject(nas_user_t *user) emm_sap_t emm_sap; int rc; + authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(WARNING, "EMM-PROC - Authentication not accepted by the network"); /* Delete any previously stored RAND and RES and stop timer T3416 */ - (void) emm_proc_authentication_delete(); + (void) emm_proc_authentication_delete(user); /* Set the EPS update status to EU3 ROAMING NOT ALLOWED */ user->emm_data->status = EU3_ROAMING_NOT_ALLOWED; @@ -445,7 +426,7 @@ int emm_proc_authentication_reject(nas_user_t *user) /* Abort any EMM signalling procedure (prevent the retransmission timers to * be restarted) */ - _authentication_data.timers = 0x00; + authentication_data->timers = 0x00; /* * Notify EMM that authentication is not accepted by the network @@ -475,12 +456,12 @@ int emm_proc_authentication_reject(nas_user_t *user) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3416 ** ** ** ***************************************************************************/ -int emm_proc_authentication_delete(void) +int emm_proc_authentication_delete(nas_user_t *user) { LOG_FUNC_IN; + authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(INFO, "EMM-PROC - Delete authentication data RAND and RES"); @@ -491,8 +472,8 @@ int emm_proc_authentication_delete(void) } /* Delete any previously stored RAND and RES */ - memset(_authentication_data.rand, 0, AUTH_RAND_SIZE); - memset(_authentication_data.res, 0, AUTH_RES_SIZE); + memset(authentication_data->rand, 0, AUTH_RAND_SIZE); + memset(authentication_data->res, 0, AUTH_RES_SIZE); LOG_FUNC_RETURN (RETURNok); } @@ -529,13 +510,14 @@ int emm_proc_authentication_delete(void) static void *_authentication_t3416_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user=args; LOG_TRACE(WARNING, "EMM-PROC - T3416 timer expired"); /* Stop timer T3416 */ T3416.id = nas_timer_stop(T3416.id); /* Delete previouly stored RAND and RES authentication data */ - (void) emm_proc_authentication_delete(); + (void) emm_proc_authentication_delete(user); LOG_FUNC_RETURN (NULL); } @@ -556,23 +538,23 @@ static void *_authentication_t3416_handler(void *args) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _authentication_data, T3418 ** ** ** ***************************************************************************/ static void *_authentication_t3418_handler(void *args) { LOG_FUNC_IN; - nas_user_t *user=args; int rc; + nas_user_t *user=args; + authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(WARNING, "EMM-PROC - T3418 timer expired"); /* Stop timer T3418 */ T3418.id = nas_timer_stop(T3418.id); /* Reset the MAC failure and UMTS challenge failure counters */ - _authentication_data.mac_count = 0; - _authentication_data.umts_count = 0; + authentication_data->mac_count = 0; + authentication_data->umts_count = 0; /* 3GPP TS 24.301, section 5.4.2.7, case f */ rc = _authentication_abnormal_case_f(user); @@ -598,22 +580,22 @@ static void *_authentication_t3418_handler(void *args) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _authentication_data, T3420 ** ** ** ***************************************************************************/ static void *_authentication_t3420_handler(void *args) { LOG_FUNC_IN; - nas_user_t *user=args; int rc; + nas_user_t *user=args; + authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(WARNING, "EMM-PROC - T3420 timer expired"); /* Stop timer T3420 */ T3420.id = nas_timer_stop(T3420.id); /* Reset the sync failure counter */ - _authentication_data.sync_count = 0; + authentication_data->sync_count = 0; /* 3GPP TS 24.301, section 5.4.2.7, case f */ rc = _authentication_abnormal_case_f(user); @@ -643,7 +625,6 @@ static void *_authentication_t3420_handler(void *args) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3418, T3420 ** ** ** ***************************************************************************/ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, @@ -652,11 +633,12 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, LOG_FUNC_IN; int rc; + authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(WARNING, "EMM-PROC - " "Abnormal case, authentication counters c/d/e = %d/%d/%d", - _authentication_data.mac_count, _authentication_data.umts_count, - _authentication_data.sync_count); + authentication_data->mac_count, authentication_data->umts_count, + authentication_data->sync_count); /* * Notify EMM-AS SAP that Authentication Failure message has to be sent @@ -682,7 +664,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, case EMM_CAUSE_MAC_FAILURE: /* 3GPP TS 24.301, section 5.4.2.6, case c * Update the MAC failure counter */ - _authentication_data.mac_count += 1; + authentication_data->mac_count += 1; /* Start timer T3418 */ T3418.id = nas_timer_start(T3418.sec, _authentication_t3418_handler, user); @@ -693,7 +675,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, case EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE: /* 3GPP TS 24.301, section 5.4.2.6, case d * Update the UMTS challenge failure counter */ - _authentication_data.umts_count += 1; + authentication_data->umts_count += 1; /* Start timer T3418 */ T3418.id = nas_timer_start(T3418.sec, _authentication_t3418_handler, user); @@ -704,7 +686,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, case EMM_CAUSE_SYNCH_FAILURE: /* 3GPP TS 24.301, section 5.4.2.6, case e * Update the synch failure counter */ - _authentication_data.sync_count += 1; + authentication_data->sync_count += 1; /* Start timer T3420 */ T3420.id = nas_timer_start(T3420.sec, _authentication_t3420_handler, user); @@ -721,7 +703,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, /* * Stop any retransmission timers that are running */ - rc = _authentication_stop_timers(); + rc = _authentication_stop_timers(user); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-PROC - " @@ -735,12 +717,12 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, int failure_counter = 0; if (emm_cause == EMM_CAUSE_MAC_FAILURE) { - failure_counter = _authentication_data.mac_count - + _authentication_data.sync_count; + failure_counter = authentication_data->mac_count + + authentication_data->sync_count; } else if (emm_cause == EMM_CAUSE_SYNCH_FAILURE) { - failure_counter = _authentication_data.mac_count - + _authentication_data.umts_count - + _authentication_data.sync_count; + failure_counter = authentication_data->mac_count + + authentication_data->umts_count + + authentication_data->sync_count; } if (failure_counter >= AUTHENTICATION_COUNTER_MAX) { @@ -796,7 +778,7 @@ static int _authentication_abnormal_case_f(nas_user_t *user) * T3430), if they were running and stopped when the UE received * the first AUTHENTICATION REQUEST message containing an invalid * MAC or SQN */ - rc = _authentication_start_timers(); + rc = _authentication_start_timers(user); } LOG_FUNC_RETURN (rc); @@ -820,40 +802,40 @@ static int _authentication_abnormal_case_f(nas_user_t *user) ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _authentication_data, T3410, T3417, T3421, ** ** T3430 ** ** ** ***************************************************************************/ -static int _authentication_stop_timers(void) +static int _authentication_stop_timers(nas_user_t *user) { LOG_FUNC_IN; + authentication_data_t *authentication_data = user->authentication_data; /* Stop attach timer */ if (T3410.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); T3410.id = nas_timer_stop(T3410.id); - _authentication_data.timers |= AUTHENTICATION_T3410; + authentication_data->timers |= AUTHENTICATION_T3410; } /* Stop service request timer */ if (T3417.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); T3417.id = nas_timer_stop(T3417.id); - _authentication_data.timers |= AUTHENTICATION_T3417; + authentication_data->timers |= AUTHENTICATION_T3417; } /* Stop detach timer */ if (T3421.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE(INFO, "EMM-PROC - Stop timer T3421 (%d)", T3421.id); T3421.id = nas_timer_stop(T3421.id); - _authentication_data.timers |= AUTHENTICATION_T3421; + authentication_data->timers |= AUTHENTICATION_T3421; } /* Stop tracking area update timer */ if (T3430.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); T3430.id = nas_timer_stop(T3430.id); - _authentication_data.timers |= AUTHENTICATION_T3430; + authentication_data->timers |= AUTHENTICATION_T3430; } LOG_FUNC_RETURN (RETURNok); @@ -871,39 +853,39 @@ static int _authentication_stop_timers(void) ** 3GPP TS 24.301, section 5.4.2.7, case f ** ** ** ** Inputs: None ** - ** Others: _authentication_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3410, T3417, T3421, T3430 ** ** ** ***************************************************************************/ -static int _authentication_start_timers(void) +static int _authentication_start_timers(nas_user_t *user) { LOG_FUNC_IN; + authentication_data_t *authentication_data = user->authentication_data; - if (_authentication_data.timers & AUTHENTICATION_T3410) { + if (authentication_data->timers & AUTHENTICATION_T3410) { /* Start attach timer */ T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in " "%ld seconds", T3410.id, T3410.sec); } - if (_authentication_data.timers & AUTHENTICATION_T3417) { + if (authentication_data->timers & AUTHENTICATION_T3417) { /* Start service request timer */ T3417.id = nas_timer_start(T3417.sec, _emm_service_t3417_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3417 (%d) expires in " "%ld seconds", T3417.id, T3417.sec); } - if (_authentication_data.timers & AUTHENTICATION_T3421) { + if (authentication_data->timers & AUTHENTICATION_T3421) { /* Start detach timer */ T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3421 (%d) expires in " "%ld seconds", T3421.id, T3421.sec); } - if (_authentication_data.timers & AUTHENTICATION_T3430) { + if (authentication_data->timers & AUTHENTICATION_T3430) { /* Start tracking area update timer */ T3430.id = nas_timer_start(T3430.sec, _emm_tau_t3430_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3430 (%d) expires in " diff --git a/openair3/NAS/UE/EMM/Authentication.h b/openair3/NAS/UE/EMM/Authentication.h new file mode 100644 index 0000000000..50b2d990aa --- /dev/null +++ b/openair3/NAS/UE/EMM/Authentication.h @@ -0,0 +1,23 @@ +#ifndef _AUTHENTICATION_H +#define _AUTHENTICATION_H + +/* + * Internal data used for authentication procedure + */ +typedef struct { + uint8_t rand[AUTH_RAND_SIZE]; /* Random challenge number */ + uint8_t res[AUTH_RES_SIZE]; /* Authentication response */ + uint8_t ck[AUTH_CK_SIZE]; /* Ciphering key */ + uint8_t ik[AUTH_IK_SIZE]; /* Integrity key */ +#define AUTHENTICATION_T3410 0x01 +#define AUTHENTICATION_T3417 0x02 +#define AUTHENTICATION_T3421 0x04 +#define AUTHENTICATION_T3430 0x08 + unsigned char timers; /* Timer restart bitmap */ +#define AUTHENTICATION_COUNTER_MAX 3 + unsigned char mac_count:2; /* MAC failure counter (#20) */ + unsigned char umts_count:2; /* UMTS challenge failure counter (#26) */ + unsigned char sync_count:2; /* Sync failure counter (#21) */ +} authentication_data_t; + +#endif diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c index f2dd7e6821..21f07ba385 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c @@ -98,7 +98,7 @@ int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) /* Delete the authentication data RAND and RES */ // FIXME REVIEW - rc = emm_proc_authentication_delete(); + rc = emm_proc_authentication_delete(user); if (rc != RETURNok) { LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/SAP/EmmNull.c b/openair3/NAS/UE/EMM/SAP/EmmNull.c index 4fe8853b35..7b553f0a76 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmNull.c +++ b/openair3/NAS/UE/EMM/SAP/EmmNull.c @@ -86,7 +86,7 @@ int EmmNull(nas_user_t *user, const emm_reg_t *evt) assert(emm_fsm_get_status(user) == EMM_NULL); /* Delete the authentication data RAND and RES */ - rc = emm_proc_authentication_delete(); + rc = emm_proc_authentication_delete(user); if (rc != RETURNok) { LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 1126f087dd..684784e3db 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -158,7 +158,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, ksi); /* Delete any previously stored RAND and RES and stop timer T3416 */ - (void) emm_proc_authentication_delete(); + (void) emm_proc_authentication_delete(user); /* * Check the replayed UE security capabilities diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index 2618c44b83..8e3253718a 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -352,6 +352,7 @@ typedef struct emm_data_s { #define T3430_DEFAULT_VALUE 15 /* 15 seconds */ #define T3440_DEFAULT_VALUE 10 /* 10 seconds */ +// FIXME put in another structure struct nas_timer_t T3402; /* attach failure timer */ struct nas_timer_t T3410; /* attach timer */ struct nas_timer_t T3411; /* attach restart timer */ diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 0a58270216..85c0ea9ef1 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -167,7 +167,7 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, const OctetString *rand, const OctetString *autn); int emm_proc_authentication_reject(nas_user_t *user); -int emm_proc_authentication_delete(void); +int emm_proc_authentication_delete(nas_user_t *user); /* diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index c00b5677fb..7109feea4f 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -97,6 +97,11 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->proc.rsrq = NAS_PROC_RSRQ_UNKNOWN; user->proc.rsrp = NAS_PROC_RSRP_UNKNOWN; + user->authentication_data = calloc(1, sizeof(authentication_data_t)); + if ( user->authentication_data == NULL ) { + LOG_TRACE(ERROR, "NAS-PROC - Failed to alloc authentication_data"); + // FIXME stop here + } /* Initialize the EMM procedure manager */ emm_main_initialize(user, emm_cb, imei); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index f3dcbeaab0..8e299fef39 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -50,18 +50,23 @@ Description NAS type definition to manage a user equipment #include "esm_pt_defs.h" #include "EMM/emm_fsm_defs.h" #include "EMM/emmData.h" +#include "EMM/Authentication.h" #include "EMM/IdleMode_defs.h" #include "API/USIM/usim_api.h" typedef struct { int fd; proc_data_t proc; + // Eps Session Management esm_data_t *esm_data; // ESM internal data (used within ESM only) esm_pt_data_t *esm_pt_data; esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts + // Eps Mobility Management emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status emm_data_t *emm_data; // EPS mobility management data emm_plmn_list_t *emm_plmn_list; // list of PLMN identities + authentication_data_t *authentication_data; + // Hardware persistent storage usim_data_t usim_data; // USIM application data } nas_user_t; From 491f299bf2eb027124bc8f7ed722fec382bf4532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 11:56:45 +0200 Subject: [PATCH 155/571] UE/EMM: move _security_data to nas_user_t --- openair3/NAS/UE/EMM/SecurityModeControl.c | 27 +++++++++-------------- openair3/NAS/UE/EMM/SecurityModeControl.h | 11 +++++++++ openair3/NAS/UE/nas_proc.c | 7 ++++++ openair3/NAS/UE/user_defs.h | 2 ++ 4 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 openair3/NAS/UE/EMM/SecurityModeControl.h diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 684784e3db..5a90b43cde 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -64,6 +64,7 @@ Description Defines the security mode control EMM procedure executed by the # include "assertions.h" #include "secu_defs.h" #include "msc.h" +#include "SecurityModeControl.h" #if defined(NAS_BUILT_IN_UE) #include "nas_itti_messaging.h" @@ -92,13 +93,6 @@ static int _security_knas_int(const OctetString *kasme, OctetString *knas_int, static int _security_kenb(const OctetString *kasme, OctetString *kenb, uint32_t count); -/* - * Internal data used for security mode control procedure - */ -static struct { - OctetString kenb; /* eNodeB security key */ -} _security_data; - static void _security_release(emm_security_context_t *ctx); /* @@ -153,6 +147,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, int rc = RETURNerror; int emm_cause = EMM_CAUSE_SUCCESS; int security_context_is_new = FALSE; + security_data_t *security_data = user->security_data; LOG_TRACE(INFO, "EMM-PROC - Security mode control requested (ksi=%d)", ksi); @@ -226,17 +221,17 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, } /* Derive the eNodeB key */ - if (_security_data.kenb.value == NULL) { - _security_data.kenb.value = (uint8_t *)calloc(1,AUTH_KENB_SIZE); - _security_data.kenb.length = AUTH_KENB_SIZE; + if (security_data->kenb.value == NULL) { + security_data->kenb.value = (uint8_t *)calloc(1,AUTH_KENB_SIZE); + security_data->kenb.length = AUTH_KENB_SIZE; } - if (_security_data.kenb.value != NULL) { + if (security_data->kenb.value != NULL) { if (rc != RETURNerror) { LOG_TRACE(INFO, "EMM-PROC - Update the non-current EPS security context kenb"); // LG COMMENT rc = _security_kenb(&user->emm_data->security->kasme, rc = _security_kenb(&user->emm_data->non_current->kasme, - &_security_data.kenb, + &security_data->kenb, *(uint32_t *)(&user->emm_data->non_current->ul_count)); } } @@ -303,10 +298,10 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED; /* Release security mode control internal data */ - if (_security_data.kenb.value) { - free(_security_data.kenb.value); - _security_data.kenb.value = NULL; - _security_data.kenb.length = 0; + if (security_data->kenb.value) { + free(security_data->kenb.value); + security_data->kenb.value = NULL; + security_data->kenb.length = 0; } } } diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.h b/openair3/NAS/UE/EMM/SecurityModeControl.h new file mode 100644 index 0000000000..314c168544 --- /dev/null +++ b/openair3/NAS/UE/EMM/SecurityModeControl.h @@ -0,0 +1,11 @@ +#ifndef _SECURITYMODECONTROL_H +#define _SECURITYMODECONTROL_H + +/* + * Internal data used for security mode control procedure + */ +typedef struct { + OctetString kenb; /* eNodeB security key */ +} security_data_t; + +#endif diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 7109feea4f..b77e112370 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -102,6 +102,13 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, LOG_TRACE(ERROR, "NAS-PROC - Failed to alloc authentication_data"); // FIXME stop here } + + user->security_data = calloc(1, sizeof(security_data_t)); + if ( user->security_data == NULL ) { + LOG_TRACE(ERROR, "NAS-PROC - Failed to alloc security_data"); + // FIXME stop here + } + /* Initialize the EMM procedure manager */ emm_main_initialize(user, emm_cb, imei); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 8e299fef39..068736b622 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -53,6 +53,7 @@ Description NAS type definition to manage a user equipment #include "EMM/Authentication.h" #include "EMM/IdleMode_defs.h" #include "API/USIM/usim_api.h" +#include "SecurityModeControl.h" typedef struct { int fd; @@ -66,6 +67,7 @@ typedef struct { emm_data_t *emm_data; // EPS mobility management data emm_plmn_list_t *emm_plmn_list; // list of PLMN identities authentication_data_t *authentication_data; + security_data_t *security_data; //Internal data used for security mode control procedure // Hardware persistent storage usim_data_t usim_data; // USIM application data } nas_user_t; From ef05c1d9005ec0373c46042e6796bafc964891c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 12:42:37 +0200 Subject: [PATCH 156/571] UE/EMM: move static T34XX timers to emm_data_t --- openair3/NAS/UE/EMM/Attach.c | 61 ++++++------ openair3/NAS/UE/EMM/Authentication.c | 113 ++++++++++++----------- openair3/NAS/UE/EMM/Detach.c | 23 +++-- openair3/NAS/UE/EMM/ServiceRequestHdl.c | 4 +- openair3/NAS/UE/EMM/TrackingAreaUpdate.c | 4 +- openair3/NAS/UE/EMM/emmData.h | 39 ++++---- openair3/NAS/UE/EMM/emm_main.c | 53 ++++++----- 7 files changed, 166 insertions(+), 131 deletions(-) diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 3204e5f2da..0594306f6a 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -148,6 +148,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) emm_as_establish_t *emm_as = &emm_sap.u.emm_as.u.establish; esm_sap_t esm_sap; int rc; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Initiate EPS attach type = %s (%d)", _emm_attach_type_str[type], type); @@ -260,12 +261,12 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) } /* Start T3410 timer */ - T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, user); + emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, _emm_attach_t3410_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in %ld seconds", - T3410.id, T3410.sec); + emm_timers->T3410.id, emm_timers->T3410.sec); /* Stop T3402 and T3411 timers if running */ - T3402.id = nas_timer_stop(T3402.id); - T3411.id = nas_timer_stop(T3411.id); + emm_timers->T3402.id = nas_timer_stop(emm_timers->T3402.id); + emm_timers->T3411.id = nas_timer_stop(emm_timers->T3411.id); /* * Notify EMM-AS SAP that a RRC connection establishment procedure @@ -357,12 +358,13 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, int rc; int i; int j; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - EPS attach accepted by the network"); /* Stop timer T3410 */ - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); /* Delete old TAI list and store the received TAI list */ user->emm_data->ltai.n_tais = n_tais; @@ -372,16 +374,16 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, } /* Update periodic tracking area update timer value */ - T3412.sec = t3412; + emm_timers->T3412.sec = t3412; /* Update attach failure timer value */ if ( !(t3402 < 0) ) { - T3402.sec = t3402; + emm_timers->T3402.sec = t3402; } /* Update E-UTRAN deactivate ISR timer value */ if ( !(t3423 < 0) ) { - T3423.sec = t3423; + emm_timers->T3423.sec = t3423; } /* Delete old GUTI and store the new assigned GUTI if provided */ @@ -506,13 +508,14 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e emm_sap_t emm_sap; int rc; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - EPS attach rejected by the network, " "EMM cause = %d", emm_cause); /* Stop timer T3410 */ - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); /* Update the EPS update status, the GUTI, the visited registered TAI and * the eKSI */ @@ -790,6 +793,7 @@ int emm_proc_attach_failure(int is_initial, void *args) int rc = RETURNok; esm_sap_t esm_sap; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - EPS attach failure"); @@ -797,9 +801,9 @@ int emm_proc_attach_failure(int is_initial, void *args) (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Stop timer T3410 if still running */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); } if (is_initial) { @@ -826,9 +830,9 @@ int emm_proc_attach_failure(int is_initial, void *args) if (rc != RETURNerror) { /* Start T3411 timer */ - T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); + emm_timers->T3411.id = nas_timer_start(emm_timers->T3411.sec, _emm_attach_t3411_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", - T3411.id, T3411.sec); + emm_timers->T3411.id, emm_timers->T3411.sec); } LOG_FUNC_RETURN(rc); @@ -1002,13 +1006,14 @@ void *_emm_attach_t3410_handler(void *args) LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc; LOG_TRACE(WARNING, "EMM-PROC - T3410 timer expired"); /* Stop T3410 timer */ - T3410.id = nas_timer_stop(T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); /* Execute abnormal case attach procedure */ _emm_attach_abnormal_cases_bcd(user, &emm_sap); @@ -1045,12 +1050,13 @@ static void *_emm_attach_t3411_handler(void *args) LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3411 timer expired"); /* Stop T3411 timer */ - T3411.id = nas_timer_stop(T3411.id); + emm_timers->T3411.id = nas_timer_stop(emm_timers->T3411.id); /* * Notify EMM that timer T3411 expired and attach procedure has to be * restarted @@ -1090,12 +1096,13 @@ static void *_emm_attach_t3402_handler(void *args) LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3402 timer expired"); /* Stop T3402 timer */ - T3402.id = nas_timer_stop(T3402.id); + emm_timers->T3402.id = nas_timer_stop(emm_timers->T3402.id); /* Reset the attach attempt counter */ _emm_attach_data.attempt_count = 0; /* @@ -1140,23 +1147,23 @@ static void *_emm_attach_t3402_handler(void *args) static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap) { LOG_FUNC_IN; - + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - Abnormal case, attach counter = %d", _emm_attach_data.attempt_count); /* Stop timer T3410 */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); } if (_emm_attach_data.attempt_count < EMM_ATTACH_COUNTER_MAX) { /* Increment the attach attempt counter */ _emm_attach_data.attempt_count += 1; /* Start T3411 timer */ - T3411.id = nas_timer_start(T3411.sec, _emm_attach_t3411_handler, NULL); + emm_timers->T3411.id = nas_timer_start(emm_timers->T3411.sec, _emm_attach_t3411_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", - T3411.id, T3411.sec); + emm_timers->T3411.id, emm_timers->T3411.sec); /* * Notify EMM that the attempt to attach for EPS services failed and * the attach attempt counter didn't reach its maximum value; network @@ -1182,9 +1189,9 @@ static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap) user->emm_data->status = EU2_NOT_UPDATED; /* Start T3402 timer */ - T3402.id = nas_timer_start(T3402.sec, _emm_attach_t3402_handler, user); + emm_timers->T3402.id = nas_timer_start(emm_timers->T3402.sec, _emm_attach_t3402_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3402 (%d) expires in %ld seconds", - T3402.id, T3402.sec); + emm_timers->T3402.id, emm_timers->T3402.sec); /* * Notify EMM that the attempt to attach for EPS services failed and * the attach attempt counter reached its maximum value. diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 8061a9d80e..8a20eead25 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -159,6 +159,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, int rc = RETURNerror; authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Authentication requested ksi type = %s, ksi = %d", native_ksi ? "native" : "mapped", ksi); @@ -172,15 +173,15 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, } /* Stop timer T3418, if running */ - if (T3418.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3418 (%d)", T3418.id); - T3418.id = nas_timer_stop(T3418.id); + if (emm_timers->T3418.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3418 (%d)", emm_timers->T3418.id); + emm_timers->T3418.id = nas_timer_stop(emm_timers->T3418.id); } /* Stop timer T3420, if running */ - if (T3420.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3420 (%d)", T3420.id); - T3420.id = nas_timer_stop(T3420.id); + if (emm_timers->T3420.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3420 (%d)", emm_timers->T3420.id); + emm_timers->T3420.id = nas_timer_stop(emm_timers->T3420.id); } /* Setup security keys */ @@ -269,14 +270,14 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, } /* Start, or reset and restart timer T3416 */ - if (T3416.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); - T3416.id = nas_timer_stop(T3416.id); + if (emm_timers->T3416.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", emm_timers->T3416.id); + emm_timers->T3416.id = nas_timer_stop(emm_timers->T3416.id); } - T3416.id = nas_timer_start(T3416.sec, _authentication_t3416_handler, NULL); + emm_timers->T3416.id = nas_timer_start(emm_timers->T3416.sec, _authentication_t3416_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3416 (%d) expires in %ld seconds", - T3416.id, T3416.sec); + emm_timers->T3416.id, emm_timers->T3416.sec); } /* @@ -383,6 +384,7 @@ int emm_proc_authentication_reject(nas_user_t *user) emm_sap_t emm_sap; int rc; authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - Authentication not accepted by the network"); @@ -407,21 +409,21 @@ int emm_proc_authentication_reject(nas_user_t *user) user->emm_data->usim_is_valid = FALSE; /* Stop timer T3410 */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); } /* Stop timer T3417 */ - if (T3417.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); - T3417.id = nas_timer_stop(T3417.id); + if (emm_timers->T3417.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", emm_timers->T3417.id); + emm_timers->T3417.id = nas_timer_stop(emm_timers->T3417.id); } /* Stop timer T3430 */ - if (T3430.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); - T3430.id = nas_timer_stop(T3430.id); + if (emm_timers->T3430.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", emm_timers->T3430.id); + emm_timers->T3430.id = nas_timer_stop(emm_timers->T3430.id); } /* Abort any EMM signalling procedure (prevent the retransmission timers to @@ -462,13 +464,14 @@ int emm_proc_authentication_delete(nas_user_t *user) { LOG_FUNC_IN; authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Delete authentication data RAND and RES"); /* Stop timer T3416, if running */ - if (T3416.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", T3416.id); - T3416.id = nas_timer_stop(T3416.id); + if (emm_timers->T3416.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3416 (%d)", emm_timers->T3416.id); + emm_timers->T3416.id = nas_timer_stop(emm_timers->T3416.id); } /* Delete any previously stored RAND and RES */ @@ -511,11 +514,12 @@ static void *_authentication_t3416_handler(void *args) { LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3416 timer expired"); /* Stop timer T3416 */ - T3416.id = nas_timer_stop(T3416.id); + emm_timers->T3416.id = nas_timer_stop(emm_timers->T3416.id); /* Delete previouly stored RAND and RES authentication data */ (void) emm_proc_authentication_delete(user); @@ -546,12 +550,13 @@ static void *_authentication_t3418_handler(void *args) int rc; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; authentication_data_t *authentication_data = user->authentication_data; LOG_TRACE(WARNING, "EMM-PROC - T3418 timer expired"); /* Stop timer T3418 */ - T3418.id = nas_timer_stop(T3418.id); + emm_timers->T3418.id = nas_timer_stop(emm_timers->T3418.id); /* Reset the MAC failure and UMTS challenge failure counters */ authentication_data->mac_count = 0; authentication_data->umts_count = 0; @@ -589,11 +594,12 @@ static void *_authentication_t3420_handler(void *args) int rc; nas_user_t *user=args; authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3420 timer expired"); /* Stop timer T3420 */ - T3420.id = nas_timer_stop(T3420.id); + emm_timers->T3420.id = nas_timer_stop(emm_timers->T3420.id); /* Reset the sync failure counter */ authentication_data->sync_count = 0; /* 3GPP TS 24.301, section 5.4.2.7, case f */ @@ -634,6 +640,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, int rc; authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - " "Abnormal case, authentication counters c/d/e = %d/%d/%d", @@ -666,10 +673,10 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, * Update the MAC failure counter */ authentication_data->mac_count += 1; /* Start timer T3418 */ - T3418.id = nas_timer_start(T3418.sec, + emm_timers->T3418.id = nas_timer_start(emm_timers->T3418.sec, _authentication_t3418_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " - "%ld seconds", T3418.id, T3418.sec); + "%ld seconds", emm_timers->T3418.id, emm_timers->T3418.sec); break; case EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE: @@ -677,10 +684,10 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, * Update the UMTS challenge failure counter */ authentication_data->umts_count += 1; /* Start timer T3418 */ - T3418.id = nas_timer_start(T3418.sec, + emm_timers->T3418.id = nas_timer_start(emm_timers->T3418.sec, _authentication_t3418_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3418 (%d) expires in " - "%ld seconds", T3418.id, T3418.sec); + "%ld seconds", emm_timers->T3418.id, emm_timers->T3418.sec); break; case EMM_CAUSE_SYNCH_FAILURE: @@ -688,10 +695,10 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, * Update the synch failure counter */ authentication_data->sync_count += 1; /* Start timer T3420 */ - T3420.id = nas_timer_start(T3420.sec, + emm_timers->T3420.id = nas_timer_start(emm_timers->T3420.sec, _authentication_t3420_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3420 (%d) expires in " - "%ld seconds", T3420.id, T3420.sec); + "%ld seconds", emm_timers->T3420.id, emm_timers->T3420.sec); break; default: @@ -809,32 +816,33 @@ static int _authentication_stop_timers(nas_user_t *user) { LOG_FUNC_IN; authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; /* Stop attach timer */ - if (T3410.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", T3410.id); - T3410.id = nas_timer_stop(T3410.id); + if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3410 (%d)", emm_timers->T3410.id); + emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); authentication_data->timers |= AUTHENTICATION_T3410; } /* Stop service request timer */ - if (T3417.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", T3417.id); - T3417.id = nas_timer_stop(T3417.id); + if (emm_timers->T3417.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3417 (%d)", emm_timers->T3417.id); + emm_timers->T3417.id = nas_timer_stop(emm_timers->T3417.id); authentication_data->timers |= AUTHENTICATION_T3417; } /* Stop detach timer */ - if (T3421.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3421 (%d)", T3421.id); - T3421.id = nas_timer_stop(T3421.id); + if (emm_timers->T3421.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3421 (%d)", emm_timers->T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); authentication_data->timers |= AUTHENTICATION_T3421; } /* Stop tracking area update timer */ - if (T3430.id != NAS_TIMER_INACTIVE_ID) { - LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", T3430.id); - T3430.id = nas_timer_stop(T3430.id); + if (emm_timers->T3430.id != NAS_TIMER_INACTIVE_ID) { + LOG_TRACE(INFO, "EMM-PROC - Stop timer T3430 (%d)", emm_timers->T3430.id); + emm_timers->T3430.id = nas_timer_stop(emm_timers->T3430.id); authentication_data->timers |= AUTHENTICATION_T3430; } @@ -863,33 +871,34 @@ static int _authentication_start_timers(nas_user_t *user) { LOG_FUNC_IN; authentication_data_t *authentication_data = user->authentication_data; + emm_timers_t *emm_timers = user->emm_data->emm_timers; if (authentication_data->timers & AUTHENTICATION_T3410) { /* Start attach timer */ - T3410.id = nas_timer_start(T3410.sec, _emm_attach_t3410_handler, NULL); + emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, _emm_attach_t3410_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in " - "%ld seconds", T3410.id, T3410.sec); + "%ld seconds", emm_timers->T3410.id, emm_timers->T3410.sec); } if (authentication_data->timers & AUTHENTICATION_T3417) { /* Start service request timer */ - T3417.id = nas_timer_start(T3417.sec, _emm_service_t3417_handler, NULL); + emm_timers->T3417.id = nas_timer_start(emm_timers->T3417.sec, _emm_service_t3417_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3417 (%d) expires in " - "%ld seconds", T3417.id, T3417.sec); + "%ld seconds", emm_timers->T3417.id, emm_timers->T3417.sec); } if (authentication_data->timers & AUTHENTICATION_T3421) { /* Start detach timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, NULL); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, _emm_detach_t3421_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3421 (%d) expires in " - "%ld seconds", T3421.id, T3421.sec); + "%ld seconds", emm_timers->T3421.id, emm_timers->T3421.sec); } if (authentication_data->timers & AUTHENTICATION_T3430) { /* Start tracking area update timer */ - T3430.id = nas_timer_start(T3430.sec, _emm_tau_t3430_handler, NULL); + emm_timers->T3430.id = nas_timer_start(emm_timers->T3430.sec, _emm_tau_t3430_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3430 (%d) expires in " - "%ld seconds", T3430.id, T3430.sec); + "%ld seconds", emm_timers->T3430.id, emm_timers->T3430.sec); } LOG_FUNC_RETURN (RETURNok); diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index 480e24448a..f29a632805 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -203,14 +203,15 @@ int emm_proc_detach_request(void *args) LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc; if ( !_emm_detach_data.switch_off ) { /* Start T3421 timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, user); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, _emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld seconds", - T3421.id, T3421.sec); + emm_timers->T3421.id, emm_timers->T3421.sec); } /* @@ -249,6 +250,7 @@ int emm_proc_detach_accept(void* args) LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; int rc; LOG_TRACE(INFO, "EMM-PROC - UE initiated detach procedure completion"); @@ -257,7 +259,7 @@ int emm_proc_detach_accept(void* args) (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* * Notify ESM that all EPS bearer contexts have to be locally deactivated @@ -299,6 +301,7 @@ int emm_proc_detach_failure(int is_initial, void *args) LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc; @@ -308,7 +311,7 @@ int emm_proc_detach_failure(int is_initial, void *args) (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* * Notify EMM that detach procedure has to be restarted @@ -372,7 +375,7 @@ int emm_proc_detach_release(void *args) ** 3GPP TS 24.301, section 5.5.2.2.4 case c ** ** On the first four expiries of the timer, the UE shall re- ** ** transmit the DETACH REQUEST message and shall reset and ** - ** restart timer T3421. On the fifth expiry of timer T3421, ** + ** restart timer emm_timers->T3421. On the fifth expiry of timer T3421, ** ** the detach procedure shall be aborted. ** ** ** ** Inputs: args: handler parameters ** @@ -388,6 +391,7 @@ void *_emm_detach_t3421_handler(void *args) LOG_FUNC_IN; nas_user_t *user=args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; int rc; /* Increment the retransmission counter */ @@ -402,7 +406,7 @@ void *_emm_detach_t3421_handler(void *args) emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* Setup NAS information message to transfer */ emm_as->NASinfo = EMM_AS_NAS_INFO_DETACH; @@ -428,9 +432,9 @@ void *_emm_detach_t3421_handler(void *args) if (rc != RETURNerror) { /* Start T3421 timer */ - T3421.id = nas_timer_start(T3421.sec, _emm_detach_t3421_handler, user); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, _emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld " - "seconds", T3421.id, T3421.sec); + "seconds", emm_timers->T3421.id, emm_timers->T3421.sec); } } else { /* Abort the detach procedure */ @@ -464,6 +468,7 @@ static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type) { LOG_FUNC_IN; + emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc ; @@ -473,7 +478,7 @@ static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type) (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Stop timer T3421 */ - T3421.id = nas_timer_stop(T3421.id); + emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); /* * Notify EMM that detach procedure failed diff --git a/openair3/NAS/UE/EMM/ServiceRequestHdl.c b/openair3/NAS/UE/EMM/ServiceRequestHdl.c index 349fce7cad..65df01b114 100644 --- a/openair3/NAS/UE/EMM/ServiceRequestHdl.c +++ b/openair3/NAS/UE/EMM/ServiceRequestHdl.c @@ -112,11 +112,13 @@ void *_emm_service_t3417_handler(void *); void *_emm_service_t3417_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3417 timer expired"); /* Stop timer T3417 */ - T3417.id = nas_timer_stop(T3417.id); + emm_timers->T3417.id = nas_timer_stop(emm_timers->T3417.id); LOG_FUNC_RETURN(NULL); } diff --git a/openair3/NAS/UE/EMM/TrackingAreaUpdate.c b/openair3/NAS/UE/EMM/TrackingAreaUpdate.c index 50a440951b..5fe732b22d 100644 --- a/openair3/NAS/UE/EMM/TrackingAreaUpdate.c +++ b/openair3/NAS/UE/EMM/TrackingAreaUpdate.c @@ -113,11 +113,13 @@ void *_emm_tau_t3430_handler(void *); void *_emm_tau_t3430_handler(void *args) { LOG_FUNC_IN; + nas_user_t *user = args; + emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(WARNING, "EMM-PROC - T3430 timer expired"); /* Stop timer T3430 */ - T3430.id = nas_timer_stop(T3430.id); + emm_timers->T3430.id = nas_timer_stop(emm_timers->T3430.id); LOG_FUNC_RETURN(NULL); } diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index 8e3253718a..bb7aff5c47 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -197,6 +197,20 @@ typedef struct emm_nvdata_s { PLMN_LIST_T(EMM_DATA_EPLMN_MAX) eplmn; } emm_nvdata_t; +typedef struct { + struct nas_timer_t T3402; /* attach failure timer */ + struct nas_timer_t T3410; /* attach timer */ + struct nas_timer_t T3411; /* attach restart timer */ + struct nas_timer_t T3412; /* periodic tracking area update timer */ + struct nas_timer_t T3416; /* EPS authentication challenge timer */ + struct nas_timer_t T3417; /* Service request timer */ + struct nas_timer_t T3418; /* MAC authentication failure timer */ + struct nas_timer_t T3420; /* Synch authentication failure timer */ + struct nas_timer_t T3421; /* Detach timer */ + struct nas_timer_t T3430; /* tracking area update timer */ + struct nas_timer_t T3423; /* E-UTRAN deactivate ISR timer */ +} emm_timers_t; + /* * Structure of the EMM data * ------------------------- @@ -324,7 +338,11 @@ typedef struct emm_data_s { */ emm_security_context_t *security; /* current security context */ emm_security_context_t *non_current; /* non-current security context */ - + /* + * EPS mobility management timers – UE side + * ---------------------------------------- + */ + emm_timers_t *emm_timers; } emm_data_t; @@ -333,11 +351,6 @@ typedef struct emm_data_s { /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ -/* - * -------------------------------------------------------------------------- - * EPS mobility management timers – UE side - * -------------------------------------------------------------------------- - */ #define T3402_DEFAULT_VALUE 720 /* 12 minutes */ #define T3410_DEFAULT_VALUE 15 /* 15 seconds */ #define T3411_DEFAULT_VALUE 10 /* 10 seconds */ @@ -352,20 +365,6 @@ typedef struct emm_data_s { #define T3430_DEFAULT_VALUE 15 /* 15 seconds */ #define T3440_DEFAULT_VALUE 10 /* 10 seconds */ -// FIXME put in another structure -struct nas_timer_t T3402; /* attach failure timer */ -struct nas_timer_t T3410; /* attach timer */ -struct nas_timer_t T3411; /* attach restart timer */ -struct nas_timer_t T3412; /* periodic tracking area update timer */ -struct nas_timer_t T3416; /* EPS authentication challenge timer */ -struct nas_timer_t T3417; /* Service request timer */ -struct nas_timer_t T3418; /* MAC authentication failure timer */ -struct nas_timer_t T3420; /* Synch authentication failure timer */ -struct nas_timer_t T3421; /* Detach timer */ -struct nas_timer_t T3430; /* tracking area update timer */ - -struct nas_timer_t T3423; /* E-UTRAN deactivate ISR timer */ - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index b9ffcf4493..a19fa54648 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -79,6 +79,32 @@ static int _emm_main_callback(emm_data_t *emm_data, int); /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ + /* + * Initialize EMM timers + */ +void _emm_timers_initialize(emm_timers_t *emm_timers) { + emm_timers->T3410.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3410.sec = T3410_DEFAULT_VALUE; + emm_timers->T3411.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3411.sec = T3411_DEFAULT_VALUE; + emm_timers->T3402.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3402.sec = T3402_DEFAULT_VALUE; + emm_timers->T3416.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3416.sec = T3416_DEFAULT_VALUE; + emm_timers->T3417.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3417.sec = T3417_DEFAULT_VALUE; + emm_timers->T3418.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3418.sec = T3418_DEFAULT_VALUE; + emm_timers->T3420.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3420.sec = T3420_DEFAULT_VALUE; + emm_timers->T3421.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3421.sec = T3421_DEFAULT_VALUE; + emm_timers->T3423.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3423.sec = T3423_DEFAULT_VALUE; + emm_timers->T3430.id = NAS_TIMER_INACTIVE_ID; + emm_timers->T3430.sec = T3430_DEFAULT_VALUE; +} + /**************************************************************************** ** ** ** Name: emm_main_initialize() ** @@ -360,26 +386,12 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* * Initialize EMM timers */ - T3410.id = NAS_TIMER_INACTIVE_ID; - T3410.sec = T3410_DEFAULT_VALUE; - T3411.id = NAS_TIMER_INACTIVE_ID; - T3411.sec = T3411_DEFAULT_VALUE; - T3402.id = NAS_TIMER_INACTIVE_ID; - T3402.sec = T3402_DEFAULT_VALUE; - T3416.id = NAS_TIMER_INACTIVE_ID; - T3416.sec = T3416_DEFAULT_VALUE; - T3417.id = NAS_TIMER_INACTIVE_ID; - T3417.sec = T3417_DEFAULT_VALUE; - T3418.id = NAS_TIMER_INACTIVE_ID; - T3418.sec = T3418_DEFAULT_VALUE; - T3420.id = NAS_TIMER_INACTIVE_ID; - T3420.sec = T3420_DEFAULT_VALUE; - T3421.id = NAS_TIMER_INACTIVE_ID; - T3421.sec = T3421_DEFAULT_VALUE; - T3423.id = NAS_TIMER_INACTIVE_ID; - T3423.sec = T3423_DEFAULT_VALUE; - T3430.id = NAS_TIMER_INACTIVE_ID; - T3430.sec = T3430_DEFAULT_VALUE; + user->emm_data->emm_timers = calloc(1, sizeof(emm_timers_t)); + if ( user->emm_data->emm_timers == NULL ) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); + // FIXME stop here + } + _emm_timers_initialize(user->emm_data->emm_timers); /* * Initialize the user notification callback @@ -389,7 +401,6 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* * Initialize EMM internal data used for UE in idle mode */ - // FIXME REVIEW IdleMode_initialize(user, &_emm_main_callback); LOG_FUNC_OUT; From 9a33bca200cb864a18260c6e712f5d9be78aa820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 13:02:43 +0200 Subject: [PATCH 157/571] UE: move _nas_user_context to nas_user_t --- openair3/NAS/UE/nas_proc_defs.h | 27 ++++++++++ openair3/NAS/UE/nas_user.c | 93 ++++++++++++++++----------------- openair3/NAS/UE/user_defs.h | 1 + 3 files changed, 74 insertions(+), 47 deletions(-) diff --git a/openair3/NAS/UE/nas_proc_defs.h b/openair3/NAS/UE/nas_proc_defs.h index d3868526eb..1ce2bfd929 100644 --- a/openair3/NAS/UE/nas_proc_defs.h +++ b/openair3/NAS/UE/nas_proc_defs.h @@ -13,4 +13,31 @@ typedef struct { int rsrp; } proc_data_t; +/* + * MT SIM pending status (see ETSI TS 127 007 V10.6.0, Note 2) + * Commands which interact with MT that are accepted when MT is pending SIM PIN, + * SIM PUK, or PH-SIM are: +CGMI, +CGMM, +CGMR, +CGSN, D112; (emergency call), + * +CPAS, +CFUN, +CPIN, +CPINR, +CDIS (read and test command only), and +CIND + * (read and test command only). +*/ +typedef enum { + NAS_USER_READY, /* MT is not pending for any password */ + NAS_USER_SIM_PIN, /* MT is waiting SIM PIN to be given */ + NAS_USER_SIM_PUK, /* MT is waiting SIM PUK to be given */ + NAS_USER_PH_SIM_PIN /* MT is waiting phone-to-SIM card + * password to be given */ +} nas_user_sim_status; + +/* + * The local UE context + */ +typedef struct { + /* Firmware version number */ + const char *version; + /* SIM pending status */ + nas_user_sim_status sim_status; + /* Level of functionality */ + int fun; +} nas_user_context_t; + #endif diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index af38c72ee5..6275e9e33b 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -126,20 +126,7 @@ static at_response_t _nas_user_data = {}; * Local UE context * --------------------------------------------------------------------- */ -/* - * MT SIM pending status (see ETSI TS 127 007 V10.6.0, Note 2) - * Commands which interact with MT that are accepted when MT is pending SIM PIN, - * SIM PUK, or PH-SIM are: +CGMI, +CGMM, +CGMR, +CGSN, D112; (emergency call), - * +CPAS, +CFUN, +CPIN, +CPINR, +CDIS (read and test command only), and +CIND - * (read and test command only). -*/ -typedef enum { - NAS_USER_READY, /* MT is not pending for any password */ - NAS_USER_SIM_PIN, /* MT is waiting SIM PIN to be given */ - NAS_USER_SIM_PUK, /* MT is waiting SIM PUK to be given */ - NAS_USER_PH_SIM_PIN /* MT is waiting phone-to-SIM card - * password to be given */ -} nas_user_sim_status; + static const char *_nas_user_sim_status_str[] = { "READY", "SIM PIN", @@ -147,18 +134,6 @@ static const char *_nas_user_sim_status_str[] = { "PH-SIM PIN" }; -/* - * The local UE context - */ -static struct { - /* Firmware version number */ - const char *version; - /* SIM pending status */ - nas_user_sim_status sim_status; - /* Level of functionality */ - int fun; -} _nas_user_context; - /* * --------------------------------------------------------------------- * UE parameters stored in the UE's non-volatile memory device @@ -170,6 +145,12 @@ static user_nvdata_t _nas_user_nvdata; /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ +void _nas_user_context_initialize(nas_user_context_t *nas_user_context, const char *version) { + nas_user_context->version = version; + nas_user_context->sim_status = NAS_USER_SIM_PIN; + nas_user_context->fun = AT_CFUN_FUN_DEFAULT; +} + /**************************************************************************** ** ** ** Name: nas_user_initialize() ** @@ -209,9 +190,12 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, free(path); } - _nas_user_context.version = version; - _nas_user_context.sim_status = NAS_USER_SIM_PIN; - _nas_user_context.fun = AT_CFUN_FUN_DEFAULT; + user->nas_user_context = calloc(1, sizeof(nas_user_context_t)); + if ( user->nas_user_context == NULL ) { + LOG_TRACE(ERROR, "USR-MAIN - Failed to alloc nas_user_context"); + // FIXME stop here + } + _nas_user_context_initialize(user->nas_user_context, version); /* Initialize the internal NAS processing data */ nas_proc_initialize(user, emm_cb, esm_cb, _nas_user_nvdata.IMEI); @@ -578,6 +562,7 @@ static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cgmr_resp_t *cgmr = &_nas_user_data.response.cgmr; @@ -591,7 +576,7 @@ static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: /* Get the revision identifier */ - strncpy(cgmr->revision, _nas_user_context.version, + strncpy(cgmr->revision, nas_user_context->version, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -634,6 +619,7 @@ static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cimi_resp_t *cimi = &_nas_user_data.response.cimi; @@ -646,7 +632,7 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -695,6 +681,7 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cfun_resp_t *cfun = &_nas_user_data.response.cfun; @@ -761,14 +748,14 @@ static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNerror) { /* Update the functionality level */ - _nas_user_context.fun = fun; + nas_user_context->fun = fun; } break; case AT_COMMAND_GET: /* Get the MT's functionality level */ - cfun->fun = _nas_user_context.fun; + cfun->fun = nas_user_context->fun; break; case AT_COMMAND_TST: @@ -808,6 +795,7 @@ static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cpin_resp_t *cpin = &_nas_user_data.response.cpin; @@ -825,7 +813,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) * Set command sends to the MT a password which is necessary * before it can be operated */ - if (_nas_user_context.sim_status == NAS_USER_SIM_PIN) { + if (nas_user_context->sim_status == NAS_USER_SIM_PIN) { /* The MT is waiting for PIN password; check the PIN code */ if (strncmp(_nas_user_nvdata.PIN, data->command.cpin.pin, USER_PIN_SIZE) != 0) { @@ -837,7 +825,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) } else { /* The PIN code is matching; update the user's PIN * pending status */ - _nas_user_context.sim_status = NAS_USER_READY; + nas_user_context->sim_status = NAS_USER_READY; } } else { /* The MT is NOT waiting for PIN password; @@ -854,7 +842,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) * whether some password is required or not. */ strncpy(cpin->code, - _nas_user_sim_status_str[_nas_user_context.sim_status], + _nas_user_sim_status_str[nas_user_context->sim_status], AT_CPIN_RESP_SIZE); break; @@ -894,6 +882,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_csq_resp_t *csq = &_nas_user_data.response.csq; @@ -906,7 +895,7 @@ static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -955,6 +944,7 @@ static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cesq_resp_t *cesq = &_nas_user_data.response.cesq; @@ -967,7 +957,7 @@ static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1020,6 +1010,7 @@ static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cops_resp_t *cops = &_nas_user_data.response.cops; @@ -1042,7 +1033,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1269,6 +1260,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cgatt_resp_t *cgatt = &_nas_user_data.response.cgatt; @@ -1281,7 +1273,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1374,6 +1366,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_creg_resp_t *creg = &_nas_user_data.response.creg; @@ -1388,7 +1381,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1523,6 +1516,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cgreg_resp_t *cgreg = &_nas_user_data.response.cgreg; @@ -1537,7 +1531,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1672,6 +1666,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cereg_resp_t *cereg = &_nas_user_data.response.cereg; @@ -1686,7 +1681,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1853,6 +1848,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cgdcont_get_t *cgdcont = &_nas_user_data.response.cgdcont.get; @@ -1874,7 +1870,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2105,6 +2101,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cgact_resp_t *cgact = &_nas_user_data.response.cgact; @@ -2120,7 +2117,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2477,6 +2474,7 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cgpaddr_resp_t *cgpaddr = &_nas_user_data.response.cgpaddr; @@ -2491,7 +2489,7 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_SET: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2569,6 +2567,7 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + nas_user_context_t *nas_user_context = user->nas_user_context; int ret_code = RETURNok; at_cnum_resp_t *cnum = &_nas_user_data.response.cnum; @@ -2581,7 +2580,7 @@ static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: - if (_nas_user_context.sim_status != NAS_USER_READY) { + if (nas_user_context->sim_status != NAS_USER_READY) { _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 068736b622..90b7704858 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -70,6 +70,7 @@ typedef struct { security_data_t *security_data; //Internal data used for security mode control procedure // Hardware persistent storage usim_data_t usim_data; // USIM application data + nas_user_context_t *nas_user_context; } nas_user_t; #endif From 83e1dc9ed0eee2c3f01182f8ceaf630fba7ef036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 13:34:15 +0200 Subject: [PATCH 158/571] UE: move _nas_user_nvdata to nas_user_t --- openair3/NAS/UE/nas_user.c | 46 ++++++++++++++++--------------------- openair3/NAS/UE/user_defs.h | 3 +++ 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 6275e9e33b..8ee3e4d982 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -134,13 +134,6 @@ static const char *_nas_user_sim_status_str[] = { "PH-SIM PIN" }; -/* - * --------------------------------------------------------------------- - * UE parameters stored in the UE's non-volatile memory device - * --------------------------------------------------------------------- - */ -static user_nvdata_t _nas_user_nvdata; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -164,7 +157,6 @@ void _nas_user_context_initialize(nas_user_context_t *nas_user_context, const ch ** ** ** Outputs: None ** ** Return: None ** - ** Others: _nas_user_nvdata, _nas_user_context ** ** ** ***************************************************************************/ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, @@ -172,33 +164,39 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, { LOG_FUNC_IN; + user->nas_user_nvdata = calloc(1, sizeof(user_nvdata_t)); + if ( user->nas_user_nvdata == NULL ) { + LOG_TRACE(ERROR, "USR-MAIN - Failed to alloc nas_user_nvdata"); + // FIXME stop here + return; + } + /* Get UE's data pathname */ char *path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); if (path == NULL) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get UE's data pathname"); + // FIXME return an error code or exit + return; } /* Get UE data stored in the non-volatile memory device */ - else { - int rc = memory_read(path, &_nas_user_nvdata, sizeof(user_nvdata_t)); - - if (rc != RETURNok) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", path); - } - - free(path); + int rc = memory_read(path, user->nas_user_nvdata, sizeof(user_nvdata_t)); + if (rc != RETURNok) { + LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", path); } + free(path); user->nas_user_context = calloc(1, sizeof(nas_user_context_t)); if ( user->nas_user_context == NULL ) { LOG_TRACE(ERROR, "USR-MAIN - Failed to alloc nas_user_context"); // FIXME stop here + return; } _nas_user_context_initialize(user->nas_user_context, version); /* Initialize the internal NAS processing data */ - nas_proc_initialize(user, emm_cb, esm_cb, _nas_user_nvdata.IMEI); + nas_proc_initialize(user, emm_cb, esm_cb, user->nas_user_nvdata->IMEI); LOG_FUNC_OUT; } @@ -395,7 +393,6 @@ const void *nas_user_get_data(void) ** ning the IMEI. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -418,7 +415,7 @@ static int _nas_user_proc_cgsn(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: /* Get the Product Serial Number Identification (IMEI) */ - strncpy(cgsn->sn, _nas_user_nvdata.IMEI, + strncpy(cgsn->sn, user->nas_user_nvdata->IMEI, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -447,7 +444,6 @@ static int _nas_user_proc_cgsn(nas_user_t *user, const at_command_t *data) ** le Equipment to which it is connected to. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -470,7 +466,7 @@ static int _nas_user_proc_cgmi(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: /* Get the Manufacturer identifier */ - strncpy(cgmi->manufacturer, _nas_user_nvdata.manufacturer, + strncpy(cgmi->manufacturer, user->nas_user_nvdata->manufacturer, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -499,7 +495,6 @@ static int _nas_user_proc_cgmi(nas_user_t *user, const at_command_t *data) ** Equipment to which it is connected to. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -522,7 +517,7 @@ static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) switch (data->type) { case AT_COMMAND_ACT: /* Get the Model identifier */ - strncpy(cgmm->model, _nas_user_nvdata.model, + strncpy(cgmm->model, user->nas_user_nvdata->model, AT_RESPONSE_INFO_TEXT_SIZE); break; @@ -609,7 +604,6 @@ static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) ** ning the IMSI. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_nvdata ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -815,7 +809,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) */ if (nas_user_context->sim_status == NAS_USER_SIM_PIN) { /* The MT is waiting for PIN password; check the PIN code */ - if (strncmp(_nas_user_nvdata.PIN, + if (strncmp(user->nas_user_nvdata->PIN, data->command.cpin.pin, USER_PIN_SIZE) != 0) { /* The PIN code is NOT matching; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - PIN code is not correct " @@ -2374,7 +2368,7 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) /* Check password parameter */ if (data->mask & AT_CLCK_PASSWD_MASK) { /* Check the PIN code */ - if (strncmp(_nas_user_nvdata.PIN, + if (strncmp(user->nas_user_nvdata->PIN, data->command.clck.passwd, USER_PIN_SIZE) != 0) { /* The PIN code is NOT matching; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - Password is not correct " diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 90b7704858..2880fea0c0 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -54,6 +54,7 @@ Description NAS type definition to manage a user equipment #include "EMM/IdleMode_defs.h" #include "API/USIM/usim_api.h" #include "SecurityModeControl.h" +#include "userDef.h" typedef struct { int fd; @@ -70,6 +71,8 @@ typedef struct { security_data_t *security_data; //Internal data used for security mode control procedure // Hardware persistent storage usim_data_t usim_data; // USIM application data + user_nvdata_t *nas_user_nvdata; //UE parameters stored in the UE's non-volatile memory device + // nas_user_context_t *nas_user_context; } nas_user_t; From 607f0ca3777350c85b61f737cddf0c4c5563a2c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 13:44:49 +0200 Subject: [PATCH 159/571] UE: remove _nas_user_context from comments --- openair3/NAS/UE/nas_user.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 8ee3e4d982..f50df9296e 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -547,7 +547,6 @@ static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) ** Equipment to which it is connected to. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -665,7 +664,6 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) ** to different power consumption states. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -779,11 +777,9 @@ static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) ** can be operated. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_context, _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) @@ -866,7 +862,6 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) ** Equipment. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -928,7 +923,6 @@ static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) ** meters. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -994,7 +988,6 @@ static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) ** slot. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -1244,7 +1237,6 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) ** or detach the MT from, the EPS service. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -1350,7 +1342,6 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) ** location information in GERA/UTRA/E-UTRA Network. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -1500,7 +1491,6 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) ** information in GERA/UTRA Network. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -1650,7 +1640,6 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) ** information in E-UTRA Network. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -1832,7 +1821,6 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) ** fault bearer and traffic flows in EPS. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -2085,7 +2073,6 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) ** for E-UTRAN ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -2458,7 +2445,6 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) ** for the specified context identifiers ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -2551,7 +2537,6 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) ** subscriber. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** @@ -2613,7 +2598,6 @@ static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) ** are available for the user. ** ** ** ** Inputs: data: Pointer to the AT command data structure ** - ** Others: _nas_user_context ** ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** From 404c346182cae2227ab52c11ef82cd6a4e2ac161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 14:06:01 +0200 Subject: [PATCH 160/571] UE: rename _nas_user_data to at_response and move it to nas_user_t --- openair3/NAS/UE/nas_ue_task.c | 6 + openair3/NAS/UE/nas_user.c | 468 +++++++++++++++++----------------- openair3/NAS/UE/nas_user.h | 2 +- openair3/NAS/UE/user_defs.h | 2 + 4 files changed, 240 insertions(+), 238 deletions(-) diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 78fc49e682..8373a6f15b 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -88,6 +88,12 @@ void *nas_ue_task(void *args_p) itti_subscribe_event_fd (TASK_NAS_UE, user->fd); } + user->at_response = calloc(1, sizeof(at_response_t)); + if ( user->at_response == NULL ) { + LOG_E(NAS, "[UE %d] Can't allocate memory for user_at_commands\n", 0); + // FIXME stop here + } + /* Initialize NAS user */ nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); } diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index f50df9296e..ef95fd052a 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -115,12 +115,6 @@ static _nas_user_procedure_t _nas_user_procedure[AT_COMMAND_ID_MAX] = { _nas_user_proc_cgpaddr, /* CGPADDR */ }; -/* - * Internal representation of data structure returned to the user - * as the result of NAS procedure function call - */ -static at_response_t _nas_user_data = {}; - /* * --------------------------------------------------------------------- * Local UE context @@ -275,7 +269,7 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) /* Send response to UserProcess (If not in simulated reception) */ if (message == NULL) { /* Encode the user data message */ - bytes = user_api_encode_data (nas_user_get_data (), i == nb_command - 1); + bytes = user_api_encode_data (nas_user_get_data (user), i == nb_command - 1); if (bytes == RETURNerror) { /* Failed to encode the user data message; @@ -313,12 +307,12 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) ** Outputs: None ** ** Return: RETURNok if the command has been success- ** ** fully executed; RETURNerror otherwise ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ int nas_user_process_data(nas_user_t *user, const void *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNerror; @@ -340,15 +334,15 @@ int nas_user_process_data(nas_user_t *user, const void *data) ret_code = (*nas_procedure)(user, user_data); } else { /* AT command related to result format only */ - _nas_user_data.id = user_data->id; - _nas_user_data.type = user_data->type; - _nas_user_data.mask = user_data->mask; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = user_data->id; + at_response->type = user_data->type; + at_response->mask = user_data->mask; + at_response->cause_code = AT_ERROR_SUCCESS; ret_code = RETURNok; } } else { LOG_TRACE(ERROR, "USR-MAIN - Data to be processed is null"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } LOG_FUNC_RETURN (ret_code); @@ -371,10 +365,10 @@ int nas_user_process_data(nas_user_t *user, const void *data) ** Others: None ** ** ** ***************************************************************************/ -const void *nas_user_get_data(void) +const void *nas_user_get_data(nas_user_t *user) { LOG_FUNC_IN; - LOG_FUNC_RETURN ((void *) &_nas_user_data); + LOG_FUNC_RETURN ((void *) user->at_response); } /****************************************************************************/ @@ -396,21 +390,21 @@ const void *nas_user_get_data(void) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgsn(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgsn_resp_t *cgsn = &_nas_user_data.response.cgsn; + at_cgsn_resp_t *cgsn = &at_response->response.cgsn; memset(cgsn, 0, sizeof(at_cgsn_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGSN_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGSN_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: @@ -426,7 +420,7 @@ static int _nas_user_proc_cgsn(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGSN command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -447,21 +441,21 @@ static int _nas_user_proc_cgsn(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgmi(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgmi_resp_t *cgmi = &_nas_user_data.response.cgmi; + at_cgmi_resp_t *cgmi = &at_response->response.cgmi; memset(cgmi, 0, sizeof(at_cgmi_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGMI_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGMI_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: @@ -477,7 +471,7 @@ static int _nas_user_proc_cgmi(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGMI command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -498,21 +492,21 @@ static int _nas_user_proc_cgmi(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgmm_resp_t *cgmm = &_nas_user_data.response.cgmm; + at_cgmm_resp_t *cgmm = &at_response->response.cgmm; memset(cgmm, 0, sizeof(at_cgmm_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGMM_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGMM_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: @@ -528,7 +522,7 @@ static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGMM command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -550,22 +544,22 @@ static int _nas_user_proc_cgmm(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgmr_resp_t *cgmr = &_nas_user_data.response.cgmr; + at_cgmr_resp_t *cgmr = &at_response->response.cgmr; memset(cgmr, 0, sizeof(at_cgmr_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGMR_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGMR_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: @@ -581,7 +575,7 @@ static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGMR command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -606,27 +600,27 @@ static int _nas_user_proc_cgmr(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cimi_resp_t *cimi = &_nas_user_data.response.cimi; + at_cimi_resp_t *cimi = &at_response->response.cimi; memset(cimi, 0, sizeof(at_cimi_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CIMI_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CIMI_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -635,7 +629,7 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get IMSI number"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -647,7 +641,7 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CIMI command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -667,24 +661,24 @@ static int _nas_user_proc_cimi(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cfun_resp_t *cfun = &_nas_user_data.response.cfun; + at_cfun_resp_t *cfun = &at_response->response.cfun; memset(cfun, 0, sizeof(at_cfun_resp_t)); int fun = AT_CFUN_FUN_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CFUN_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CFUN_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: @@ -700,7 +694,7 @@ static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.cfun.rst); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -713,7 +707,7 @@ static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) * is not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.cfun.fun); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -759,7 +753,7 @@ static int _nas_user_proc_cfun(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CFUN command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -786,15 +780,16 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cpin_resp_t *cpin = &_nas_user_data.response.cpin; + at_cpin_resp_t *cpin = &at_response->response.cpin; memset(cpin, 0, sizeof(at_cpin_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CPIN_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CPIN_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: @@ -810,7 +805,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) /* The PIN code is NOT matching; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - PIN code is not correct " "(%s)", data->command.cpin.pin); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PASSWD; + at_response->cause_code = AT_ERROR_INCORRECT_PASSWD; ret_code = RETURNerror; } else { /* The PIN code is matching; update the user's PIN @@ -820,7 +815,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) } else { /* The MT is NOT waiting for PIN password; * return an error message */ - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_ALLOWED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_ALLOWED; ret_code = RETURNerror; } @@ -844,7 +839,7 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) /* Other types of AT CPIN command are not valid */ LOG_TRACE(ERROR, "USR-MAIN - AT+CPIN command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -865,27 +860,27 @@ static int _nas_user_proc_cpin(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_csq_resp_t *csq = &_nas_user_data.response.csq; + at_csq_resp_t *csq = &at_response->response.csq; memset(csq, 0, sizeof(at_csq_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CSQ_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CSQ_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -906,7 +901,7 @@ static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CSQ command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -926,27 +921,27 @@ static int _nas_user_proc_csq(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cesq_resp_t *cesq = &_nas_user_data.response.cesq; + at_cesq_resp_t *cesq = &at_response->response.cesq; memset(cesq, 0, sizeof(at_cesq_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CESQ_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CESQ_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -969,7 +964,7 @@ static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CESQ command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -991,16 +986,16 @@ static int _nas_user_proc_cesq(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cops_resp_t *cops = &_nas_user_data.response.cops; + at_cops_resp_t *cops = &at_response->response.cops; memset(cops, 0, sizeof(at_cops_resp_t)); static int read_format = AT_COPS_FORMAT_DEFAULT; @@ -1013,15 +1008,15 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) int oper_is_selected; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1057,7 +1052,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) /* field shall be present */ if ( !(data->mask & AT_COPS_OPER_MASK) ) { LOG_TRACE(ERROR, "USR-MAIN - parameter is not present"); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1065,7 +1060,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) /* field shall be present */ if ( !(data->mask & AT_COPS_FORMAT_MASK) ) { LOG_TRACE(ERROR, "USR-MAIN - parameter is not present"); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1076,7 +1071,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) /* The value of field is not valid */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid (%d)", data->command.cops.format); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1090,7 +1085,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) /* The value of field is not valid */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid (%d)", data->command.cops.AcT); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1118,7 +1113,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) /* The value of field is not valid */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid (%d)", data->command.cops.format); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1134,7 +1129,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - parameter is not supported (%d)", mode); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1150,7 +1145,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Network deregistration failed"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } } else if (mode != AT_COPS_FORMAT) { @@ -1161,7 +1156,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Network registration failed (=%d)", mode); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } } @@ -1183,7 +1178,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration data (=%d)", mode); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } @@ -1199,11 +1194,11 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) /* Set optional parameter bitmask */ if (oper_is_selected) { cops->get.format = read_format; - _nas_user_data.mask |= (AT_COPS_RESP_FORMAT_MASK | + at_response->mask |= (AT_COPS_RESP_FORMAT_MASK | AT_COPS_RESP_OPER_MASK); if (cops->get.AcT != NET_ACCESS_UNAVAILABLE) { - _nas_user_data.mask |= AT_COPS_RESP_ACT_MASK; + at_response->mask |= AT_COPS_RESP_ACT_MASK; } } @@ -1220,7 +1215,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+COPS command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1240,27 +1235,27 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgatt_resp_t *cgatt = &_nas_user_data.response.cgatt; + at_cgatt_resp_t *cgatt = &at_response->response.cgatt; memset(cgatt, 0, sizeof(at_cgatt_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGATT_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGATT_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1275,7 +1270,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid (%d)", data->command.cgatt.state); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1295,7 +1290,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - Failed to attach/detach " "to/from EPS service (=%d)", data->command.cgatt.state); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } } @@ -1324,7 +1319,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGATT command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1345,29 +1340,29 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_creg_resp_t *creg = &_nas_user_data.response.creg; + at_creg_resp_t *creg = &at_response->response.creg; memset(creg, 0, sizeof(at_creg_resp_t)); static int n = AT_CREG_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1384,7 +1379,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.creg.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1410,7 +1405,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to disable logging of network notification"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1425,7 +1420,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1456,7 +1451,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1473,7 +1468,7 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CREG command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1494,29 +1489,29 @@ static int _nas_user_proc_creg(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgreg_resp_t *cgreg = &_nas_user_data.response.cgreg; + at_cgreg_resp_t *cgreg = &at_response->response.cgreg; memset(cgreg, 0, sizeof(at_cgreg_resp_t)); static int n = AT_CGREG_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1533,7 +1528,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.cgreg.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1559,7 +1554,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to disable logging of network notification"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1574,7 +1569,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1605,7 +1600,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1622,7 +1617,7 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGREG command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1643,29 +1638,29 @@ static int _nas_user_proc_cgreg(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cereg_resp_t *cereg = &_nas_user_data.response.cereg; + at_cereg_resp_t *cereg = &at_response->response.cereg; memset(cereg, 0, sizeof(at_cereg_resp_t)); static int n = AT_CEREG_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1682,7 +1677,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.cereg.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1708,7 +1703,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to disable logging of network notification"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1719,7 +1714,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of location information"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1731,7 +1726,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to enable logging of registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1759,16 +1754,16 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get location information"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; break; } if (cereg->tac[0] != 0) { - _nas_user_data.mask |= (AT_CEREG_RESP_TAC_MASK | + at_response->mask |= (AT_CEREG_RESP_TAC_MASK | AT_CEREG_RESP_CI_MASK); if (cereg->AcT != NET_ACCESS_UNAVAILABLE) { - _nas_user_data.mask |= (AT_CEREG_RESP_ACT_MASK); + at_response->mask |= (AT_CEREG_RESP_ACT_MASK); } } @@ -1781,7 +1776,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get registration status"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -1798,7 +1793,7 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CEREG command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -1824,16 +1819,16 @@ static int _nas_user_proc_cereg(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgdcont_get_t *cgdcont = &_nas_user_data.response.cgdcont.get; + at_cgdcont_get_t *cgdcont = &at_response->response.cgdcont.get; memset(cgdcont, 0, sizeof(at_cgdcont_resp_t)); int cid = AT_CGDCONT_CID_DEFAULT; @@ -1845,15 +1840,15 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) int im_cn_signalling = AT_CGDCONT_IM_CM_DEFAULT; int reset_pdn = TRUE; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_NO_PARAM; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_NO_PARAM; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -1867,7 +1862,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.cgdcont.cid); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1887,7 +1882,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not " "valid (%s)", data->command.cgdcont.PDP_type); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1906,7 +1901,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) * not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not " "valid (%d)", data->command.cgdcont.d_comp); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1921,7 +1916,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) * not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not " "valid (%d)", data->command.cgdcont.h_comp); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1937,7 +1932,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - parameter " "is not valid (%d)", data->command.cgdcont.IPv4AddrAlloc); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1953,7 +1948,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - " "parameter is not valid (%d)", data->command.cgdcont.emergency_indication); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1969,7 +1964,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - " "parameter is not valid (%d)", data->command.cgdcont.P_CSCF_discovery); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -1986,7 +1981,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) LOG_TRACE(ERROR, "USR-MAIN - " "parameter is not valid (%d)", data->command.cgdcont.IM_CN_Signalling_Flag_Ind); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2011,7 +2006,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to setup PDN connection " "(=%d)", data->command.cgdcont.cid); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2028,7 +2023,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) if (cgdcont->n_pdns == 0) { LOG_TRACE(ERROR, "USR-MAIN - No any PDN context is defined"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2043,11 +2038,11 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) if (cid_max > AT_CGDCONT_RESP_SIZE) { /* The range is defined by the user interface */ - _nas_user_data.response.cgdcont.tst.n_cid = + at_response->response.cgdcont.tst.n_cid = AT_CGDCONT_RESP_SIZE; } else { /* The range is defined by the ESM sublayer application */ - _nas_user_data.response.cgdcont.tst.n_cid = cid_max; + at_response->response.cgdcont.tst.n_cid = cid_max; } } break; @@ -2055,7 +2050,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGDCONT command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2076,30 +2071,30 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgact_resp_t *cgact = &_nas_user_data.response.cgact; + at_cgact_resp_t *cgact = &at_response->response.cgact; memset(cgact, 0, sizeof(at_cgact_resp_t)); int cid = -1; int state = AT_CGACT_STATE_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGACT_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGACT_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2114,7 +2109,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) * not valid; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is " "not valid (%d)", data->command.cgact.state); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2128,7 +2123,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is " "not valid (%d)", data->command.cgact.cid); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2152,7 +2147,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) "(=%d,=%d)", (state != AT_CGACT_ACTIVATED)? "deactivate" : "activate", state, cid); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2167,7 +2162,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) if (cgact->n_pdns == 0) { LOG_TRACE(ERROR, "USR-MAIN - No any PDN context is defined"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2182,7 +2177,7 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGACT command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2204,7 +2199,6 @@ static int _nas_user_proc_cgact(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) @@ -2212,15 +2206,16 @@ static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) LOG_FUNC_IN; int ret_code = RETURNok; - at_cmee_resp_t *cmee = &_nas_user_data.response.cmee; + at_response_t *at_response = user->at_response; + at_cmee_resp_t *cmee = &at_response->response.cmee; memset(cmee, 0, sizeof(at_cmee_resp_t)); int n = AT_CMEE_N_DEFAULT; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CMEE_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CMEE_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: /* ATV0, ATV1 response format commands */ @@ -2238,7 +2233,7 @@ static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.cmee.n); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2282,7 +2277,7 @@ static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) if (cmee->n == RETURNerror) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get format of the final result code"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2296,7 +2291,7 @@ static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CMEE command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2317,21 +2312,21 @@ static int _nas_user_proc_cmee(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_clck_resp_t *clck = &_nas_user_data.response.clck; + at_clck_resp_t *clck = &at_response->response.clck; memset(clck, 0, sizeof(at_clck_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CLCK_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CLCK_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: @@ -2347,7 +2342,7 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) /* Facilities other than SIM is not supported */ LOG_TRACE(ERROR, "USR-MAIN - Facility is not supported (%s)", data->command.clck.fac); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2360,7 +2355,7 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) /* The PIN code is NOT matching; return an error message */ LOG_TRACE(ERROR, "USR-MAIN - Password is not correct " "(%s)", data->command.clck.passwd); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PASSWD; + at_response->cause_code = AT_ERROR_INCORRECT_PASSWD; ret_code = RETURNerror; break; } @@ -2375,14 +2370,14 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) /* unlock requires password */ LOG_TRACE(ERROR, "USR-MAIN - unlock mode of operation " "requires a password"); - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; ret_code = RETURNerror; break; } LOG_TRACE(ERROR, "USR-MAIN - unlock mode of operation " "is not supported"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; @@ -2393,14 +2388,14 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) /* unlock requires password */ LOG_TRACE(ERROR, "USR-MAIN - lock mode of operation " "requires a password"); - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; ret_code = RETURNerror; break; } LOG_TRACE(ERROR, "USR-MAIN - lock mode of operation " "is not supported"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; @@ -2412,7 +2407,7 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - parameter is not valid" " (%d)", data->command.clck.mode); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2428,7 +2423,7 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CLCK command type %d is not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2448,29 +2443,29 @@ static int _nas_user_proc_clck(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cgpaddr_resp_t *cgpaddr = &_nas_user_data.response.cgpaddr; + at_cgpaddr_resp_t *cgpaddr = &at_response->response.cgpaddr; memset(cgpaddr, 0, sizeof(at_cgpaddr_resp_t)); int cid = -1; - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CGPADDR_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CGPADDR_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_SET: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2484,7 +2479,7 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) * return an error message */ LOG_TRACE(ERROR, "USR-MAIN - parameter is " "not valid (%d)", data->command.cgpaddr.cid); - _nas_user_data.cause_code = AT_ERROR_INCORRECT_PARAMETERS; + at_response->cause_code = AT_ERROR_INCORRECT_PARAMETERS; ret_code = RETURNerror; break; } @@ -2502,7 +2497,7 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) if (cgpaddr->n_pdns == 0) { LOG_TRACE(ERROR, "USR-MAIN - No any PDN context is defined"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2520,7 +2515,7 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CGPADDR command type %d is " "not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2540,27 +2535,27 @@ static int _nas_user_proc_cgpaddr(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; nas_user_context_t *nas_user_context = user->nas_user_context; + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_cnum_resp_t *cnum = &_nas_user_data.response.cnum; + at_cnum_resp_t *cnum = &at_response->response.cnum; memset(cnum, 0, sizeof(at_cnum_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CNUM_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CNUM_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: if (nas_user_context->sim_status != NAS_USER_READY) { - _nas_user_data.cause_code = AT_ERROR_SIM_PIN_REQUIRED; + at_response->cause_code = AT_ERROR_SIM_PIN_REQUIRED; LOG_FUNC_RETURN(RETURNerror); } @@ -2569,7 +2564,7 @@ static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) if (ret_code != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get MS dialing number"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2581,7 +2576,7 @@ static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CNUM command type %d is " "not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } @@ -2601,21 +2596,20 @@ static int _nas_user_proc_cnum(nas_user_t *user, const at_command_t *data) ** ** ** Outputs: None ** ** Return: RETURNok; RETURNerror; ** - ** Others: _nas_user_data ** ** ** ***************************************************************************/ static int _nas_user_proc_clac(nas_user_t *user, const at_command_t *data) { LOG_FUNC_IN; - + at_response_t *at_response = user->at_response; int ret_code = RETURNok; - at_clac_resp_t *clac = &_nas_user_data.response.clac; + at_clac_resp_t *clac = &at_response->response.clac; memset(clac, 0, sizeof(at_clac_resp_t)); - _nas_user_data.id = data->id; - _nas_user_data.type = data->type; - _nas_user_data.mask = AT_RESPONSE_CLAC_MASK; - _nas_user_data.cause_code = AT_ERROR_SUCCESS; + at_response->id = data->id; + at_response->type = data->type; + at_response->mask = AT_RESPONSE_CLAC_MASK; + at_response->cause_code = AT_ERROR_SUCCESS; switch (data->type) { case AT_COMMAND_ACT: @@ -2625,7 +2619,7 @@ static int _nas_user_proc_clac(nas_user_t *user, const at_command_t *data) if (clac->n_acs == 0) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get the list of " "supported AT commands"); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; } break; @@ -2637,7 +2631,7 @@ static int _nas_user_proc_clac(nas_user_t *user, const at_command_t *data) default: LOG_TRACE(ERROR, "USR-MAIN - AT+CLAC command type %d is " "not supported", data->type); - _nas_user_data.cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; + at_response->cause_code = AT_ERROR_OPERATION_NOT_SUPPORTED; ret_code = RETURNerror; break; } diff --git a/openair3/NAS/UE/nas_user.h b/openair3/NAS/UE/nas_user.h index c78759ef42..eb7f94a671 100644 --- a/openair3/NAS/UE/nas_user.h +++ b/openair3/NAS/UE/nas_user.h @@ -67,6 +67,6 @@ int nas_user_receive_and_process(nas_user_t *user, char *message); int nas_user_process_data(nas_user_t *user, const void *data); -const void *nas_user_get_data(void); +const void *nas_user_get_data(nas_user_t *nas_user); #endif /* __NAS_USER_H__*/ diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 2880fea0c0..685e5c05e9 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -55,6 +55,7 @@ Description NAS type definition to manage a user equipment #include "API/USIM/usim_api.h" #include "SecurityModeControl.h" #include "userDef.h" +#include "at_response.h" typedef struct { int fd; @@ -74,6 +75,7 @@ typedef struct { user_nvdata_t *nas_user_nvdata; //UE parameters stored in the UE's non-volatile memory device // nas_user_context_t *nas_user_context; + at_response_t *at_response; // data structure returned to the user as the result of NAS procedure function call } nas_user_t; #endif From 46438c7cd9b071147c888487e417b782c69bf699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 14:25:04 +0200 Subject: [PATCH 161/571] UE/ESM: move _default_eps_bearer_context_data to nas_user_t --- .../ESM/DefaultEpsBearerContextActivation.c | 39 ++++--------------- openair3/NAS/UE/ESM/SAP/esm_sap.c | 2 +- openair3/NAS/UE/ESM/esmData.h | 13 ++++++- openair3/NAS/UE/ESM/esm_main.c | 9 +++++ openair3/NAS/UE/ESM/esm_proc.h | 2 +- openair3/NAS/UE/user_defs.h | 1 + 6 files changed, 30 insertions(+), 36 deletions(-) diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 68d1ce8eab..02d5671808 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -63,19 +63,6 @@ Description Defines the default EPS bearer context activation ESM /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -/* - * -------------------------------------------------------------------------- - * Internal data handled by the default EPS bearer context activation - * procedure in the UE - * -------------------------------------------------------------------------- - */ -static struct { - int ebi; /* EPS bearer identity of the default EPS bearer associated - * to the PDN connection to be activated */ -} _default_eps_bearer_context_data = {ESM_EBI_UNASSIGNED}; - - - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -101,7 +88,6 @@ static struct { ** Outputs: esm_cause: Cause code returned upon ESM procedure ** ** failure ** ** Return: RETURNok, RETURNerror ** - ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int ebi, @@ -110,6 +96,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e { LOG_FUNC_IN; esm_data_t *esm_data = user->esm_data; + default_eps_bearer_context_data_t *default_eps_bearer_context_data = user->default_eps_bearer_context_data; int rc = RETURNerror; LOG_TRACE(INFO, "ESM-PROC - Default EPS bearer context activation " @@ -144,7 +131,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e if (ebi != ESM_EBI_UNASSIGNED) { /* Default EPS bearer contextx successfully created */ - _default_eps_bearer_context_data.ebi = ebi; + default_eps_bearer_context_data->ebi = ebi; rc = RETURNok; } else { /* No resource available */ @@ -311,10 +298,9 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_complete(void) +int esm_proc_default_eps_bearer_context_complete(default_eps_bearer_context_data_t *default_eps_bearer_context_data) { LOG_FUNC_IN; @@ -322,7 +308,7 @@ int esm_proc_default_eps_bearer_context_complete(void) "ESM-PROC - Default EPS bearer context activation complete"); /* Reset default EPS bearer context internal data */ - _default_eps_bearer_context_data.ebi = ESM_EBI_UNASSIGNED; + default_eps_bearer_context_data->ebi = ESM_EBI_UNASSIGNED; LOG_FUNC_RETURN (RETURNok); } @@ -340,18 +326,17 @@ int esm_proc_default_eps_bearer_context_complete(void) ** ACCEPT message was sent. ** ** ** ** Inputs: None ** - ** Others: _default_eps_bearer_context_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _default_eps_bearer_context_data ** ** ** ***************************************************************************/ int esm_proc_default_eps_bearer_context_failure(nas_user_t *user) { LOG_FUNC_IN; + default_eps_bearer_context_data_t *default_eps_bearer_context_data = user->default_eps_bearer_context_data; - int ebi = _default_eps_bearer_context_data.ebi; + int ebi = default_eps_bearer_context_data->ebi; int pid, bid; LOG_TRACE(WARNING, @@ -362,18 +347,8 @@ int esm_proc_default_eps_bearer_context_failure(nas_user_t *user) if (rc != RETURNerror) { /* Reset default EPS bearer context internal data */ - _default_eps_bearer_context_data.ebi = ESM_EBI_UNASSIGNED; + default_eps_bearer_context_data->ebi = ESM_EBI_UNASSIGNED; } LOG_FUNC_RETURN (rc); } - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/* - * -------------------------------------------------------------------------- - * Timer handlers - * -------------------------------------------------------------------------- - */ diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index ae895af3e9..7ff1e57380 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -260,7 +260,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) * The activate default ESP bearer context accept message * has been successfully delivered to the other side */ - rc = esm_proc_default_eps_bearer_context_complete(); + rc = esm_proc_default_eps_bearer_context_complete(user->default_eps_bearer_context_data); if (rc != RETURNerror) { rc = esm_proc_pdn_connectivity_complete(user); diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 75947dabc9..ef7f523435 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -58,6 +58,17 @@ Description Defines internal private data handled by EPS Session /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * -------------------------------------------------------------------------- + * Internal data handled by the default EPS bearer context activation + * procedure in the UE + * -------------------------------------------------------------------------- + */ +typedef struct { + int ebi; /* EPS bearer identity of the default EPS bearer associated + * to the PDN connection to be activated */ +} default_eps_bearer_context_data_t; + /* * Minimal and maximal value of an EPS bearer identity: * The EPS Bearer Identity (EBI) identifies a message flow @@ -73,8 +84,6 @@ typedef enum { ESM_EBR_STATE_MAX } esm_ebr_state; - - /* * ----------------------- * EPS bearer context data diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index f79b40cfec..1b4099ce5b 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -77,12 +77,21 @@ void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) LOG_FUNC_IN; int i; + esm_data_t *esm_data = calloc(1, sizeof(esm_data_t)); if ( esm_data == NULL ) { LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc esm_data"); // FIXME Stop here !!! } user->esm_data = esm_data; + + default_eps_bearer_context_data_t *default_eps_bearer_context = calloc(1, sizeof(default_eps_bearer_context_data_t)); + if ( default_eps_bearer_context == NULL ) { + LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc default_eps_bearer_context"); + // FIXME Stop here !!! + } + default_eps_bearer_context->ebi = ESM_EBI_UNASSIGNED; + user->default_eps_bearer_context_data = default_eps_bearer_context; /* Total number of active EPS bearer contexts */ esm_data->n_ebrs = 0; /* List of active PDN connections */ diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h index 7ea23015e8..3d7260b83b 100644 --- a/openair3/NAS/UE/ESM/esm_proc.h +++ b/openair3/NAS/UE/ESM/esm_proc.h @@ -154,7 +154,7 @@ int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause); int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int ebi, const esm_proc_qos_t *esm_qos, int *esm_cause); -int esm_proc_default_eps_bearer_context_complete(void); +int esm_proc_default_eps_bearer_context_complete(default_eps_bearer_context_data_t *default_eps_bearer_context_data); int esm_proc_default_eps_bearer_context_failure(nas_user_t *user); int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 685e5c05e9..0661543047 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -64,6 +64,7 @@ typedef struct { esm_data_t *esm_data; // ESM internal data (used within ESM only) esm_pt_data_t *esm_pt_data; esm_ebr_data_t *esm_ebr_data; // EPS bearer contexts + default_eps_bearer_context_data_t *default_eps_bearer_context_data; // Eps Mobility Management emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status emm_data_t *emm_data; // EPS mobility management data From 289f1ea971a55cc25e6be8555bc8407ff48e2a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 14:48:32 +0200 Subject: [PATCH 162/571] UE/EMM: move _emm_detach_data to emm_data_t --- openair3/NAS/UE/EMM/Detach.c | 56 +++++++++++------------------ openair3/NAS/UE/EMM/emmData.h | 14 ++++++++ openair3/NAS/UE/EMM/emm_main.c | 17 +++++++++ openair3/NAS/UE/EMM/emm_proc.h | 27 -------------- openair3/NAS/UE/EMM/emm_proc_defs.h | 31 ++++++++++++++++ 5 files changed, 83 insertions(+), 62 deletions(-) create mode 100644 openair3/NAS/UE/EMM/emm_proc_defs.h diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index f29a632805..44fbe95181 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -85,20 +85,6 @@ void *_emm_detach_t3421_handler(void *); */ static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type); -/* - * Internal data used for detach procedure - */ -static struct { -#define EMM_DETACH_COUNTER_MAX 5 - unsigned int count; /* Counter used to limit the number of - * subsequently detach attempts */ - int switch_off; /* UE switch-off indicator */ - emm_proc_detach_type_t type; /* Type of the detach procedure - * currently in progress */ -} _emm_detach_data = {0, FALSE, EMM_DETACH_TYPE_RESERVED}; - - - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -128,7 +114,6 @@ static struct { ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: _emm_detach_data ** ** ** ***************************************************************************/ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off) @@ -137,15 +122,16 @@ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_of emm_sap_t emm_sap; emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; int rc; LOG_TRACE(INFO, "EMM-PROC - Initiate EPS detach type = %s (%d)", _emm_detach_type_str[type], type); /* Initialize the detach procedure internal data */ - _emm_detach_data.count = 0; - _emm_detach_data.switch_off = switch_off; - _emm_detach_data.type = type; + emm_detach_data->count = 0; + emm_detach_data->switch_off = switch_off; + emm_detach_data->type = type; /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ @@ -202,12 +188,13 @@ int emm_proc_detach_request(void *args) { LOG_FUNC_IN; - nas_user_t *user=args; + nas_user_t *user = args; emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; emm_sap_t emm_sap; int rc; - if ( !_emm_detach_data.switch_off ) { + if ( !emm_detach_data->switch_off ) { /* Start T3421 timer */ emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, _emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld seconds", @@ -289,7 +276,6 @@ int emm_proc_detach_accept(void* args) ** ** ** Inputs: is_initial: Not used ** ** args: Not used ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -300,7 +286,8 @@ int emm_proc_detach_failure(int is_initial, void *args) { LOG_FUNC_IN; - nas_user_t *user=args; + nas_user_t *user = args; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; emm_timers_t *emm_timers = user->emm_data->emm_timers; emm_sap_t emm_sap; int rc; @@ -317,7 +304,7 @@ int emm_proc_detach_failure(int is_initial, void *args) * Notify EMM that detach procedure has to be restarted */ emm_sap.primitive = EMMREG_DETACH_INIT; - emm_sap.u.emm_reg.u.detach.switch_off = _emm_detach_data.switch_off; + emm_sap.u.emm_reg.u.detach.switch_off = emm_detach_data->switch_off; rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN(rc); @@ -335,7 +322,6 @@ int emm_proc_detach_failure(int is_initial, void *args) ** The detach procedure shall be aborted. ** ** ** ** Inputs: args: not used ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** @@ -348,9 +334,10 @@ int emm_proc_detach_release(void *args) LOG_TRACE(WARNING, "EMM-PROC - NAS signalling connection released"); - nas_user_t *user=args; + nas_user_t *user = args; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; /* Abort the detach procedure */ - int rc = _emm_detach_abort(user, _emm_detach_data.type); + int rc = _emm_detach_abort(user, emm_detach_data->type); LOG_FUNC_RETURN(rc); } @@ -379,7 +366,6 @@ int emm_proc_detach_release(void *args) ** the detach procedure shall be aborted. ** ** ** ** Inputs: args: handler parameters ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: None ** @@ -390,17 +376,18 @@ void *_emm_detach_t3421_handler(void *args) { LOG_FUNC_IN; - nas_user_t *user=args; + nas_user_t *user = args; + emm_detach_data_t *emm_detach_data = user->emm_data->emm_detach_data; emm_timers_t *emm_timers = user->emm_data->emm_timers; int rc; /* Increment the retransmission counter */ - _emm_detach_data.count += 1; + emm_detach_data->count += 1; LOG_TRACE(WARNING, "EMM-PROC - T3421 timer expired, " - "retransmission counter = %d", _emm_detach_data.count); + "retransmission counter = %d", emm_detach_data->count); - if (_emm_detach_data.count < EMM_DETACH_COUNTER_MAX) { + if (emm_detach_data->count < EMM_DETACH_COUNTER_MAX) { /* Retransmit the Detach Request message */ emm_sap_t emm_sap; emm_as_data_t *emm_as = &emm_sap.u.emm_as.u.data; @@ -413,9 +400,9 @@ void *_emm_detach_t3421_handler(void *args) emm_as->NASmsg.length = 0; emm_as->NASmsg.value = NULL; /* Set the detach type */ - emm_as->type = _emm_detach_data.type; + emm_as->type = emm_detach_data->type; /* Set the switch-off indicator */ - emm_as->switch_off = _emm_detach_data.switch_off; + emm_as->switch_off = emm_detach_data->switch_off; /* Set the EPS mobile identity */ emm_as->guti = user->emm_data->guti; emm_as->ueid = 0; @@ -438,7 +425,7 @@ void *_emm_detach_t3421_handler(void *args) } } else { /* Abort the detach procedure */ - rc = _emm_detach_abort(user, _emm_detach_data.type); + rc = _emm_detach_abort(user, emm_detach_data->type); } LOG_FUNC_RETURN(NULL); @@ -457,7 +444,6 @@ void *_emm_detach_t3421_handler(void *args) ** Description: Aborts the detach procedure ** ** ** ** Inputs: type: not used ** - ** Others: _emm_detach_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index bb7aff5c47..a9921c8c8b 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -47,6 +47,7 @@ Description Defines internal private data handled by EPS Mobility #include "nas_timer.h" #include "esmData.h" +#include "emm_proc_defs.h" @@ -93,6 +94,18 @@ Description Defines internal private data handled by EPS Mobility /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * Internal data used for detach procedure + */ +typedef struct { +#define EMM_DETACH_COUNTER_MAX 5 + unsigned int count; /* Counter used to limit the number of + * subsequently detach attempts */ + int switch_off; /* UE switch-off indicator */ + emm_proc_detach_type_t type; /* Type of the detach procedure + * currently in progress */ +} emm_detach_data_t; + /* * -------------------------------------------------------------------------- * EPS NAS security context handled by EPS Mobility Management sublayer in @@ -343,6 +356,7 @@ typedef struct emm_data_s { * ---------------------------------------- */ emm_timers_t *emm_timers; + emm_detach_data_t *emm_detach_data; } emm_data_t; diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index a19fa54648..95ab7872f8 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -41,6 +41,7 @@ Description Defines the EPS Mobility Management procedure call manager, #include "nas_log.h" #include "emmData.h" #include "MobileIdentity.h" +#include "emm_proc_defs.h" #include "memory.h" #include "usim_api.h" @@ -105,6 +106,12 @@ void _emm_timers_initialize(emm_timers_t *emm_timers) { emm_timers->T3430.sec = T3430_DEFAULT_VALUE; } +void _emm_detach_initialize(emm_detach_data_t *emm_detach) { + emm_detach->count = 0; + emm_detach->switch_off = FALSE; + emm_detach->type = EMM_DETACH_TYPE_RESERVED; +} + /**************************************************************************** ** ** ** Name: emm_main_initialize() ** @@ -393,6 +400,16 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c } _emm_timers_initialize(user->emm_data->emm_timers); + /* + * Initialize Internal data used for detach procedure + */ + user->emm_data->emm_detach_data = calloc(1, sizeof(emm_detach_data_t)); + if ( user->emm_data->emm_detach_data == NULL ) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); + // FIXME stop here + } + _emm_detach_initialize(user->emm_data->emm_detach_data); + /* * Initialize the user notification callback */ diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 85c0ea9ef1..ca307b3f3a 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -48,33 +48,6 @@ Description Defines the EPS Mobility Management procedures executed at /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/* Type of network attachment */ -typedef enum { - EMM_ATTACH_TYPE_EPS = 0, - EMM_ATTACH_TYPE_IMSI, - EMM_ATTACH_TYPE_EMERGENCY, - EMM_ATTACH_TYPE_RESERVED, -} emm_proc_attach_type_t; - -/* Type of network detach */ -typedef enum { - EMM_DETACH_TYPE_EPS = 0, - EMM_DETACH_TYPE_IMSI, - EMM_DETACH_TYPE_EPS_IMSI, - EMM_DETACH_TYPE_REATTACH, - EMM_DETACH_TYPE_NOT_REATTACH, - EMM_DETACH_TYPE_RESERVED, -} emm_proc_detach_type_t; - -/* Type of requested identity */ -typedef enum { - EMM_IDENT_TYPE_NOT_AVAILABLE = 0, - EMM_IDENT_TYPE_IMSI, - EMM_IDENT_TYPE_IMEI, - EMM_IDENT_TYPE_IMEISV, - EMM_IDENT_TYPE_TMSI -} emm_proc_identity_type_t; - /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/EMM/emm_proc_defs.h b/openair3/NAS/UE/EMM/emm_proc_defs.h new file mode 100644 index 0000000000..3779626ac0 --- /dev/null +++ b/openair3/NAS/UE/EMM/emm_proc_defs.h @@ -0,0 +1,31 @@ +#ifndef _EMM_PROC_DEFS_H +#define _EMM_PROC_DEFS_H + +/* Type of network attachment */ +typedef enum { + EMM_ATTACH_TYPE_EPS = 0, + EMM_ATTACH_TYPE_IMSI, + EMM_ATTACH_TYPE_EMERGENCY, + EMM_ATTACH_TYPE_RESERVED, +} emm_proc_attach_type_t; + +/* Type of network detach */ +typedef enum { + EMM_DETACH_TYPE_EPS = 0, + EMM_DETACH_TYPE_IMSI, + EMM_DETACH_TYPE_EPS_IMSI, + EMM_DETACH_TYPE_REATTACH, + EMM_DETACH_TYPE_NOT_REATTACH, + EMM_DETACH_TYPE_RESERVED, +} emm_proc_detach_type_t; + +/* Type of requested identity */ +typedef enum { + EMM_IDENT_TYPE_NOT_AVAILABLE = 0, + EMM_IDENT_TYPE_IMSI, + EMM_IDENT_TYPE_IMEI, + EMM_IDENT_TYPE_IMEISV, + EMM_IDENT_TYPE_TMSI +} emm_proc_identity_type_t; + +#endif From 60032f57b40c8bed16cfe7ab133d55ca77e1c2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 13 Jul 2016 15:05:48 +0200 Subject: [PATCH 163/571] UE/EMM: move _emm_attach_data to emm_data_t --- openair3/NAS/UE/EMM/Attach.c | 40 +++++++++++++--------------------- openair3/NAS/UE/EMM/emmData.h | 12 ++++++++++ openair3/NAS/UE/EMM/emm_main.c | 14 ++++++++++++ 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 0594306f6a..b47b8cea8b 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -99,16 +99,6 @@ static void *_emm_attach_t3402_handler(void *); */ static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *); -/* - * Internal data used for attach procedure - */ -static struct { -#define EMM_ATTACH_COUNTER_MAX 5 - unsigned int attempt_count; /* Counter used to limit the number of - * subsequently rejected attach attempts */ -} _emm_attach_data = {0}; - - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -499,7 +489,6 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: user->emm_data-> _emm_attach_data, T3410 ** ** ** ***************************************************************************/ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg_pP) @@ -509,6 +498,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e emm_sap_t emm_sap; int rc; emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; LOG_TRACE(WARNING, "EMM-PROC - EPS attach rejected by the network, " "EMM cause = %d", emm_cause); @@ -566,14 +556,14 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e /* Delete the list of equivalent PLMNs */ user->emm_data->nvdata.eplmn.n_plmns = 0; /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; break; case EMM_CAUSE_TA_NOT_ALLOWED: case EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN: case EMM_CAUSE_NO_SUITABLE_CELLS: /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; break; case EMM_CAUSE_ESM_FAILURE: @@ -582,7 +572,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e if (user->emm_data->NAS_SignallingPriority != 1) { /* The UE is not configured for NAS signalling low priority; * set the attach attempt counter to 5 */ - _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; + emm_attach_data->attempt_count = EMM_ATTACH_COUNTER_MAX; } break; @@ -594,7 +584,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e case EMM_CAUSE_PROTOCOL_ERROR: /* 3GPP TS 24.301, section 5.5.1.2.6, case d * Set the attach attempt counter to 5 */ - _emm_attach_data.attempt_count = EMM_ATTACH_COUNTER_MAX; + emm_attach_data->attempt_count = EMM_ATTACH_COUNTER_MAX; break; default : @@ -717,14 +707,14 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** - ** Others: user->emm_data-> _emm_attach_data ** ** ** ***************************************************************************/ int emm_proc_attach_complete(void *args) { LOG_FUNC_IN; - nas_user_t *user=args; + nas_user_t *user = args; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; emm_sap_t emm_sap; esm_sap_t esm_sap; int rc; @@ -735,7 +725,7 @@ int emm_proc_attach_complete(void *args) (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; /* TODO: Reset the tracking area updating attempt counter */ /* Set the EPS update status to EU1 UPDATED */ @@ -1088,15 +1078,15 @@ static void *_emm_attach_t3411_handler(void *args) ** ** ** Outputs: None ** ** Return: None ** - ** Others: _emm_attach_data, T3402 ** ** ** ***************************************************************************/ static void *_emm_attach_t3402_handler(void *args) { LOG_FUNC_IN; - nas_user_t *user=args; + nas_user_t *user = args; emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; emm_sap_t emm_sap; LOG_TRACE(WARNING, "EMM-PROC - T3402 timer expired"); @@ -1104,7 +1094,7 @@ static void *_emm_attach_t3402_handler(void *args) /* Stop T3402 timer */ emm_timers->T3402.id = nas_timer_stop(emm_timers->T3402.id); /* Reset the attach attempt counter */ - _emm_attach_data.attempt_count = 0; + emm_attach_data->attempt_count = 0; /* * Notify EMM that timer T3402 expired and attach procedure has to be * restarted @@ -1140,7 +1130,6 @@ static void *_emm_attach_t3402_handler(void *args) ** ** ** Outputs: emm_sap: EMM service access point ** ** Return: None ** - ** Others: user->emm_data-> _emm_attach_data, T3402, T3410, ** ** T3411 ** ** ** ***************************************************************************/ @@ -1148,8 +1137,9 @@ static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap) { LOG_FUNC_IN; emm_timers_t *emm_timers = user->emm_data->emm_timers; + emm_attach_data_t *emm_attach_data = user->emm_data->emm_attach_data; LOG_TRACE(WARNING, "EMM-PROC - Abnormal case, attach counter = %d", - _emm_attach_data.attempt_count); + emm_attach_data->attempt_count); /* Stop timer T3410 */ if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { @@ -1157,9 +1147,9 @@ static void _emm_attach_abnormal_cases_bcd(nas_user_t *user, emm_sap_t *emm_sap) emm_timers->T3410.id = nas_timer_stop(emm_timers->T3410.id); } - if (_emm_attach_data.attempt_count < EMM_ATTACH_COUNTER_MAX) { + if (emm_attach_data->attempt_count < EMM_ATTACH_COUNTER_MAX) { /* Increment the attach attempt counter */ - _emm_attach_data.attempt_count += 1; + emm_attach_data->attempt_count += 1; /* Start T3411 timer */ emm_timers->T3411.id = nas_timer_start(emm_timers->T3411.sec, _emm_attach_t3411_handler, NULL); LOG_TRACE(INFO, "EMM-PROC - Timer T3411 (%d) expires in %ld seconds", diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index a9921c8c8b..84e58bb963 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -94,6 +94,17 @@ Description Defines internal private data handled by EPS Mobility /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * Internal data used for attach procedure + */ + +#define EMM_ATTACH_COUNTER_MAX 5 + +typedef struct { + unsigned int attempt_count; /* Counter used to limit the number of + * subsequently rejected attach attempts */ +} emm_attach_data_t; + /* * Internal data used for detach procedure */ @@ -357,6 +368,7 @@ typedef struct emm_data_s { */ emm_timers_t *emm_timers; emm_detach_data_t *emm_detach_data; + emm_attach_data_t *emm_attach_data; } emm_data_t; diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 95ab7872f8..5b6a44909e 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -106,6 +106,10 @@ void _emm_timers_initialize(emm_timers_t *emm_timers) { emm_timers->T3430.sec = T3430_DEFAULT_VALUE; } +void _emm_attach_initialize(emm_attach_data_t *emm_attach_data) { + emm_attach_data->attempt_count = 0; +} + void _emm_detach_initialize(emm_detach_data_t *emm_detach) { emm_detach->count = 0; emm_detach->switch_off = FALSE; @@ -410,6 +414,16 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c } _emm_detach_initialize(user->emm_data->emm_detach_data); + /* + * Initialize Internal data used for attach procedure + */ + user->emm_data->emm_attach_data = calloc(1, sizeof(emm_attach_data_t)); + if ( user->emm_data->emm_attach_data == NULL ) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); + // FIXME stop here + } + _emm_attach_initialize(user->emm_data->emm_attach_data); + /* * Initialize the user notification callback */ From c875b44958724582b4042c811fdf78d73e90da70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 18 Jul 2016 09:08:12 +0200 Subject: [PATCH 164/571] UE/API/USIM: move _usim_api_k to usim_keys_t --- openair3/NAS/UE/API/USIM/usim_api.c | 31 ++++++---------------------- openair3/NAS/UE/API/USIM/usim_api.h | 9 +++++++- openair3/NAS/UE/EMM/Authentication.c | 5 +++-- 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index 58ca9aa279..ed2449b4ab 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -66,17 +66,6 @@ Description Implements the API used by the NAS layer to read/write */ #define USIM_API_NVRAM_DIRNAME "USIM_DIR" -/* - * Subscriber authentication security key - */ -#define USIM_API_K_SIZE 16 -//#define USIM_API_K_VALUE "fec86ba6eb707ed08905757b1bb44b8f" -#define USIM_API_K_VALUE "8BAF473F2F8FD09487CCCBD7097C6862" -#define TEST_USIM_API_K_VALUE "000102030405060708090a0b0c0d0e0f" // CMW500 K key - -static uint8_t _usim_api_k[USIM_API_K_SIZE]; - - /* * List of last used Sequence Numbers SQN */ @@ -137,14 +126,7 @@ int usim_api_read(usim_data_t* data) } /* initialize the subscriber authentication security key */ - if(data->usimtestmode == 0) - { - _usim_api_hex_string_to_hex_value(_usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); - } - else - { - _usim_api_hex_string_to_hex_value(_usim_api_k, TEST_USIM_API_K_VALUE, USIM_API_K_SIZE); - } + _usim_api_hex_string_to_hex_value(data->keys.usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); free(path); LOG_FUNC_RETURN (RETURNok); @@ -392,7 +374,6 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au ** autn_pP: Authentication token ** ** AUTN = (SQN xor AK) || AMF || MAC ** ** 48 16 64 bits ** - ** Others: Security key ** ** ** ** Outputs: auts_pP: Re-synchronization token ** ** res_pP: Authentication response ** @@ -403,7 +384,7 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au ** Others: None ** ** ** ***************************************************************************/ -int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP, +int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts_pP, OctetString* res_pP, OctetString* ck_pP, OctetString* ik_pP) { @@ -421,7 +402,7 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP /* Compute the anonymity key AK = f5K (RAND) */ u8 ak[USIM_API_AK_SIZE]; - f2345(_usim_api_k, rand_pP->value, + f2345(usim_api_k, rand_pP->value, res_pP->value, ck_pP->value, ik_pP->value, ak); LOG_TRACE(INFO, "USIM-API - res(f2) :%s",dump_octet_string(res_pP)); LOG_TRACE(INFO, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP)); @@ -443,7 +424,7 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP /* Compute XMAC = f1K (SQN || RAND || AMF) */ #define USIM_API_XMAC_SIZE 8 u8 xmac[USIM_API_XMAC_SIZE]; - f1(_usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac); + f1(usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac); LOG_TRACE(DEBUG, "USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X", xmac[0],xmac[1],xmac[2],xmac[3], @@ -471,7 +452,7 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP /* Concealed value of the counter SQNms in the USIM: * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ - f5star(_usim_api_k, rand_pP->value, ak); + f5star(usim_api_k, rand_pP->value, ak); u8 sqn_ms[USIM_API_SQNMS_SIZE]; @@ -499,7 +480,7 @@ int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP * MACS = f1*K(SQNMS || RAND || AMF) */ #define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE u8 macs[USIM_API_MACS_SIZE]; - f1star(_usim_api_k, rand_pP->value, sqn_ms, + f1star(usim_api_k, rand_pP->value, sqn_ms, &rand_pP->value[USIM_API_SQN_SIZE], macs); LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X", macs[0],macs[1],macs[2],macs[3], diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index 8cfaeb8aed..c0bdf9a197 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -48,6 +48,12 @@ Description Implements the API used by the NAS layer to read/write /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ +/* + * Subscriber authentication security key + */ +#define USIM_API_K_SIZE 16 +#define USIM_API_K_VALUE "fec86ba6eb707ed08905757b1bb44b8f" + /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ @@ -106,6 +112,7 @@ typedef struct { /* Integrity key */ #define USIM_IK_SIZE 16 Byte_t ik[USIM_IK_SIZE]; + uint8_t usim_api_k[USIM_API_K_SIZE]; } usim_keys_t; /* @@ -343,7 +350,7 @@ int usim_api_read(usim_data_t* data); int usim_api_write(const usim_data_t* data); -int usim_api_authenticate(const OctetString* rand, const OctetString* autn, +int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts, OctetString* res, OctetString* ck, OctetString* ik); int usim_api_authenticate_test(const OctetString* rand, const OctetString* autn, diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 8a20eead25..b32a1c59f0 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -159,6 +159,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, int rc = RETURNerror; authentication_data_t *authentication_data = user->authentication_data; + uint8_t *key = user->usim_data.keys.usim_api_k; emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Authentication requested ksi type = %s, ksi = %d", native_ksi ? "native" : "mapped", ksi); @@ -219,11 +220,11 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, */ if(usim_test == 0) { - rc = usim_api_authenticate(rand, autn, &auts, &res, &ck, &ik); + rc = usim_api_authenticate(key, rand, autn, &auts, &res, &ck, &ik); } else { - rc = usim_api_authenticate_test(rand, autn, &auts, &res, &ck, &ik); // XOR algo for autentication on usim test mode + rc = usim_api_authenticate_test(key, rand, autn, &auts, &res, &ck, &ik); } } From ec889250a5f4645e8802cf3f4ea7f26efdeebb1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 18 Jul 2016 09:29:43 +0200 Subject: [PATCH 165/571] UE/API: remove old Makefiles --- openair3/NAS/UE/API/USER/Makefile | 42 ------------------- openair3/NAS/UE/API/USER/tst/Makefile | 58 --------------------------- openair3/NAS/UE/API/USIM/Makefile | 42 ------------------- 3 files changed, 142 deletions(-) delete mode 100644 openair3/NAS/UE/API/USER/Makefile delete mode 100644 openair3/NAS/UE/API/USER/tst/Makefile delete mode 100644 openair3/NAS/UE/API/USIM/Makefile diff --git a/openair3/NAS/UE/API/USER/Makefile b/openair3/NAS/UE/API/USER/Makefile deleted file mode 100644 index d5f4d6fffb..0000000000 --- a/openair3/NAS/UE/API/USER/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -#/* -# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The OpenAirInterface Software Alliance licenses this file to You under -# * the OAI Public License, Version 1.0 (the "License"); you may not use this file -# * except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.openairinterface.org/?page_id=698 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# *------------------------------------------------------------------------------- -# * For more information about the OpenAirInterface (OAI) Software Alliance: -# * contact@openairinterface.org -# */ - -ifndef PROJDIR -PROJDIR = $(PWD)/../../.. -INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(IESDIR) -I$(EMMMSGDIR) -I$(ESMMSGDIR) -endif - -include $(PROJDIR)/Makerules -include $(PROJDIR)/Makefile.inc - -all: $(OBJS) - -%.o: %.c Makefile - @echo Compiling $< - @$(CC) $(CFLAGS) -c $< -o $@ - -clean: - $(RM) $(OBJS) *.bak *~ - -depend: - makedepend -- ${CFLAGS} -- ${SRCS} - -# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/openair3/NAS/UE/API/USER/tst/Makefile b/openair3/NAS/UE/API/USER/tst/Makefile deleted file mode 100644 index 48681f31a5..0000000000 --- a/openair3/NAS/UE/API/USER/tst/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -#/* -# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The OpenAirInterface Software Alliance licenses this file to You under -# * the OAI Public License, Version 1.0 (the "License"); you may not use this file -# * except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.openairinterface.org/?page_id=698 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# *------------------------------------------------------------------------------- -# * For more information about the OpenAirInterface (OAI) Software Alliance: -# * contact@openairinterface.org -# */ - -ifndef PROJDIR -PROJDIR = $(PWD)/../../../.. -endif - -include $(PROJDIR)/Makerules -include $(PROJDIR)/Makefile.inc - -LIBS = -lutil -lapi -lEMMmsg -lESMmsg -lies -INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(USERAPIDIR) - -LIBSAPI = $(LIBDIR)/$(LIBAPI).a $(LIBDIR)/$(LIBAPI).so - -TST_OBJ = at_parser.o - -TST_TARGET = at_parser - -TARGETS = $(TST_TARGET) - -all: $(TARGETS) - -%.o: %.c Makefile - $(CC) $(CFLAGS) -c $< -o $@ - -$(TST_TARGET): $(TST_OBJ) - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) - -clean: - $(RM) $(OBJS) $(TARGETS) *.bak *~ - -depend: - makedepend -- ${CFLAGS} -- ${SRCS} - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -at_parser.o: $(USERAPIDIR)/at_command.h -at_parser.o: $(INCDIR)/commonDef.h $(INCDIR)/userDef.h -at_parser.o: $(INCDIR)/networkDef.h $(UTILDIR)/log.h diff --git a/openair3/NAS/UE/API/USIM/Makefile b/openair3/NAS/UE/API/USIM/Makefile deleted file mode 100644 index d5f4d6fffb..0000000000 --- a/openair3/NAS/UE/API/USIM/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -#/* -# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The OpenAirInterface Software Alliance licenses this file to You under -# * the OAI Public License, Version 1.0 (the "License"); you may not use this file -# * except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.openairinterface.org/?page_id=698 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# *------------------------------------------------------------------------------- -# * For more information about the OpenAirInterface (OAI) Software Alliance: -# * contact@openairinterface.org -# */ - -ifndef PROJDIR -PROJDIR = $(PWD)/../../.. -INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(IESDIR) -I$(EMMMSGDIR) -I$(ESMMSGDIR) -endif - -include $(PROJDIR)/Makerules -include $(PROJDIR)/Makefile.inc - -all: $(OBJS) - -%.o: %.c Makefile - @echo Compiling $< - @$(CC) $(CFLAGS) -c $< -o $@ - -clean: - $(RM) $(OBJS) *.bak *~ - -depend: - makedepend -- ${CFLAGS} -- ${SRCS} - -# DO NOT DELETE THIS LINE -- make depend depends on it. From b33b4df006b06491b2a9f17a9260363a380e6c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 18 Jul 2016 14:18:58 +0200 Subject: [PATCH 166/571] UE/API: rename _usim_api_data to usim_sqn_data and move it to usim_data --- openair3/NAS/UE/API/USIM/usim_api.c | 32 +++++++--------------------- openair3/NAS/UE/API/USIM/usim_api.h | 21 +++++++++++++++++- openair3/NAS/UE/EMM/Authentication.c | 6 +++--- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index ed2449b4ab..fc362e2461 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -66,22 +66,6 @@ Description Implements the API used by the NAS layer to read/write */ #define USIM_API_NVRAM_DIRNAME "USIM_DIR" -/* - * List of last used Sequence Numbers SQN - */ -#define USIM_API_AK_SIZE 6 -#define USIM_API_SQN_SIZE USIM_API_AK_SIZE -#define USIM_API_SQNMS_SIZE USIM_API_SQN_SIZE - -static struct _usim_api_data_s { - /* Highest sequence number the USIM has ever accepted */ - uint8_t sqn_ms[USIM_API_SQNMS_SIZE]; - /* List of the last used sequence numbers */ -#define USIM_API_SQN_LIST_SIZE 32 - uint8_t n_sqns; - uint32_t sqn[USIM_API_SQN_LIST_SIZE]; -} _usim_api_data; - static uint8_t _usim_api_hex_char_to_hex_value (char c); static void _usim_api_hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); static int _usim_api_check_sqn(uint32_t seq, uint8_t ind); @@ -384,7 +368,7 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au ** Others: None ** ** ** ***************************************************************************/ -int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString* rand_pP, const OctetString* autn_pP, +int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts_pP, OctetString* res_pP, OctetString* ck_pP, OctetString* ik_pP) { @@ -402,7 +386,7 @@ int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString /* Compute the anonymity key AK = f5K (RAND) */ u8 ak[USIM_API_AK_SIZE]; - f2345(usim_api_k, rand_pP->value, + f2345(usim_data->keys.usim_api_k, rand_pP->value, res_pP->value, ck_pP->value, ik_pP->value, ak); LOG_TRACE(INFO, "USIM-API - res(f2) :%s",dump_octet_string(res_pP)); LOG_TRACE(INFO, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP)); @@ -424,7 +408,7 @@ int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString /* Compute XMAC = f1K (SQN || RAND || AMF) */ #define USIM_API_XMAC_SIZE 8 u8 xmac[USIM_API_XMAC_SIZE]; - f1(usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac); + f1(usim_data->keys.usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac); LOG_TRACE(DEBUG, "USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X", xmac[0],xmac[1],xmac[2],xmac[3], @@ -452,19 +436,19 @@ int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString /* Concealed value of the counter SQNms in the USIM: * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ - f5star(usim_api_k, rand_pP->value, ak); + f5star(usim_data->keys.usim_api_k, rand_pP->value, ak); u8 sqn_ms[USIM_API_SQNMS_SIZE]; memset(sqn_ms, 0, USIM_API_SQNMS_SIZE); //#define USIM_API_SQN_MS_SIZE 3 - printf("_usim_api_data.sqn_ms %p\n",_usim_api_data.sqn_ms); + printf("usim_data->usim_sqn.sqn_ms %p\n",usim_data->usim_sqn_data.sqn_ms); for (i = 0; i < USIM_API_SQNMS_SIZE; i++) { //#warning "LG:BUG HERE TODO" - printf("i %d: ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); + printf("i %d: ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); sqn_ms[USIM_API_SQNMS_SIZE - i] = - ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; + ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; } u8 sqnms[USIM_API_SQNMS_SIZE]; @@ -480,7 +464,7 @@ int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString * MACS = f1*K(SQNMS || RAND || AMF) */ #define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE u8 macs[USIM_API_MACS_SIZE]; - f1star(usim_api_k, rand_pP->value, sqn_ms, + f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms, &rand_pP->value[USIM_API_SQN_SIZE], macs); LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X", macs[0],macs[1],macs[2],macs[3], diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index c0bdf9a197..5939de019f 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -115,6 +115,23 @@ typedef struct { uint8_t usim_api_k[USIM_API_K_SIZE]; } usim_keys_t; +/* + * List of last used Sequence Numbers SQN + */ +#define USIM_API_AK_SIZE 6 +#define USIM_API_SQN_SIZE USIM_API_AK_SIZE +#define USIM_API_SQNMS_SIZE USIM_API_SQN_SIZE + +typedef struct { + /* Highest sequence number the USIM has ever accepted */ + uint8_t sqn_ms[USIM_API_SQNMS_SIZE]; + /* List of the last used sequence numbers */ +#define USIM_API_SQN_LIST_SIZE 32 + uint8_t n_sqns; + uint32_t sqn[USIM_API_SQN_LIST_SIZE]; +} usim_sqn_data_t; + + /* * EPS NAS Security Context * ------------------------ @@ -336,6 +353,8 @@ typedef struct { usim_nasconfig_t nasconfig; /* usim test mode */ uint8_t usimtestmode; + usim_sqn_data_t usim_sqn_data; +>>>>>>> UE/API: rename _usim_api_data to usim_sqn_data and move it to usim_data } usim_data_t; /****************************************************************************/ @@ -350,7 +369,7 @@ int usim_api_read(usim_data_t* data); int usim_api_write(const usim_data_t* data); -int usim_api_authenticate(uint8_t usim_api_k[USIM_API_K_SIZE], const OctetString* rand_pP, const OctetString* autn_pP, +int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts, OctetString* res, OctetString* ck, OctetString* ik); int usim_api_authenticate_test(const OctetString* rand, const OctetString* autn, diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index b32a1c59f0..cee8553113 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -75,6 +75,7 @@ Description Defines the authentication EMM procedure executed by the /* * Retransmission timer handlers */ +// FIXME REVIEW extern void *_emm_attach_t3410_handler(void *); extern void *_emm_service_t3417_handler(void *); extern void *_emm_detach_t3421_handler(void *); @@ -159,7 +160,6 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, int rc = RETURNerror; authentication_data_t *authentication_data = user->authentication_data; - uint8_t *key = user->usim_data.keys.usim_api_k; emm_timers_t *emm_timers = user->emm_data->emm_timers; LOG_TRACE(INFO, "EMM-PROC - Authentication requested ksi type = %s, ksi = %d", native_ksi ? "native" : "mapped", ksi); @@ -220,11 +220,11 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, */ if(usim_test == 0) { - rc = usim_api_authenticate(key, rand, autn, &auts, &res, &ck, &ik); + rc = usim_api_authenticate(&user->usim_data, rand, autn, &auts, &res, &ck, &ik); } else { - rc = usim_api_authenticate_test(key, rand, autn, &auts, &res, &ck, &ik); + rc = usim_api_authenticate_test(&user->usim_data, rand, autn, &auts, &res, &ck, &ik); } } From 5b90bcbd252f31fd03dd068dea8b6b3a88a33488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 18 Jul 2016 14:35:20 +0200 Subject: [PATCH 167/571] UE/EMM/SAP: fix misuse of extern for emm_proc_plmn_selection_end() and emm_proc_status() --- openair3/NAS/UE/EMM/SAP/emm_as.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 09a0397055..8c26b42818 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -53,6 +53,8 @@ Description Defines the EMMAS Service Access Point that provides #include "emm_cause.h" #include "LowerLayer.h" +#include "emm_proc.h" + #include // memset #include // malloc, free @@ -65,10 +67,6 @@ Description Defines the EMMAS Service Access Point that provides /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -extern int emm_proc_plmn_selection_end(int found, tac_t tac, ci_t ci, AcT_t rat); - -extern int emm_proc_status(unsigned int ueid, int emm_cause); - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -108,7 +106,7 @@ static int _emm_as_release_ind(nas_user_t *user, const emm_as_release_t *msg); static int _emm_as_page_ind(const emm_as_page_t *msg); -static int _emm_as_cell_info_res(const emm_as_cell_info_t *msg); +static int _emm_as_cell_info_res(nas_user_t *user, const emm_as_cell_info_t *msg); static int _emm_as_cell_info_ind(const emm_as_cell_info_t *msg); static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm_cause); @@ -225,7 +223,7 @@ int emm_as_send(nas_user_t *user, const emm_as_t *msg) break; case _EMMAS_CELL_INFO_RES: - rc = _emm_as_cell_info_res(&msg->u.cell_info); + rc = _emm_as_cell_info_res(user, &msg->u.cell_info); break; case _EMMAS_CELL_INFO_IND: @@ -266,7 +264,7 @@ int emm_as_send(nas_user_t *user, const emm_as_t *msg) LOG_TRACE(WARNING, "EMMAS-SAP - Received EMM message is not valid " "(cause=%d)", emm_cause); /* Return an EMM status message */ - rc = emm_proc_status(ueid, emm_cause); + rc = emm_proc_status(user, ueid, emm_cause); } if (rc != RETURNok) { @@ -663,7 +661,7 @@ static int _emm_as_page_ind(const emm_as_page_t *msg) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_cell_info_res(const emm_as_cell_info_t *msg) +static int _emm_as_cell_info_res(nas_user_t *user, const emm_as_cell_info_t *msg) { LOG_FUNC_IN; @@ -685,7 +683,7 @@ static int _emm_as_cell_info_res(const emm_as_cell_info_t *msg) } /* Notify EMM that a cell has been found */ - rc = emm_proc_plmn_selection_end(msg->found, msg->tac, msg->cellID, AcT); + rc = emm_proc_plmn_selection_end(user, msg->found, msg->tac, msg->cellID, AcT); LOG_FUNC_RETURN (rc); } From 26538bb9e22df20416f8f4a1bd93e0f0fcdbc292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 19 Jul 2016 08:12:56 +0200 Subject: [PATCH 168/571] UE/API/USIM: move OP to usim_keys_t --- openair3/NAS/UE/API/USIM/aka_functions.c | 55 +++++++----------------- openair3/NAS/UE/API/USIM/aka_functions.h | 12 +++--- openair3/NAS/UE/API/USIM/usim_api.c | 20 +++++++-- openair3/NAS/UE/API/USIM/usim_api.h | 1 + 4 files changed, 38 insertions(+), 50 deletions(-) diff --git a/openair3/NAS/UE/API/USIM/aka_functions.c b/openair3/NAS/UE/API/USIM/aka_functions.c index 415ba695f2..68efb2b24a 100644 --- a/openair3/NAS/UE/API/USIM/aka_functions.c +++ b/openair3/NAS/UE/API/USIM/aka_functions.c @@ -39,26 +39,6 @@ #include "aka_functions.h" #include "nas_log.h" -/*--------- Operator Variant Algorithm Configuration Field --------*/ -/*------- Insert your value of OP here -------*/ -/* PFT OP used currently in HSS (OPENAIRHSS/auc/kdf.c) */ -#define OAI_LTEBOX - -#ifdef OAI_LTEBOX -//1006020f0a478bf6b699f15c062e42b3 -/*u8 OP[16] = {0xb3, 0x42, 0x2e, 0x06, 0x5c, 0xf1, 0x99, 0xb6, - 0xf6, 0x8b, 0x47, 0x0a, 0x0f, 0x02, 0x06, 0x10 - };*/ -u8 OP[16] = {0x10, 0x06, 0x02, 0x0f, 0x0a, 0x47, 0x8b, 0xf6, - 0xb6, 0x99, 0xf1, 0x5c, 0x06, 0x2e, 0x42, 0xb3 -}; -#else -u8 OP[16] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 - }; -#endif -/*------- Insert your value of OP here -------*/ - /*------------------------------------------------------------------- * Algorithm f1 *------------------------------------------------------------------- @@ -69,7 +49,7 @@ u8 OP[16] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, * *-----------------------------------------------------------------*/ void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], - u8 mac_a_pP[8] ) + u8 mac_a_pP[8], const u8 op[16]) { u8 op_c[16]; u8 temp[16]; @@ -78,7 +58,7 @@ void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); + ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -124,7 +104,7 @@ void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], * *-----------------------------------------------------------------*/ void f2345 ( u8 k_pP[16], u8 rand_pP[16], - u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6] ) + u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6],const u8 op[16]) { u8 op_c[16]; u8 temp[16]; @@ -142,7 +122,7 @@ void f2345 ( u8 k_pP[16], u8 rand_pP[16], rand_pP[8],rand_pP[9],rand_pP[10],rand_pP[11],rand_pP[12],rand_pP[13],rand_pP[14],rand_pP[15]); RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); + ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -225,7 +205,7 @@ void f2345 ( u8 k_pP[16], u8 rand_pP[16], * *-----------------------------------------------------------------*/ void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], - u8 mac_s_pP[8] ) + u8 mac_s_pP[8],const u8 op[16]) { u8 op_c[16]; u8 temp[16]; @@ -234,7 +214,7 @@ void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); + ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -280,7 +260,7 @@ void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], * *-----------------------------------------------------------------*/ void f5star( u8 k_pP[16], u8 rand_pP[16], - u8 ak_pP[6] ) + u8 ak_pP[6], const u8 op[16]) { u8 op_c[16]; u8 temp[16]; @@ -288,7 +268,7 @@ void f5star( u8 k_pP[16], u8 rand_pP[16], u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc( op_c ); + ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -316,22 +296,17 @@ void f5star( u8 k_pP[16], u8 rand_pP[16], * Function to compute OPc from OP and K. Assumes key schedule has already been performed. *-----------------------------------------------------------------*/ -void ComputeOPc( u8 op_c_pP[16] ) +void ComputeOPc(const u8 op[16], u8 op_c_pP[16]) { u8 i; LOG_TRACE(DEBUG, - "USIM-API - ComputeOPc : OP[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", - OP[0],OP[1],OP[2], OP[3], OP[4], OP[5], OP[6], OP[7], - OP[8],OP[9],OP[10],OP[11],OP[12],OP[13],OP[14],OP[15]); - RijndaelEncrypt( OP, op_c_pP ); + "USIM-API - ComputeOPc : op[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", + op[0],op[1],op[2], op[3], op[4], op[5], op[6], op[7], + op[8],op[9],op[10],op[11],op[12],op[13],op[14],op[15]); + RijndaelEncrypt( op, op_c_pP ); for (i=0; i<16; i++) - op_c_pP[i] ^= OP[i]; - LOG_TRACE(DEBUG, - "USIM-API - OPc[0..15]=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", - op_c_pP[0],op_c_pP[1],op_c_pP[2], op_c_pP[3], op_c_pP[4], op_c_pP[5], op_c_pP[6], op_c_pP[7], - op_c_pP[8],op_c_pP[9],op_c_pP[10],op_c_pP[11],op_c_pP[12],op_c_pP[13],op_c_pP[14],op_c_pP[15]); - + op_c_pP[i] ^= op[i]; return; } /* end of function ComputeOPc */ @@ -489,7 +464,7 @@ void MixColumn(u8 state[4][4]) * 16-byte output (using round keys already derived from 16-byte * key). *-----------------------------------------------------------------*/ -void RijndaelEncrypt( u8 input[16], u8 output[16] ) +void RijndaelEncrypt(const u8 input[16], u8 output[16] ) { u8 state[4][4]; int i, r; diff --git a/openair3/NAS/UE/API/USIM/aka_functions.h b/openair3/NAS/UE/API/USIM/aka_functions.h index 66b5a90fbc..8c370bb76c 100644 --- a/openair3/NAS/UE/API/USIM/aka_functions.h +++ b/openair3/NAS/UE/API/USIM/aka_functions.h @@ -23,13 +23,13 @@ typedef unsigned char u8; /*--------------------------- prototypes --------------------------*/ void f1 ( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], - u8 mac_a[8] ); + u8 mac_a[8], const u8 op[16]); void f2345 ( u8 k[16], u8 rand[16], - u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6] ); + u8 res[8], u8 ck[16], u8 ik[16], u8 ak[6], const u8 op[16]); void f1star( u8 k[16], u8 rand[16], u8 sqn[6], u8 amf[2], - u8 mac_s[8] ); + u8 mac_s[8], const u8 op[16]); void f5star( u8 k[16], u8 rand[16], - u8 ak[6] ); -void ComputeOPc( u8 op_c[16] ); + u8 ak[6], const u8 op[16]); +void ComputeOPc(const u8 op[16], u8 op_c_pP[16] ); void RijndaelKeySchedule( u8 key[16] ); -void RijndaelEncrypt( u8 input[16], u8 output[16] ); +void RijndaelEncrypt(const u8 input[16], u8 output[16] ); diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index fc362e2461..73aeda709d 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -112,6 +112,18 @@ int usim_api_read(usim_data_t* data) /* initialize the subscriber authentication security key */ _usim_api_hex_string_to_hex_value(data->keys.usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); + // initialize OP + /* PFT OP used currently in HSS (OPENAIRHSS/auc/kdf.c) */ + #define OAI_LTEBOX + + #ifdef OAI_LTEBOX + u8 _op[16] = {0x10, 0x06, 0x02, 0x0f, 0x0a, 0x47, 0x8b, 0xf6, + 0xb6, 0x99, 0xf1, 0x5c, 0x06, 0x2e, 0x42, 0xb3 }; + #else + u8 _op[16] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; + #endif + memcpy(data->keys.op, _op, sizeof(_op)); free(path); LOG_FUNC_RETURN (RETURNok); } @@ -387,7 +399,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co u8 ak[USIM_API_AK_SIZE]; f2345(usim_data->keys.usim_api_k, rand_pP->value, - res_pP->value, ck_pP->value, ik_pP->value, ak); + res_pP->value, ck_pP->value, ik_pP->value, ak, usim_data->keys.op); LOG_TRACE(INFO, "USIM-API - res(f2) :%s",dump_octet_string(res_pP)); LOG_TRACE(INFO, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP)); LOG_TRACE(INFO, "USIM-API - ik(f4) :%s",dump_octet_string(ik_pP)); @@ -408,7 +420,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co /* Compute XMAC = f1K (SQN || RAND || AMF) */ #define USIM_API_XMAC_SIZE 8 u8 xmac[USIM_API_XMAC_SIZE]; - f1(usim_data->keys.usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac); + f1(usim_data->keys.usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac, usim_data->keys.op); LOG_TRACE(DEBUG, "USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X", xmac[0],xmac[1],xmac[2],xmac[3], @@ -436,7 +448,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co /* Concealed value of the counter SQNms in the USIM: * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ - f5star(usim_data->keys.usim_api_k, rand_pP->value, ak); + f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.op); u8 sqn_ms[USIM_API_SQNMS_SIZE]; @@ -465,7 +477,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co #define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE u8 macs[USIM_API_MACS_SIZE]; f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms, - &rand_pP->value[USIM_API_SQN_SIZE], macs); + &rand_pP->value[USIM_API_SQN_SIZE], macs, usim_data->keys.op); LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X", macs[0],macs[1],macs[2],macs[3], macs[4],macs[5],macs[6],macs[7]); diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index 5939de019f..9114150396 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -113,6 +113,7 @@ typedef struct { #define USIM_IK_SIZE 16 Byte_t ik[USIM_IK_SIZE]; uint8_t usim_api_k[USIM_API_K_SIZE]; + uint8_t op[16]; } usim_keys_t; /* From 5ab2fccf2f47323c897008b30f60d744e8617a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 19 Jul 2016 08:41:30 +0200 Subject: [PATCH 169/571] UE/API/USER: rename _user_data to user_at_commands_t and move it to nas_user_t --- openair3/NAS/UE/API/USER/user_api.c | 33 ++++++++++++----------------- openair3/NAS/UE/API/USER/user_api.h | 15 +++++++++++-- openair3/NAS/UE/UEprocess.c | 1 + openair3/NAS/UE/nas_ue_task.c | 6 ++++++ openair3/NAS/UE/nas_user.c | 4 ++-- openair3/NAS/UE/user_defs.h | 3 +++ 6 files changed, 38 insertions(+), 24 deletions(-) diff --git a/openair3/NAS/UE/API/USER/user_api.c b/openair3/NAS/UE/API/USER/user_api.c index dd5b5758f1..9fa6ebc0a9 100644 --- a/openair3/NAS/UE/API/USER/user_api.c +++ b/openair3/NAS/UE/API/USER/user_api.c @@ -110,23 +110,16 @@ static struct { * The buffer used to receive data from the user application layer */ #define USER_API_RECV_BUFFER_SIZE 4096 +// FIXME not reentrant static char _user_api_recv_buffer[USER_API_RECV_BUFFER_SIZE]; /* * The buffer used to send data to the user application layer */ #define USER_API_SEND_BUFFER_SIZE USER_API_RECV_BUFFER_SIZE +// FIXME not reentrant static char _user_api_send_buffer[USER_API_SEND_BUFFER_SIZE]; -/* - * The decoded data received from the user application layer - */ -static struct { - int n_cmd; /* number of user data to be processed */ -#define USER_DATA_MAX 10 - at_command_t cmd[USER_DATA_MAX]; /* user data to be processed */ -} _user_data = {}; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -261,12 +254,12 @@ int user_api_get_fd(void) ** Others: None ** ** ** ***************************************************************************/ -const void* user_api_get_data(int index) +const void* user_api_get_data(user_at_commands_t *commands, int index) { LOG_FUNC_IN; - if (index < _user_data.n_cmd) { - LOG_FUNC_RETURN ((void*)(&_user_data.cmd[index])); + if (index < commands->n_cmd) { + LOG_FUNC_RETURN ((void*)(&commands->cmd[index])); } LOG_FUNC_RETURN (NULL); @@ -458,22 +451,22 @@ void user_api_close(int fd) ** Others: _user_api_send_buffer, _user_data ** ** ** ***************************************************************************/ -int user_api_decode_data(int length) +int user_api_decode_data(user_at_commands_t *commands, int length) { LOG_FUNC_IN; /* Parse the AT command line */ LOG_TRACE(INFO, "USR-API - Decode user data: %s", _user_api_recv_buffer); - _user_data.n_cmd = at_command_decode(_user_api_recv_buffer, length, - _user_data.cmd); + commands->n_cmd = at_command_decode(_user_api_recv_buffer, length, + commands->cmd); - if (_user_data.n_cmd > 0) { + if (commands->n_cmd > 0) { /* AT command data received from the user application layer * has been successfully decoded */ LOG_TRACE(INFO, "USR-API - %d AT command%s ha%s been successfully " - "decoded", _user_data.n_cmd, - (_user_data.n_cmd > 1) ? "s" : "", - (_user_data.n_cmd > 1) ? "ve" : "s"); + "decoded", commands->n_cmd, + (commands->n_cmd > 1) ? "s" : "", + (commands->n_cmd > 1) ? "ve" : "s"); } else { int bytes; @@ -490,7 +483,7 @@ int user_api_decode_data(int length) (void) _user_api_send_data(bytes); } - LOG_FUNC_RETURN (_user_data.n_cmd); + LOG_FUNC_RETURN (commands->n_cmd); } /**************************************************************************** diff --git a/openair3/NAS/UE/API/USER/user_api.h b/openair3/NAS/UE/API/USER/user_api.h index 9597c0f1d1..b3325417c6 100644 --- a/openair3/NAS/UE/API/USER/user_api.h +++ b/openair3/NAS/UE/API/USER/user_api.h @@ -42,6 +42,7 @@ Description Implements the API used by the NAS layer running in the UE #include "commonDef.h" #include "networkDef.h" +#include "at_command.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -51,6 +52,16 @@ Description Implements the API used by the NAS layer running in the UE /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +/* + * The decoded data received from the user application layer + */ +typedef struct { + int n_cmd; /* number of user data to be processed */ +#define USER_DATA_MAX 10 + at_command_t cmd[USER_DATA_MAX]; /* user data to be processed */ +} user_at_commands_t; + + /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -65,14 +76,14 @@ int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char int user_api_esm_callback(int cid, network_pdn_state_t state); int user_api_get_fd(void); -const void* user_api_get_data(int index); +const void* user_api_get_data(user_at_commands_t *commands, int index); int user_api_read_data(int fd); int user_api_set_data(char *message); int user_api_send_data(int fd, int length); void user_api_close(int fd); -int user_api_decode_data(int length); +int user_api_decode_data(user_at_commands_t *commands, int length); int user_api_encode_data(const void* data, int add_success_code); #endif /* __USER_API_H__ */ diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index aa96a97b73..18756fe4b4 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -74,6 +74,7 @@ static void _nas_clean(int usr_fd, int net_fd); uint8_t usim_test = 0; // FIXME user must be set up with right itti message instance +// FIXME allocate user and initialize its fields nas_user_t *user = NULL; /****************************************************************************/ diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 8373a6f15b..ece175bd05 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -88,6 +88,12 @@ void *nas_ue_task(void *args_p) itti_subscribe_event_fd (TASK_NAS_UE, user->fd); } + user->user_at_commands = calloc(1, sizeof(user_at_commands_t)); + if ( user->user_at_commands == NULL ) { + LOG_E(NAS, "[UE %d] Can't allocate memory for user_at_commands\n", 0); + // FIXME stop here + } + user->at_response = calloc(1, sizeof(at_response_t)); if ( user->at_response == NULL ) { LOG_E(NAS, "[UE %d] Can't allocate memory for user_at_commands\n", 0); diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index ef95fd052a..36ba0b7706 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -239,11 +239,11 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) } /* Decode the user data message */ - nb_command = user_api_decode_data (bytes); + nb_command = user_api_decode_data (user->user_at_commands, bytes); for (i = 0; i < nb_command; i++) { /* Get the user data to be processed */ - const void *data = user_api_get_data (i); + const void *data = user_api_get_data (user->user_at_commands, i); if (data == NULL) { /* Failed to get user data at the given index; diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 0661543047..00e713a7d3 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -53,6 +53,7 @@ Description NAS type definition to manage a user equipment #include "EMM/Authentication.h" #include "EMM/IdleMode_defs.h" #include "API/USIM/usim_api.h" +#include "API/USER/user_api.h" #include "SecurityModeControl.h" #include "userDef.h" #include "at_response.h" @@ -77,6 +78,8 @@ typedef struct { // nas_user_context_t *nas_user_context; at_response_t *at_response; // data structure returned to the user as the result of NAS procedure function call + // + user_at_commands_t *user_at_commands; //decoded data received from the user application layer } nas_user_t; #endif From 53fa94785ac2dad424e24d56dce8be874686bda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 19 Jul 2016 09:09:40 +0200 Subject: [PATCH 170/571] UE/EMM: remove extern definitions for timers --- openair3/NAS/UE/EMM/Attach.c | 9 ++++----- openair3/NAS/UE/EMM/Authentication.c | 19 ++++++------------- openair3/NAS/UE/EMM/Detach.c | 11 ++++------- openair3/NAS/UE/EMM/ServiceRequestHdl.c | 7 +------ openair3/NAS/UE/EMM/TrackingAreaUpdate.c | 6 +----- openair3/NAS/UE/EMM/emm_timers.h | 14 ++++++++++++++ openair3/NAS/UE/ESM/esm_ip.c | 1 + 7 files changed, 31 insertions(+), 36 deletions(-) create mode 100644 openair3/NAS/UE/EMM/emm_timers.h diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index b47b8cea8b..12be189d9b 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -59,6 +59,7 @@ Description Defines the attach related EMM procedure executed by the #include "nas_timer.h" #include "emmData.h" +#include "emm_timers.h" #include "emm_sap.h" #include "esm_sap.h" @@ -90,9 +91,7 @@ static const char *_emm_attach_type_str[] = { /* * Timer handlers */ -void *_emm_attach_t3410_handler(void *); -static void *_emm_attach_t3411_handler(void *); -static void *_emm_attach_t3402_handler(void *); +static void *_emm_attach_t3411_handler(void *args); /* * Abnormal case attach procedure @@ -251,7 +250,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) } /* Start T3410 timer */ - emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, _emm_attach_t3410_handler, user); + emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, emm_attach_t3410_handler, user); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in %ld seconds", emm_timers->T3410.id, emm_timers->T3410.sec); /* Stop T3402 and T3411 timers if running */ @@ -991,7 +990,7 @@ int emm_proc_attach_set_detach(void *nas_user) ** Others: T3410 ** ** ** ***************************************************************************/ -void *_emm_attach_t3410_handler(void *args) +void *emm_attach_t3410_handler(void *args) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index cee8553113..cb448388f7 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -59,9 +59,11 @@ Description Defines the authentication EMM procedure executed by the #include "nas_timer.h" #include "emmData.h" +#include "emm_timers.h" #include "emm_sap.h" #include "emm_cause.h" +#include "emm_timers.h" #include "usim_api.h" #include "secu_defs.h" @@ -72,15 +74,6 @@ Description Defines the authentication EMM procedure executed by the /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -/* - * Retransmission timer handlers - */ -// FIXME REVIEW -extern void *_emm_attach_t3410_handler(void *); -extern void *_emm_service_t3417_handler(void *); -extern void *_emm_detach_t3421_handler(void *); -extern void *_emm_tau_t3430_handler(void *); - extern uint8_t usim_test; /****************************************************************************/ @@ -876,28 +869,28 @@ static int _authentication_start_timers(nas_user_t *user) if (authentication_data->timers & AUTHENTICATION_T3410) { /* Start attach timer */ - emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, _emm_attach_t3410_handler, NULL); + emm_timers->T3410.id = nas_timer_start(emm_timers->T3410.sec, emm_attach_t3410_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3410 (%d) expires in " "%ld seconds", emm_timers->T3410.id, emm_timers->T3410.sec); } if (authentication_data->timers & AUTHENTICATION_T3417) { /* Start service request timer */ - emm_timers->T3417.id = nas_timer_start(emm_timers->T3417.sec, _emm_service_t3417_handler, NULL); + emm_timers->T3417.id = nas_timer_start(emm_timers->T3417.sec, emm_service_t3417_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3417 (%d) expires in " "%ld seconds", emm_timers->T3417.id, emm_timers->T3417.sec); } if (authentication_data->timers & AUTHENTICATION_T3421) { /* Start detach timer */ - emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, _emm_detach_t3421_handler, NULL); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, emm_detach_t3421_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3421 (%d) expires in " "%ld seconds", emm_timers->T3421.id, emm_timers->T3421.sec); } if (authentication_data->timers & AUTHENTICATION_T3430) { /* Start tracking area update timer */ - emm_timers->T3430.id = nas_timer_start(emm_timers->T3430.sec, _emm_tau_t3430_handler, NULL); + emm_timers->T3430.id = nas_timer_start(emm_timers->T3430.sec, emm_tau_t3430_handler, NULL); LOG_TRACE(INFO,"EMM-PROC - Timer T3430 (%d) expires in " "%ld seconds", emm_timers->T3430.id, emm_timers->T3430.sec); } diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index 44fbe95181..58148205a3 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -49,6 +49,7 @@ Description Defines the detach related EMM procedure executed by the #include "nas_timer.h" #include "emmData.h" +#include "emm_timers.h" #include "emm_sap.h" #include "esm_sap.h" @@ -75,10 +76,6 @@ static const char *_emm_detach_type_str[] = { * Internal data handled by the detach procedure in the UE * -------------------------------------------------------------------------- */ -/* - * Timer handlers - */ -void *_emm_detach_t3421_handler(void *); /* * Abnormal case detach procedures @@ -196,7 +193,7 @@ int emm_proc_detach_request(void *args) if ( !emm_detach_data->switch_off ) { /* Start T3421 timer */ - emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, _emm_detach_t3421_handler, user); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld seconds", emm_timers->T3421.id, emm_timers->T3421.sec); } @@ -372,7 +369,7 @@ int emm_proc_detach_release(void *args) ** Others: None ** ** ** ***************************************************************************/ -void *_emm_detach_t3421_handler(void *args) +void *emm_detach_t3421_handler(void *args) { LOG_FUNC_IN; @@ -419,7 +416,7 @@ void *_emm_detach_t3421_handler(void *args) if (rc != RETURNerror) { /* Start T3421 timer */ - emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, _emm_detach_t3421_handler, user); + emm_timers->T3421.id = nas_timer_start(emm_timers->T3421.sec, emm_detach_t3421_handler, user); LOG_TRACE(INFO, "EMM-PROC - Timer T3421 (%d) expires in %ld " "seconds", emm_timers->T3421.id, emm_timers->T3421.sec); } diff --git a/openair3/NAS/UE/EMM/ServiceRequestHdl.c b/openair3/NAS/UE/EMM/ServiceRequestHdl.c index 65df01b114..93e66efdbd 100644 --- a/openair3/NAS/UE/EMM/ServiceRequestHdl.c +++ b/openair3/NAS/UE/EMM/ServiceRequestHdl.c @@ -67,11 +67,6 @@ Description Defines the service request EMM procedure executed by the * Internal data handled by the service request procedure in the UE * -------------------------------------------------------------------------- */ -/* - * Timer handlers - */ -void *_emm_service_t3417_handler(void *); - /* * -------------------------------------------------------------------------- * Internal data handled by the service request procedure in the MME @@ -109,7 +104,7 @@ void *_emm_service_t3417_handler(void *); ** Others: None ** ** ** ***************************************************************************/ -void *_emm_service_t3417_handler(void *args) +void *emm_service_t3417_handler(void *args) { LOG_FUNC_IN; nas_user_t *user = args; diff --git a/openair3/NAS/UE/EMM/TrackingAreaUpdate.c b/openair3/NAS/UE/EMM/TrackingAreaUpdate.c index 5fe732b22d..bafddaf317 100644 --- a/openair3/NAS/UE/EMM/TrackingAreaUpdate.c +++ b/openair3/NAS/UE/EMM/TrackingAreaUpdate.c @@ -67,10 +67,6 @@ Description Defines the tracking area update EMM procedure executed by the * Internal data handled by the tracking area update procedure in the UE * -------------------------------------------------------------------------- */ -/* - * Timer handlers - */ -void *_emm_tau_t3430_handler(void *); /* * -------------------------------------------------------------------------- @@ -110,7 +106,7 @@ void *_emm_tau_t3430_handler(void *); ** Others: None ** ** ** ***************************************************************************/ -void *_emm_tau_t3430_handler(void *args) +void *emm_tau_t3430_handler(void *args) { LOG_FUNC_IN; nas_user_t *user = args; diff --git a/openair3/NAS/UE/EMM/emm_timers.h b/openair3/NAS/UE/EMM/emm_timers.h new file mode 100644 index 0000000000..abf7c9ff87 --- /dev/null +++ b/openair3/NAS/UE/EMM/emm_timers.h @@ -0,0 +1,14 @@ +#ifndef EMM_TIMERS_H +#define EMM_TIMERS_H + +/* + * Retransmission timer handlers + */ + +void *emm_attach_t3410_handler(void *); +void *emm_service_t3417_handler(void *); +void *emm_detach_t3421_handler(void *); +void *emm_tau_t3430_handler(void *); + + +#endif diff --git a/openair3/NAS/UE/ESM/esm_ip.c b/openair3/NAS/UE/ESM/esm_ip.c index f21305a1a0..23d8ecce97 100644 --- a/openair3/NAS/UE/ESM/esm_ip.c +++ b/openair3/NAS/UE/ESM/esm_ip.c @@ -22,6 +22,7 @@ #include "emmData.h" #include "esmData.h" +// FIXME don't work for reentrant calls char ip_addr_str[100]; inline char *esm_data_get_ipv4_addr(const OctetString *ip_addr) From a99e1a95af4d7a4953409e2b26539993dac37b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Thu, 21 Jul 2016 15:37:00 +0200 Subject: [PATCH 171/571] API/USER: move _user_api_id to nas_user_t --- openair3/NAS/UE/API/USER/user_api.c | 143 +++++++----------- openair3/NAS/UE/API/USER/user_api.h | 32 ++-- openair3/NAS/UE/API/USER/user_api_defs.h | 45 ++++++ openair3/NAS/UE/API/USER/user_indication.c | 4 +- openair3/NAS/UE/API/USER/user_indication.h | 5 +- openair3/NAS/UE/EMM/IdleMode.c | 18 ++- openair3/NAS/UE/EMM/IdleMode.h | 2 +- .../EMM/SAP/EmmDeregisteredNoCellAvailable.c | 4 +- .../UE/EMM/SAP/EmmDeregisteredPlmnSearch.c | 6 +- .../NAS/UE/EMM/SAP/EmmRegisteredInitiated.c | 6 +- openair3/NAS/UE/EMM/emm_main.c | 6 +- openair3/NAS/UE/EMM/emm_main.h | 2 +- openair3/NAS/UE/EMM/emm_proc.h | 6 +- .../ESM/DedicatedEpsBearerContextActivation.c | 4 +- .../ESM/DefaultEpsBearerContextActivation.c | 4 +- .../NAS/UE/ESM/EpsBearerContextDeactivation.c | 6 +- openair3/NAS/UE/ESM/esm_ebr.c | 4 +- openair3/NAS/UE/ESM/esm_ebr.h | 4 +- openair3/NAS/UE/ESM/esm_ebr_context.c | 6 +- openair3/NAS/UE/UEprocess.c | 27 ++-- openair3/NAS/UE/nas_ue_task.c | 13 +- openair3/NAS/UE/nas_user.c | 7 +- openair3/NAS/UE/user_defs.h | 3 +- 23 files changed, 195 insertions(+), 162 deletions(-) create mode 100644 openair3/NAS/UE/API/USER/user_api_defs.h diff --git a/openair3/NAS/UE/API/USER/user_api.c b/openair3/NAS/UE/API/USER/user_api.c index 9fa6ebc0a9..c71b59b443 100644 --- a/openair3/NAS/UE/API/USER/user_api.c +++ b/openair3/NAS/UE/API/USER/user_api.c @@ -45,7 +45,6 @@ Description Implements the API used by the NAS layer running in the UE #include "device.h" #include "nas_user.h" -#include "at_command.h" #include "at_response.h" #include "at_error.h" #include "esm_ebr.h" @@ -69,42 +68,12 @@ Description Implements the API used by the NAS layer running in the UE /* * Asynchronous notification procedure handlers */ -static int _user_api_registration_handler(unsigned char id, const void* data, size_t size); -static int _user_api_location_handler(unsigned char id, const void* data, size_t size); -static int _user_api_network_handler(unsigned char id, const void* data, size_t size); -static int _user_api_pdn_connection_handler(unsigned char id, const void* data, size_t size); +static int _user_api_registration_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); +static int _user_api_location_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); +static int _user_api_network_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); +static int _user_api_pdn_connection_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size); -static int _user_api_send(at_response_t* data); - -/* ------------------- - * Connection endpoint - * ------------------- - * The connection endpoint is used to send/receive data to/from the - * user application layer. Its definition depends on the underlaying - * mechanism chosen to communicate (network socket, I/O terminal device). - * A connection endpoint is handled using an identifier, and functions - * used to retreive the file descriptor actually allocated by the system, - * to receive data, to send data, and to perform clean up when connection - * is shut down. - * Only one single end to end connection with the user is managed at a - * time. - */ -static struct { - /* Connection endpoint reference */ - void* endpoint; - /* Connection endpoint handlers */ - void* (*open) (int, const char*, const char*); - int (*getfd)(const void*); - ssize_t (*recv) (void*, char*, size_t); - ssize_t (*send) (const void*, const char*, size_t); - void (*close)(void*); -} _user_api_id; - -#define USER_API_OPEN(a, b, c) _user_api_id.open(a, b, c) -#define USER_API_GETFD() _user_api_id.getfd(_user_api_id.endpoint) -#define USER_API_RECV(a, b) _user_api_id.recv(_user_api_id.endpoint, a, b) -#define USER_API_SEND(a, b) _user_api_id.send(_user_api_id.endpoint, a, b) -#define USER_API_CLOSE() _user_api_id.close(_user_api_id.endpoint) +static int _user_api_send(user_api_id_t *user_api_id, at_response_t* data); /* * The buffer used to receive data from the user application layer @@ -141,7 +110,7 @@ static char _user_api_send_buffer[USER_API_SEND_BUFFER_SIZE]; ** Others: _user_api_id ** ** ** ***************************************************************************/ -int user_api_initialize(const char* host, const char* port, +int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char* port, const char* devname, const char* devparams) { LOG_FUNC_IN; @@ -150,35 +119,35 @@ int user_api_initialize(const char* host, const char* port, if (devname != NULL) { /* Initialize device handlers */ - _user_api_id.open = device_open; - _user_api_id.getfd = device_get_fd; - _user_api_id.recv = device_read; - _user_api_id.send = device_write; - _user_api_id.close = device_close; + user_api_id->open = device_open; + user_api_id->getfd = device_get_fd; + user_api_id->recv = device_read; + user_api_id->send = device_write; + user_api_id->close = device_close; /* Initialize communication channel */ - _user_api_id.endpoint = USER_API_OPEN(DEVICE, devname, devparams); + user_api_id->endpoint = user_api_id->open(DEVICE, devname, devparams); - if (_user_api_id.endpoint == NULL) { + if (user_api_id->endpoint == NULL) { LOG_TRACE(ERROR, "USR-API - Failed to open connection endpoint, " "%s", strerror(errno)); LOG_FUNC_RETURN (RETURNerror); } LOG_TRACE(INFO, "USR-API - User's communication device %d is OPENED " - "on %s/%s", user_api_get_fd(), _user_api_send_buffer, devname); + "on %s/%s", user_api_get_fd(user_api_id), _user_api_send_buffer, devname); } else { /* Initialize network socket handlers */ - _user_api_id.open = socket_udp_open; - _user_api_id.getfd = socket_get_fd; - _user_api_id.recv = socket_recv; - _user_api_id.send = socket_send; - _user_api_id.close = socket_close; + user_api_id->open = socket_udp_open; + user_api_id->getfd = socket_get_fd; + user_api_id->recv = socket_recv; + user_api_id->send = socket_send; + user_api_id->close = socket_close; /* Initialize communication channel */ - _user_api_id.endpoint = USER_API_OPEN(SOCKET_SERVER, host, port); + user_api_id->endpoint = user_api_id->open(SOCKET_SERVER, host, port); - if (_user_api_id.endpoint == NULL) { + if (user_api_id->endpoint == NULL) { const char* error = ( (errno < 0) ? gai_strerror(errno) : strerror(errno) ); LOG_TRACE(ERROR, "USR-API - Failed to open connection endpoint, " @@ -187,7 +156,7 @@ int user_api_initialize(const char* host, const char* port, } LOG_TRACE(INFO, "USR-API - User's UDP socket %d is BOUND to %s/%s", - user_api_get_fd(), _user_api_send_buffer, port); + user_api_get_fd(user_api_id), _user_api_send_buffer, port); } /* Register the asynchronous notification handlers */ @@ -232,10 +201,10 @@ int user_api_initialize(const char* host, const char* port, ** Others: None ** ** ** ***************************************************************************/ -int user_api_get_fd(void) +int user_api_get_fd(user_api_id_t *user_api_id) { LOG_FUNC_IN; - LOG_FUNC_RETURN (USER_API_GETFD()); + LOG_FUNC_RETURN (user_api_id->getfd(user_api_id->endpoint)); } /**************************************************************************** @@ -247,7 +216,6 @@ int user_api_get_fd(void) ** before its usage. ** ** ** ** Inputs: index: Index of the user data structure to get ** - ** Others: _user_data ** ** ** ** Outputs: Return: A generic pointer to the user data ** ** structure ** @@ -280,14 +248,14 @@ const void* user_api_get_data(user_at_commands_t *commands, int index) ** Others: _user_api_recv_buffer, _user_api_id ** ** ** ***************************************************************************/ -int user_api_read_data(int fd) +int user_api_read_data(user_api_id_t *user_api_id, int fd) { LOG_FUNC_IN; int rbytes; /* Sanity check */ - int sfd = user_api_get_fd(); + int sfd = user_api_get_fd(user_api_id); if (fd != sfd) { LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); @@ -297,7 +265,7 @@ int user_api_read_data(int fd) memset(_user_api_recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); /* Receive data from the user application layer */ - rbytes = USER_API_RECV(_user_api_recv_buffer, USER_API_RECV_BUFFER_SIZE); + rbytes = user_api_id->recv(user_api_id->endpoint, _user_api_recv_buffer, USER_API_RECV_BUFFER_SIZE); if (rbytes == RETURNerror) { LOG_TRACE(ERROR, "USR-API - recv() failed, %s", strerror(errno)); @@ -345,7 +313,7 @@ int user_api_set_data(char *message) /**************************************************************************** ** ** - ** Name: user_api_send_data() ** +** Name: user_api_send_data() ** ** ** ** Description: Send data to the user application layer ** ** ** @@ -359,9 +327,9 @@ int user_api_set_data(char *message) ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_send_data(int length) +static int _user_api_send_data(user_api_id_t *user_api_id, int length) { - int sbytes = USER_API_SEND(_user_api_send_buffer, length); + int sbytes = user_api_id->send(user_api_id->endpoint, _user_api_send_buffer, length); if (sbytes == RETURNerror) { LOG_TRACE(ERROR, "USR-API - send() failed, %s", strerror(errno)); @@ -376,12 +344,12 @@ static int _user_api_send_data(int length) return sbytes; } -int user_api_send_data(int fd, int length) +int user_api_send_data(user_api_id_t *user_api_id, int fd, int length) { LOG_FUNC_IN; /* Sanity check */ - int sfd = user_api_get_fd(); + int sfd = user_api_get_fd(user_api_id); if (fd != sfd) { LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); @@ -392,7 +360,7 @@ int user_api_send_data(int fd, int length) int sbytes = 0; if (length > 0) { - sbytes = _user_api_send_data(length); + sbytes = _user_api_send_data(user_api_id, length); } LOG_FUNC_RETURN (sbytes); @@ -414,12 +382,12 @@ int user_api_send_data(int fd, int length) ** Others: _user_api_id ** ** ** ***************************************************************************/ -void user_api_close(int fd) +void user_api_close(user_api_id_t *user_api_id, int fd) { LOG_FUNC_IN; /* Sanity check */ - int sfd = user_api_get_fd(); + int sfd = user_api_get_fd(user_api_id); if (fd != sfd) { LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); @@ -428,8 +396,8 @@ void user_api_close(int fd) } /* Cleanup the connection endpoint */ - USER_API_CLOSE(); - _user_api_id.endpoint = NULL; + user_api_id->close(user_api_id->endpoint) ; + user_api_id->endpoint = NULL; LOG_FUNC_OUT; } @@ -451,7 +419,7 @@ void user_api_close(int fd) ** Others: _user_api_send_buffer, _user_data ** ** ** ***************************************************************************/ -int user_api_decode_data(user_at_commands_t *commands, int length) +int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length) { LOG_FUNC_IN; @@ -479,8 +447,9 @@ int user_api_decode_data(user_at_commands_t *commands, int length) bytes = at_error_encode(_user_api_send_buffer, AT_ERROR_SYNTAX, AT_ERROR_OPERATION_NOT_SUPPORTED); + // FIXME move _user_data call /* Send the syntax error code message */ - (void) _user_api_send_data(bytes); + _user_api_send_data(user_api_id, bytes); } LOG_FUNC_RETURN (commands->n_cmd); @@ -561,7 +530,7 @@ int user_api_encode_data(const void* data, int success_code) ** Others: None ** ** ** ***************************************************************************/ -int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, +int user_api_emm_callback(user_api_id_t *user_api_id, Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char* data, size_t size) { LOG_FUNC_IN; @@ -573,14 +542,14 @@ int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, * The list of available operators present in the network has to be * displayed to the user application */ - rc = user_ind_notify(USER_IND_PLMN, (void*)data, size); + rc = user_ind_notify(user_api_id, USER_IND_PLMN, (void*)data, size); } else { user_indication_t ind; ind.notification.reg.status = stat; if (size > 0) { /* The UE's network registration status has changed */ - rc = user_ind_notify(USER_IND_REG, (void*)&ind, 0); + rc = user_ind_notify(user_api_id, USER_IND_REG, (void*)&ind, 0); } if (rc != RETURNerror) { @@ -590,7 +559,7 @@ int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, ind.notification.loc.tac = tac; ind.notification.loc.ci = ci; ind.notification.loc.AcT = AcT; - rc = user_ind_notify(USER_IND_LOC, (void*)&ind, 0); + rc = user_ind_notify(user_api_id, USER_IND_LOC, (void*)&ind, 0); } } @@ -618,7 +587,7 @@ int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, ** Others: None ** ** ** ***************************************************************************/ -int user_api_esm_callback(int cid, network_pdn_state_t state) +int user_api_esm_callback(user_api_id_t *user_api_id, int cid, network_pdn_state_t state) { LOG_FUNC_IN; @@ -628,7 +597,7 @@ int user_api_esm_callback(int cid, network_pdn_state_t state) ind.notification.pdn.cid = cid; ind.notification.pdn.status = state; /* The status of the specified PDN connection has changed */ - rc = user_ind_notify(USER_IND_PDN, (void*)&ind, 0); + rc = user_ind_notify(user_api_id, USER_IND_PDN, (void*)&ind, 0); LOG_FUNC_RETURN (rc); } @@ -651,7 +620,7 @@ int user_api_esm_callback(int cid, network_pdn_state_t state) ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_send(at_response_t* data) +static int _user_api_send(user_api_id_t *user_api_id, at_response_t* data) { LOG_FUNC_IN; @@ -660,7 +629,7 @@ static int _user_api_send(at_response_t* data) /* Send the AT command response message to the user application */ if (bytes != RETURNerror) { - bytes = _user_api_send_data(bytes); + bytes = _user_api_send_data(user_api_id, bytes); } LOG_FUNC_RETURN (bytes); @@ -687,7 +656,7 @@ static int _user_api_send(at_response_t* data) ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_registration_handler(unsigned char id, const void* data, +static int _user_api_registration_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -704,7 +673,7 @@ static int _user_api_registration_handler(unsigned char id, const void* data, at_response.response.cereg.stat = reg->status; /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } @@ -729,7 +698,7 @@ static int _user_api_registration_handler(unsigned char id, const void* data, ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_location_handler(unsigned char id, const void* data, +static int _user_api_location_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -753,7 +722,7 @@ static int _user_api_location_handler(unsigned char id, const void* data, } /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } @@ -776,7 +745,7 @@ static int _user_api_location_handler(unsigned char id, const void* data, ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_network_handler(unsigned char id, const void* data, +static int _user_api_network_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -789,7 +758,7 @@ static int _user_api_network_handler(unsigned char id, const void* data, at_response.response.cops.tst.size = size; /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } @@ -814,7 +783,7 @@ static int _user_api_network_handler(unsigned char id, const void* data, ** Others: None ** ** ** ***************************************************************************/ -static int _user_api_pdn_connection_handler(unsigned char id, const void* data, +static int _user_api_pdn_connection_handler(user_api_id_t *user_api_id, unsigned char id, const void* data, size_t size) { LOG_FUNC_IN; @@ -831,7 +800,7 @@ static int _user_api_pdn_connection_handler(unsigned char id, const void* data, at_response.response.cgev.code = pdn->status; /* Encode and send the AT command response message to the user */ - int bytes = _user_api_send(&at_response); + int bytes = _user_api_send(user_api_id, &at_response); LOG_FUNC_RETURN (bytes); } diff --git a/openair3/NAS/UE/API/USER/user_api.h b/openair3/NAS/UE/API/USER/user_api.h index b3325417c6..06e489b2bf 100644 --- a/openair3/NAS/UE/API/USER/user_api.h +++ b/openair3/NAS/UE/API/USER/user_api.h @@ -43,25 +43,13 @@ Description Implements the API used by the NAS layer running in the UE #include "commonDef.h" #include "networkDef.h" #include "at_command.h" +#include "user_api_defs.h" +#include "user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* - * The decoded data received from the user application layer - */ -typedef struct { - int n_cmd; /* number of user data to be processed */ -#define USER_DATA_MAX 10 - at_command_t cmd[USER_DATA_MAX]; /* user data to be processed */ -} user_at_commands_t; - - /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ @@ -70,20 +58,20 @@ typedef struct { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int user_api_initialize(const char* host, const char* port, const char* devname, const char* devparams); +int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char* port, const char* devname, const char* devparams); -int user_api_emm_callback(Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char* data, size_t size); -int user_api_esm_callback(int cid, network_pdn_state_t state); +int user_api_emm_callback(user_api_id_t *user_api_id, Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char* data, size_t size); +int user_api_esm_callback(user_api_id_t *user_api_id, int cid, network_pdn_state_t state); -int user_api_get_fd(void); +int user_api_get_fd(user_api_id_t *user_api_id); const void* user_api_get_data(user_at_commands_t *commands, int index); -int user_api_read_data(int fd); +int user_api_read_data(user_api_id_t *user_api_id, int fd); int user_api_set_data(char *message); -int user_api_send_data(int fd, int length); -void user_api_close(int fd); +int user_api_send_data(user_api_id_t *user_api_id, int fd, int length); +void user_api_close(user_api_id_t *user_api_id, int fd); -int user_api_decode_data(user_at_commands_t *commands, int length); +int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length); int user_api_encode_data(const void* data, int add_success_code); #endif /* __USER_API_H__ */ diff --git a/openair3/NAS/UE/API/USER/user_api_defs.h b/openair3/NAS/UE/API/USER/user_api_defs.h new file mode 100644 index 0000000000..9c43bf36f3 --- /dev/null +++ b/openair3/NAS/UE/API/USER/user_api_defs.h @@ -0,0 +1,45 @@ +#ifndef _USER_API_DEFS_H +#define _USER_API_DEFS_H + +#include +#include "at_command.h" + +/****************************************************************************/ +/************************ G L O B A L T Y P E S ************************/ +/****************************************************************************/ + +/* + * The decoded data received from the user application layer + */ +typedef struct { + int n_cmd; /* number of user data to be processed */ +#define USER_DATA_MAX 10 + at_command_t cmd[USER_DATA_MAX]; /* user data to be processed */ +} user_at_commands_t; + +/* ------------------- + * Connection endpoint + * ------------------- + * The connection endpoint is used to send/receive data to/from the + * user application layer. Its definition depends on the underlaying + * mechanism chosen to communicate (network socket, I/O terminal device). + * A connection endpoint is handled using an identifier, and functions + * used to retreive the file descriptor actually allocated by the system, + * to receive data, to send data, and to perform clean up when connection + * is shut down. + * Only one single end to end connection with the user is managed at a + * time. + */ +typedef struct { + /* Connection endpoint reference */ + void* endpoint; + /* Connection endpoint handlers */ + void* (*open) (int, const char*, const char*); + int (*getfd)(const void*); + ssize_t (*recv) (void*, char*, size_t); + ssize_t (*send) (const void*, const char*, size_t); + void (*close)(void*); +} user_api_id_t; + + +#endif diff --git a/openair3/NAS/UE/API/USER/user_indication.c b/openair3/NAS/UE/API/USER/user_indication.c index d7495f46e7..620596005d 100644 --- a/openair3/NAS/UE/API/USER/user_indication.c +++ b/openair3/NAS/UE/API/USER/user_indication.c @@ -146,7 +146,7 @@ int user_ind_deregister(user_ind_t ind) ** Others: None ** ** ** ***************************************************************************/ -int user_ind_notify(user_ind_t ind, const void* data, size_t size) +int user_ind_notify(user_api_id_t *user_api_id, user_ind_t ind, const void* data, size_t size) { LOG_FUNC_IN; @@ -158,7 +158,7 @@ int user_ind_notify(user_ind_t ind, const void* data, size_t size) user_ind_callback_t notify = _user_ind_handler.callback[ind]; if (notify != NULL) { - rc = (*notify)(_user_ind_handler.id, data, size); + rc = (*notify)(user_api_id, _user_ind_handler.id, data, size); } } else { /* Silently discard not registered notification */ diff --git a/openair3/NAS/UE/API/USER/user_indication.h b/openair3/NAS/UE/API/USER/user_indication.h index d31a8754e4..39aba424e7 100644 --- a/openair3/NAS/UE/API/USER/user_indication.h +++ b/openair3/NAS/UE/API/USER/user_indication.h @@ -43,6 +43,7 @@ Description Defines functions which allow the user application to register #include "commonDef.h" #include "networkDef.h" +#include "user_api_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -101,7 +102,7 @@ typedef struct { /* * Type of procedure executed upon receiving registered notification */ -typedef int (*user_ind_callback_t) (unsigned char, const void*, size_t); +typedef int (*user_ind_callback_t) (user_api_id_t *user_api_id, unsigned char, const void*, size_t); /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ @@ -117,6 +118,6 @@ typedef int (*user_ind_callback_t) (unsigned char, const void*, size_t); int user_ind_register(user_ind_t ind, unsigned char id, user_ind_callback_t cb); int user_ind_deregister(user_ind_t ind); -int user_ind_notify(user_ind_t ind, const void* data, size_t size); +int user_ind_notify(user_api_id_t *user_api_id, user_ind_t ind, const void* data, size_t size); #endif /* __USER_IND_H__*/ diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index efecf7d321..8cff0b4ca5 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -594,6 +594,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) { LOG_FUNC_IN; emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; int rc = RETURNok; @@ -613,7 +614,7 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) * list of available PLMNs to the user */ index = -1; - rc = emm_proc_network_notify(emm_plmn_list, emm_data, emm_plmn_list->hplmn); + rc = emm_proc_network_notify(emm_plmn_list, user_api_id, emm_data, emm_plmn_list->hplmn); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify " @@ -685,6 +686,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, int rc = RETURNerror; emm_data_t *emm_data = user->emm_data; emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; + user_api_id_t *user_api_id = user->user_api_id; int index = emm_plmn_list->index; int select_next_plmn = FALSE; @@ -706,7 +708,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, emm_plmn_list->param[index].rat = rat; /* Update the location data and notify EMM that data have changed */ - rc = emm_proc_location_notify(emm_data, tac, ci , rat); + rc = emm_proc_location_notify(user_api_id, emm_data, tac, ci , rat); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-IDLE - Failed to notify location update"); @@ -934,7 +936,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status) +int emm_proc_registration_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, Stat_t status) { LOG_FUNC_IN; @@ -944,7 +946,7 @@ int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status) if (emm_data->stat != status) { emm_data->stat = status; /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(emm_data, 1); + rc = (*_emm_indication_notify)(user_api_id, emm_data, 1); } LOG_FUNC_RETURN (rc); @@ -968,7 +970,7 @@ int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status) ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat) +int emm_proc_location_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat) { LOG_FUNC_IN; @@ -982,7 +984,7 @@ int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat emm_data->ci = ci; emm_data->rat = rat; /* Notify EMM that data has changed */ - rc = (*_emm_indication_notify)(emm_data, 0); + rc = (*_emm_indication_notify)(user_api_id, emm_data, 0); } LOG_FUNC_RETURN (rc); @@ -1005,14 +1007,14 @@ int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat ** Others: user->emm_data-> ** ** ** ***************************************************************************/ -int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int index) +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, user_api_id_t *user_api_id, emm_data_t *emm_data, int index) { LOG_FUNC_IN; /* Update the list of operators present in the network */ int size = IdleMode_update_plmn_list(emm_plmn_list, emm_data, index); /* Notify EMM that data has changed */ - int rc = (*_emm_indication_notify)(emm_data, size); + int rc = (*_emm_indication_notify)(user_api_id, emm_data, size); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/IdleMode.h b/openair3/NAS/UE/EMM/IdleMode.h index e92e14f5cb..e80b4f9134 100644 --- a/openair3/NAS/UE/EMM/IdleMode.h +++ b/openair3/NAS/UE/EMM/IdleMode.h @@ -51,7 +51,7 @@ Description Defines the functions used to get information from the list /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ -typedef int (*IdleMode_callback_t) (emm_data_t *emm_data, int); +typedef int (*IdleMode_callback_t) (user_api_id_t *user_api_id, emm_data_t *emm_data, int); /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c index 0ea25dbe5f..af9ab5e5be 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c @@ -89,6 +89,8 @@ int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) LOG_FUNC_IN; int rc = RETURNerror; + emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; assert(emm_fsm_get_status(user) == EMM_DEREGISTERED_NO_CELL_AVAILABLE); @@ -108,7 +110,7 @@ int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *evt) * Notify EMM that the MT is currently searching an operator * to register to */ - rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_ON); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_ON); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c index bcf089e3cc..ed41362f2f 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredPlmnSearch.c @@ -85,6 +85,8 @@ Description Implements the EPS Mobility Management procedures executed int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) { LOG_FUNC_IN; + emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; int rc = RETURNerror; @@ -95,7 +97,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) /* * No suitable cell of the selected PLMN has been found to camp on */ - rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_DENIED); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_DENIED); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -112,7 +114,7 @@ int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *evt) * may be selected either automatically or manually. * Or the user manually re-selected a PLMN to register to. */ - rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_ON); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_ON); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index 1072e31319..c0d5f50ebc 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -83,6 +83,8 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) LOG_FUNC_IN; int rc = RETURNerror; + emm_data_t *emm_data = user->emm_data; + user_api_id_t *user_api_id = user->user_api_id; assert(emm_fsm_get_status(user) == EMM_REGISTERED_INITIATED); @@ -140,7 +142,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) /* * Notify EMM that the MT is registered */ - rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_HN); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_HN); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " @@ -167,7 +169,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) /* * Notify EMM that the MT's registration is denied */ - rc = emm_proc_registration_notify(user->emm_data, NET_REG_STATE_DENIED); + rc = emm_proc_registration_notify(user_api_id, emm_data, NET_REG_STATE_DENIED); if (rc != RETURNok) { LOG_TRACE(WARNING, "EMM-FSM - " diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 5b6a44909e..7ec228d963 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -74,7 +74,7 @@ static int _emm_main_get_plmn_index(emm_plmn_list_t *emm_plmn_list, const char * * to the user application */ static emm_indication_callback_t _emm_main_user_callback; -static int _emm_main_callback(emm_data_t *emm_data, int); +static int _emm_main_callback(user_api_id_t *user_api_id, emm_data_t *emm_data, int size); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -881,12 +881,12 @@ int emm_main_is_emergency(emm_data_t *emm_data) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_main_callback(emm_data_t *emm_data, int size) +static int _emm_main_callback(user_api_id_t *user_api_id, emm_data_t *emm_data, int size) { LOG_FUNC_IN; /* Forward the notification to the user API */ - int rc = (*_emm_main_user_callback)(emm_data->stat, emm_data->tac, + int rc = (*_emm_main_user_callback)(user_api_id, emm_data->stat, emm_data->tac, emm_data->ci, emm_data->rat, emm_data->plist.buffer, size); diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index fe574f6d3d..1885a42469 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -57,7 +57,7 @@ Description Defines the EPS Mobility Management procedure call manager, * location change, new PLMN becomes available) is notified by the * EPS Mobility Management sublayer */ -typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, +typedef int (*emm_indication_callback_t) (user_api_id_t *user_api_id, Stat_t, tac_t, ci_t, AcT_t, const char*, size_t); /****************************************************************************/ diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index ca307b3f3a..333343b6ca 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -156,8 +156,8 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, in * Network indication handlers *--------------------------------------------------------------------------- */ -int emm_proc_registration_notify(emm_data_t *emm_data, Stat_t status); -int emm_proc_location_notify(emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat); -int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, int index); +int emm_proc_registration_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, Stat_t status); +int emm_proc_location_notify(user_api_id_t *user_api_id, emm_data_t *emm_data, tac_t tac, ci_t ci, AcT_t rat); +int emm_proc_network_notify(emm_plmn_list_t *emm_plmn_list, user_api_id_t *user_api_id, emm_data_t *emm_data, int index); #endif /* __EMM_PROC_H__*/ diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index c96a40a1b8..068ec2aef0 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -212,6 +212,8 @@ int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standa LOG_FUNC_IN; int rc; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_TRACE(INFO,"ESM-PROC - Dedicated EPS bearer context activation " "accepted by the UE (ebi=%d)", ebi); @@ -229,7 +231,7 @@ int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standa if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ - rc = esm_ebr_set_status(user->esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in ACTIVE state */ diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 02d5671808..92ae9dcd99 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -181,6 +181,8 @@ int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalo LOG_FUNC_IN; int rc = RETURNok; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_TRACE(INFO,"ESM-PROC - Default EPS bearer context activation " "accepted by the UE (ebi=%d)", ebi); @@ -200,7 +202,7 @@ int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalo if (rc != RETURNerror) { /* Set the EPS bearer context state to ACTIVE */ - rc = esm_ebr_set_status(user->esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_ACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in ACTIVE state */ diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index c92ce2c582..0ffb683bf1 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -282,6 +282,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand int rc = RETURNok; esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_TRACE(INFO,"ESM-PROC - EPS bearer context deactivation accepted"); @@ -299,7 +300,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand if (rc != RETURNerror) { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(esm_ebr_data, ebi, ESM_EBR_INACTIVE, ue_triggered); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, ue_triggered); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ @@ -359,6 +360,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) int rc = RETURNerror; esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; /* Release the EPS bearer context entry */ ebi = esm_ebr_context_release(user, ebi, pid, bid); @@ -367,7 +369,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); } else { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(esm_ebr_data, ebi, ESM_EBR_INACTIVE, FALSE); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, FALSE); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 81d3ff3270..1cf1d4a4e5 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -294,7 +294,7 @@ int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -int esm_ebr_set_status(esm_ebr_data_t *esm_ebr_data, +int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested) { esm_ebr_context_t *ebr_ctx; @@ -329,7 +329,7 @@ int esm_ebr_set_status(esm_ebr_data_t *esm_ebr_data, /* * Notify the user that the state of the EPS bearer has changed */ - (*_esm_ebr_callback)(ebr_ctx->cid, + (*_esm_ebr_callback)(user_api_id, ebr_ctx->cid, _esm_ebr_pdn_state[ue_requested][ebr_ctx->is_default_ebr][status]); LOG_FUNC_RETURN (RETURNok); } diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h index adc10de0c4..8e1eaee1a4 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.h +++ b/openair3/NAS/UE/ESM/esm_ebr.h @@ -63,7 +63,7 @@ Description Defines functions used to handle state of EPS bearer contexts * respect of PDN connection or EPS bearer context is notified by the EPS * Session Management sublayer */ -typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); +typedef int (*esm_indication_callback_t) (user_api_id_t *user_api_id, int, network_pdn_state_t); /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ @@ -81,7 +81,7 @@ esm_ebr_data_t *esm_ebr_initialize(void); int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr); int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_set_status(esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested); +int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested); esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi); int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi); diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 1f7707c5c3..4ce201260a 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -331,6 +331,8 @@ int esm_ebr_context_release(nas_user_t *user, int found = FALSE; esm_pdn_t *pdn = NULL; esm_data_context_t *esm_ctx; + esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; + user_api_id_t *user_api_id = user->user_api_id; LOG_FUNC_IN; @@ -448,11 +450,11 @@ int esm_ebr_context_release(nas_user_t *user, } /* Set the EPS bearer context state to INACTIVE */ - esm_ebr_set_status(user->esm_ebr_data, pdn->bearer[i]->ebi, + esm_ebr_set_status(user_api_id, esm_ebr_data, pdn->bearer[i]->ebi, ESM_EBR_INACTIVE, TRUE); /* Release EPS bearer data */ - esm_ebr_release(user->esm_ebr_data, pdn->bearer[i]->ebi); + esm_ebr_release(esm_ebr_data, pdn->bearer[i]->ebi); // esm_ebr_release() /* Release dedicated EPS bearer data */ diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 18756fe4b4..122ee72f6e 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -70,7 +70,7 @@ static void *_nas_network_mngr(void *); static int _nas_set_signal_handler(int signal, void (handler)(int)); static void _nas_signal_handler(int signal); -static void _nas_clean(int usr_fd, int net_fd); +static void _nas_clean(user_api_id_t *user_api_id, int usr_fd, int net_fd); uint8_t usim_test = 0; // FIXME user must be set up with right itti message instance @@ -84,6 +84,8 @@ nas_user_t *user = NULL; /****************************************************************************/ int main(int argc, const char *argv[]) { + // FIXME allocate and put it in user + user_api_id_t *user_api_id = NULL; /* * Get the command line options */ @@ -112,19 +114,19 @@ int main(int argc, const char *argv[]) /* * Initialize the User interface */ - if (user_api_initialize (uhost, uport, devpath, devparams) != RETURNok) { + if (user_api_initialize (user_api_id, uhost, uport, devpath, devparams) != RETURNok) { LOG_TRACE (ERROR, "UE-MAIN - user_api_initialize() failed"); exit (EXIT_FAILURE); } - int user_fd = user_api_get_fd (); + int user_fd = user_api_get_fd (user_api_id); /* * Initialize the Network interface */ if (network_api_initialize (nhost, nport) != RETURNok) { LOG_TRACE (ERROR, "UE-MAIN - network_api_initialize() failed"); - user_api_close (user_fd); + user_api_close (user_api_id, user_fd); exit (EXIT_FAILURE); } @@ -161,7 +163,7 @@ int main(int argc, const char *argv[]) if (pthread_create (&user_mngr, &attr, _nas_user_mngr, &user_fd) != 0) { LOG_TRACE (ERROR, "UE-MAIN - " "Failed to create the user management thread"); - user_api_close (user_fd); + user_api_close (user_api_id, user_fd); network_api_close (network_fd); exit (EXIT_FAILURE); } @@ -175,7 +177,7 @@ int main(int argc, const char *argv[]) &network_fd) != 0) { LOG_TRACE (ERROR, "UE-MAIN - " "Failed to create the network management thread"); - user_api_close (user_fd); + user_api_close (user_api_id, user_fd); network_api_close (network_fd); exit (EXIT_FAILURE); } @@ -188,12 +190,12 @@ int main(int argc, const char *argv[]) */ while ((user_fd != -1) && (network_fd != -1)) { poll (NULL, 0, NAS_SLEEP_TIMEOUT); - user_fd = user_api_get_fd (); + user_fd = user_api_get_fd (user_api_id); network_fd = network_api_get_fd (); } /* Termination cleanup */ - _nas_clean (user_fd, network_fd); + _nas_clean (user_api_id, user_fd, network_fd); LOG_TRACE (WARNING, "UE-MAIN - NAS main process exited"); @@ -234,7 +236,7 @@ static void *_nas_user_mngr(void *args) } /* Close the connection to the user application layer */ - user_api_close (*fd); + user_api_close (user->user_api_id, *fd); LOG_TRACE (WARNING, "UE-MAIN - " "The user connection endpoint manager exited"); @@ -383,7 +385,8 @@ static void _nas_signal_handler(int signal) LOG_FUNC_IN; LOG_TRACE (WARNING, "UE-MAIN - Signal %d received", signal); - _nas_clean (user_api_get_fd (), network_api_get_fd ()); + // FIXME acces to global + _nas_clean (user->user_api_id, user_api_get_fd (user->user_api_id), network_api_get_fd ()); exit (EXIT_SUCCESS); LOG_FUNC_OUT @@ -404,7 +407,7 @@ static void _nas_signal_handler(int signal) ** Others: None ** ** ** ***************************************************************************/ -static void _nas_clean(int usr_fd, int net_fd) +static void _nas_clean(user_api_id_t *user_api_id, int usr_fd, int net_fd) { LOG_FUNC_IN; @@ -416,7 +419,7 @@ static void _nas_clean(int usr_fd, int net_fd) LOG_TRACE (INFO, "UE-MAIN - " "Closing user connection %d and network connection %d", usr_fd, net_fd); - user_api_close (usr_fd); + user_api_close (user_api_id, usr_fd); network_api_close (net_fd); LOG_FUNC_OUT diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index ece175bd05..53b0520933 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -78,13 +78,22 @@ void *nas_ue_task(void *args_p) { /* Initialize user interface (to exchange AT commands with user process) */ { - if (user_api_initialize (NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL, + user_api_id_t *user_api_id = calloc(1, sizeof(user_api_id_t)); + + if (user_api_id == NULL) { + LOG_E(NAS, "[UE] Failed to alloc user_api_id_t"); + // FIXME stop here + } + + user->user_api_id = user_api_id; + + if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL, NULL) != RETURNok) { LOG_E(NAS, "[UE] user interface initialization failed!"); exit (EXIT_FAILURE); } - user->fd = user_api_get_fd (); + user->fd = user_api_get_fd (user_api_id); itti_subscribe_event_fd (TASK_NAS_UE, user->fd); } diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 36ba0b7706..da55b3bbf1 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -216,13 +216,14 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) int nb_command; int bytes; int i; + user_api_id_t *user_api_id = user->user_api_id; if (message != NULL) { /* Set the message in receive buffer (Use to simulate reception of data from UserProcess) */ bytes = user_api_set_data(message); } else { /* Read the user data message */ - bytes = user_api_read_data (user->fd); + bytes = user_api_read_data (user_api_id, user->fd); if (bytes == RETURNerror) { /* Failed to read data from the user application layer; @@ -239,7 +240,7 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) } /* Decode the user data message */ - nb_command = user_api_decode_data (user->user_at_commands, bytes); + nb_command = user_api_decode_data (user_api_id, user->user_at_commands, bytes); for (i = 0; i < nb_command; i++) { /* Get the user data to be processed */ @@ -278,7 +279,7 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) } /* Send the data message to the user */ - bytes = user_api_send_data (user->fd, bytes); + bytes = user_api_send_data (user_api_id, user->fd, bytes); if (bytes == RETURNerror) { /* Failed to send data to the user application layer; diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 00e713a7d3..c92a5a9388 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -53,7 +53,7 @@ Description NAS type definition to manage a user equipment #include "EMM/Authentication.h" #include "EMM/IdleMode_defs.h" #include "API/USIM/usim_api.h" -#include "API/USER/user_api.h" +#include "API/USER/user_api_defs.h" #include "SecurityModeControl.h" #include "userDef.h" #include "at_response.h" @@ -80,6 +80,7 @@ typedef struct { at_response_t *at_response; // data structure returned to the user as the result of NAS procedure function call // user_at_commands_t *user_at_commands; //decoded data received from the user application layer + user_api_id_t *user_api_id; } nas_user_t; #endif From e6daacf7eab8ce5a943b160bc7dcb31c9f399761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 10:22:40 +0200 Subject: [PATCH 172/571] UE/API/USER: move _user_api_*_buffer to user_api_id_t --- openair3/NAS/UE/API/USER/user_api.c | 68 +++++++++--------------- openair3/NAS/UE/API/USER/user_api.h | 4 +- openair3/NAS/UE/API/USER/user_api_defs.h | 7 ++- openair3/NAS/UE/nas_user.c | 4 +- 4 files changed, 34 insertions(+), 49 deletions(-) diff --git a/openair3/NAS/UE/API/USER/user_api.c b/openair3/NAS/UE/API/USER/user_api.c index c71b59b443..21e4eacf9d 100644 --- a/openair3/NAS/UE/API/USER/user_api.c +++ b/openair3/NAS/UE/API/USER/user_api.c @@ -75,20 +75,6 @@ static int _user_api_pdn_connection_handler(user_api_id_t *user_api_id, unsigned static int _user_api_send(user_api_id_t *user_api_id, at_response_t* data); -/* - * The buffer used to receive data from the user application layer - */ -#define USER_API_RECV_BUFFER_SIZE 4096 -// FIXME not reentrant -static char _user_api_recv_buffer[USER_API_RECV_BUFFER_SIZE]; - -/* - * The buffer used to send data to the user application layer - */ -#define USER_API_SEND_BUFFER_SIZE USER_API_RECV_BUFFER_SIZE -// FIXME not reentrant -static char _user_api_send_buffer[USER_API_SEND_BUFFER_SIZE]; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -115,7 +101,7 @@ int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char { LOG_FUNC_IN; - gethostname(_user_api_send_buffer, USER_API_SEND_BUFFER_SIZE); + gethostname(user_api_id->send_buffer, USER_API_SEND_BUFFER_SIZE); if (devname != NULL) { /* Initialize device handlers */ @@ -135,7 +121,7 @@ int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char } LOG_TRACE(INFO, "USR-API - User's communication device %d is OPENED " - "on %s/%s", user_api_get_fd(user_api_id), _user_api_send_buffer, devname); + "on %s/%s", user_api_get_fd(user_api_id), user_api_id->send_buffer, devname); } else { /* Initialize network socket handlers */ user_api_id->open = socket_udp_open; @@ -156,7 +142,7 @@ int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char } LOG_TRACE(INFO, "USR-API - User's UDP socket %d is BOUND to %s/%s", - user_api_get_fd(user_api_id), _user_api_send_buffer, port); + user_api_get_fd(user_api_id), user_api_id->send_buffer, port); } /* Register the asynchronous notification handlers */ @@ -245,7 +231,7 @@ const void* user_api_get_data(user_at_commands_t *commands, int index) ** ** ** Outputs: Return: The number of bytes read when success; ** ** RETURNerror Otherwise ** - ** Others: _user_api_recv_buffer, _user_api_id ** + ** Others: user_api_id->recv_buffer, _user_api_id ** ** ** ***************************************************************************/ int user_api_read_data(user_api_id_t *user_api_id, int fd) @@ -262,10 +248,10 @@ int user_api_read_data(user_api_id_t *user_api_id, int fd) LOG_FUNC_RETURN (RETURNerror); } - memset(_user_api_recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); + memset(user_api_id->recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); /* Receive data from the user application layer */ - rbytes = user_api_id->recv(user_api_id->endpoint, _user_api_recv_buffer, USER_API_RECV_BUFFER_SIZE); + rbytes = user_api_id->recv(user_api_id->endpoint, user_api_id->recv_buffer, USER_API_RECV_BUFFER_SIZE); if (rbytes == RETURNerror) { LOG_TRACE(ERROR, "USR-API - recv() failed, %s", strerror(errno)); @@ -275,7 +261,7 @@ int user_api_read_data(user_api_id_t *user_api_id, int fd) } else { LOG_TRACE(INFO, "USR-API - %d bytes received " "from the user application layer", rbytes); - LOG_DUMP(_user_api_recv_buffer, rbytes); + LOG_DUMP(user_api_id->recv_buffer, rbytes); } LOG_FUNC_RETURN (rbytes); @@ -291,22 +277,22 @@ int user_api_read_data(user_api_id_t *user_api_id, int fd) ** ** ** Outputs: Return: The number of bytes write when success; ** ** RETURNerror Otherwise ** - ** Others: _user_api_recv_buffer ** + ** Others: user_api_id->recv_buffer ** ** ** ***************************************************************************/ -int user_api_set_data(char *message) +int user_api_set_data(user_api_id_t *user_api_id, char *message) { LOG_FUNC_IN; int rbytes; - memset(_user_api_recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); + memset(user_api_id->recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); - strncpy(_user_api_recv_buffer, message, USER_API_RECV_BUFFER_SIZE); - rbytes = strlen(_user_api_recv_buffer); + strncpy(user_api_id->recv_buffer, message, USER_API_RECV_BUFFER_SIZE); + rbytes = strlen(user_api_id->recv_buffer); LOG_TRACE(INFO, "USR-API - %d bytes write", rbytes); - LOG_DUMP(_user_api_recv_buffer, rbytes); + LOG_DUMP(user_api_id->recv_buffer, rbytes); LOG_FUNC_RETURN (rbytes); } @@ -320,7 +306,6 @@ int user_api_set_data(char *message) ** Inputs: fd: File descriptor of the connection endpoint ** ** to which data have to be sent ** ** length: Number of bytes to send ** - ** Others: _user_api_send_buffer, _user_api_id ** ** ** ** Outputs: Return: The number of bytes sent when success; ** ** RETURNerror Otherwise ** @@ -329,7 +314,7 @@ int user_api_set_data(char *message) ***************************************************************************/ static int _user_api_send_data(user_api_id_t *user_api_id, int length) { - int sbytes = user_api_id->send(user_api_id->endpoint, _user_api_send_buffer, length); + int sbytes = user_api_id->send(user_api_id->endpoint, user_api_id->send_buffer, length); if (sbytes == RETURNerror) { LOG_TRACE(ERROR, "USR-API - send() failed, %s", strerror(errno)); @@ -339,7 +324,7 @@ static int _user_api_send_data(user_api_id_t *user_api_id, int length) } else { LOG_TRACE(INFO, "USR-API - %d bytes sent " "to the user application layer", sbytes); - LOG_DUMP(_user_api_send_buffer, sbytes); + LOG_DUMP(user_api_id->send_buffer, sbytes); } return sbytes; @@ -379,7 +364,6 @@ int user_api_send_data(user_api_id_t *user_api_id, int fd, int length) ** Others: None ** ** ** ** Outputs: Return: None ** - ** Others: _user_api_id ** ** ** ***************************************************************************/ void user_api_close(user_api_id_t *user_api_id, int fd) @@ -412,11 +396,9 @@ void user_api_close(user_api_id_t *user_api_id, int fd) ** layer when the AT command failed to be decoded. ** ** ** ** Inputs: length: Number of bytes to decode ** - ** Others: _user_api_recv_buffer ** ** ** ** Outputs: Return: The number of AT commands succeessfully ** ** decoded ** - ** Others: _user_api_send_buffer, _user_data ** ** ** ***************************************************************************/ int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length) @@ -424,8 +406,8 @@ int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *command LOG_FUNC_IN; /* Parse the AT command line */ - LOG_TRACE(INFO, "USR-API - Decode user data: %s", _user_api_recv_buffer); - commands->n_cmd = at_command_decode(_user_api_recv_buffer, length, + LOG_TRACE(INFO, "USR-API - Decode user data: %s", user_api_id->recv_buffer); + commands->n_cmd = at_command_decode(user_api_id->recv_buffer, length, commands->cmd); if (commands->n_cmd > 0) { @@ -441,10 +423,10 @@ int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *command /* Failed to decode AT command data received from the user * application layer; Return syntax error code message */ LOG_TRACE(ERROR, "USR-API - Syntax error: Failed to decode " - "AT command data %s", _user_api_recv_buffer); + "AT command data %s", user_api_id->recv_buffer); /* Encode the syntax error code message */ - bytes = at_error_encode(_user_api_send_buffer, AT_ERROR_SYNTAX, + bytes = at_error_encode(user_api_id->send_buffer, AT_ERROR_SYNTAX, AT_ERROR_OPERATION_NOT_SUPPORTED); // FIXME move _user_data call @@ -471,10 +453,9 @@ int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *command ** Outputs: Return: The number of characters that have been ** ** successfully encoded; ** ** RETURNerror otherwise. ** - ** Others: _user_api_send_buffer ** ** ** ***************************************************************************/ -int user_api_encode_data(const void* data, int success_code) +int user_api_encode_data(user_api_id_t *user_api_id, const void* data, int success_code) { LOG_FUNC_IN; @@ -483,16 +464,16 @@ int user_api_encode_data(const void* data, int success_code) /* Encode AT command error message */ if (user_data->cause_code != AT_ERROR_SUCCESS) { - bytes = at_error_encode(_user_api_send_buffer, AT_ERROR_CME, + bytes = at_error_encode(user_api_id->send_buffer, AT_ERROR_CME, user_data->cause_code); } /* Encode AT command response message */ else { - bytes = at_response_encode(_user_api_send_buffer, user_data); + bytes = at_response_encode(user_api_id->send_buffer, user_data); /* Add success result code */ if ( (success_code) && (bytes != RETURNerror) ) { - bytes += at_error_encode(&_user_api_send_buffer[bytes], + bytes += at_error_encode(&user_api_id->send_buffer[bytes], AT_ERROR_OK, 0); } } @@ -613,7 +594,6 @@ int user_api_esm_callback(user_api_id_t *user_api_id, int cid, network_pdn_state ** Description: Encodes and sends data to the user application layer ** ** ** ** Inputs: data: The data to send ** - ** Others: _user_api_send_buffer, _user_api_id ** ** ** ** Outputs: Return: The number of bytes sent when success; ** ** RETURNerror Otherwise ** @@ -625,7 +605,7 @@ static int _user_api_send(user_api_id_t *user_api_id, at_response_t* data) LOG_FUNC_IN; /* Encode AT command response message */ - int bytes = at_response_encode(_user_api_send_buffer, data); + int bytes = at_response_encode(user_api_id->send_buffer, data); /* Send the AT command response message to the user application */ if (bytes != RETURNerror) { diff --git a/openair3/NAS/UE/API/USER/user_api.h b/openair3/NAS/UE/API/USER/user_api.h index 06e489b2bf..513a44e4fb 100644 --- a/openair3/NAS/UE/API/USER/user_api.h +++ b/openair3/NAS/UE/API/USER/user_api.h @@ -67,11 +67,11 @@ int user_api_get_fd(user_api_id_t *user_api_id); const void* user_api_get_data(user_at_commands_t *commands, int index); int user_api_read_data(user_api_id_t *user_api_id, int fd); -int user_api_set_data(char *message); +int user_api_set_data(user_api_id_t *user_api_id, char *message); int user_api_send_data(user_api_id_t *user_api_id, int fd, int length); void user_api_close(user_api_id_t *user_api_id, int fd); int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length); -int user_api_encode_data(const void* data, int add_success_code); +int user_api_encode_data(user_api_id_t *user_api_id, const void* data, int add_success_code); #endif /* __USER_API_H__ */ diff --git a/openair3/NAS/UE/API/USER/user_api_defs.h b/openair3/NAS/UE/API/USER/user_api_defs.h index 9c43bf36f3..ef4d8cd383 100644 --- a/openair3/NAS/UE/API/USER/user_api_defs.h +++ b/openair3/NAS/UE/API/USER/user_api_defs.h @@ -8,12 +8,15 @@ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ +#define USER_API_RECV_BUFFER_SIZE 4096 +#define USER_API_SEND_BUFFER_SIZE USER_API_RECV_BUFFER_SIZE +#define USER_DATA_MAX 10 + /* * The decoded data received from the user application layer */ typedef struct { int n_cmd; /* number of user data to be processed */ -#define USER_DATA_MAX 10 at_command_t cmd[USER_DATA_MAX]; /* user data to be processed */ } user_at_commands_t; @@ -39,6 +42,8 @@ typedef struct { ssize_t (*recv) (void*, char*, size_t); ssize_t (*send) (const void*, const char*, size_t); void (*close)(void*); + char recv_buffer[USER_API_RECV_BUFFER_SIZE]; + char send_buffer[USER_API_SEND_BUFFER_SIZE]; } user_api_id_t; diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index da55b3bbf1..065bbca17d 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -220,7 +220,7 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) if (message != NULL) { /* Set the message in receive buffer (Use to simulate reception of data from UserProcess) */ - bytes = user_api_set_data(message); + bytes = user_api_set_data(user_api_id, message); } else { /* Read the user data message */ bytes = user_api_read_data (user_api_id, user->fd); @@ -270,7 +270,7 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) /* Send response to UserProcess (If not in simulated reception) */ if (message == NULL) { /* Encode the user data message */ - bytes = user_api_encode_data (nas_user_get_data (user), i == nb_command - 1); + bytes = user_api_encode_data (user->user_api_id, nas_user_get_data (user), i == nb_command - 1); if (bytes == RETURNerror) { /* Failed to encode the user data message; From c7a36ec6d26c46f099368353fae541a12a16824e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 10:45:46 +0200 Subject: [PATCH 173/571] UE/EMM/LowerLayer: move ueid to nas_user_t --- openair3/NAS/UE/EMM/LowerLayer.c | 22 +++++++++------------- openair3/NAS/UE/EMM/LowerLayer.h | 9 ++++----- openair3/NAS/UE/EMM/SAP/emm_as.c | 10 +++++----- openair3/NAS/UE/EMM/SAP/emm_esm.c | 2 +- openair3/NAS/UE/nas_ue_task.c | 1 + openair3/NAS/UE/user_defs.h | 1 + 6 files changed, 21 insertions(+), 24 deletions(-) diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c index ab1d5c6cf8..2d67cf6417 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.c +++ b/openair3/NAS/UE/EMM/LowerLayer.c @@ -88,7 +88,6 @@ static struct { ** Description: Notify the EPS Mobility Management entity that data have ** ** been successfully delivered to the network ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** @@ -96,7 +95,7 @@ static struct { ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_success(nas_user_t *user, unsigned int ueid) +int lowerlayer_success(nas_user_t *user) { LOG_FUNC_IN; @@ -104,7 +103,7 @@ int lowerlayer_success(nas_user_t *user, unsigned int ueid) int rc; emm_sap.primitive = EMMREG_LOWERLAYER_SUCCESS; - emm_sap.u.emm_reg.ueid = ueid; + emm_sap.u.emm_reg.ueid = user->ueid; rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); @@ -117,7 +116,6 @@ int lowerlayer_success(nas_user_t *user, unsigned int ueid) ** Description: Notify the EPS Mobility Management entity that lower la- ** ** yers failed to deliver data to the network ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** @@ -125,7 +123,7 @@ int lowerlayer_success(nas_user_t *user, unsigned int ueid) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_failure(nas_user_t *user, unsigned int ueid) +int lowerlayer_failure(nas_user_t *user) { LOG_FUNC_IN; @@ -133,7 +131,7 @@ int lowerlayer_failure(nas_user_t *user, unsigned int ueid) int rc; emm_sap.primitive = EMMREG_LOWERLAYER_FAILURE; - emm_sap.u.emm_reg.ueid = ueid; + emm_sap.u.emm_reg.ueid = user->ueid; rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); @@ -191,7 +189,7 @@ int lowerlayer_release(nas_user_t *user, int cause) user->emm_data->ecm_status = ECM_IDLE; emm_sap.primitive = EMMREG_LOWERLAYER_RELEASE; - emm_sap.u.emm_reg.ueid = 0; + emm_sap.u.emm_reg.ueid = user->ueid; rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); @@ -204,7 +202,6 @@ int lowerlayer_release(nas_user_t *user, int cause) ** Description: Notify the EPS Session Management entity that data have ** ** been received from lower layers ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** data: Data transfered from lower layers ** ** Others: None ** ** ** @@ -213,7 +210,7 @@ int lowerlayer_release(nas_user_t *user, int cause) ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_ind(nas_user_t *user, unsigned int ueid, const OctetString *data) +int lowerlayer_data_ind(nas_user_t *user, const OctetString *data) { esm_sap_t esm_sap; int rc; @@ -223,7 +220,7 @@ int lowerlayer_data_ind(nas_user_t *user, unsigned int ueid, const OctetString * esm_sap.primitive = ESM_UNITDATA_IND; esm_sap.is_standalone = TRUE; - esm_sap.ueid = ueid; + esm_sap.ueid = user->ueid; esm_sap.recv = data; rc = esm_sap_send(user, &esm_sap); @@ -238,7 +235,6 @@ int lowerlayer_data_ind(nas_user_t *user, unsigned int ueid, const OctetString * ** Description: Notify the EPS Mobility Management entity that data have ** ** to be transfered to lower layers ** ** ** - ** Inputs: ueid: UE lower layer identifier ** ** data: Data to be transfered to lower layers ** ** Others: None ** ** ** @@ -247,7 +243,7 @@ int lowerlayer_data_ind(nas_user_t *user, unsigned int ueid, const OctetString * ** Others: None ** ** ** ***************************************************************************/ -int lowerlayer_data_req(nas_user_t *user, unsigned int ueid, const OctetString *data) +int lowerlayer_data_req(nas_user_t *user, const OctetString *data) { LOG_FUNC_IN; @@ -258,7 +254,7 @@ int lowerlayer_data_req(nas_user_t *user, unsigned int ueid, const OctetString * emm_sap.primitive = EMMAS_DATA_REQ; emm_sap.u.emm_as.u.data.guti = user->emm_data->guti; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; sctx = user->emm_data->security; emm_sap.u.emm_as.u.data.NASinfo = 0; diff --git a/openair3/NAS/UE/EMM/LowerLayer.h b/openair3/NAS/UE/EMM/LowerLayer.h index 85229de686..019803936c 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.h +++ b/openair3/NAS/UE/EMM/LowerLayer.h @@ -79,13 +79,12 @@ typedef int (*lowerlayer_release_callback_t)(void *); /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -// FIXME prototype with ueid -int lowerlayer_success(nas_user_t *user, unsigned int ueid); -int lowerlayer_failure(nas_user_t *user, unsigned int ueid); +int lowerlayer_success(nas_user_t *user); +int lowerlayer_failure(nas_user_t *user); int lowerlayer_establish(nas_user_t *user); int lowerlayer_release(nas_user_t *user, int cause); -int lowerlayer_data_ind(nas_user_t *user, unsigned int ueid, const OctetString *data); -int lowerlayer_data_req(nas_user_t *user, unsigned int ueid, const OctetString *data); +int lowerlayer_data_ind(nas_user_t *user, const OctetString *data); +int lowerlayer_data_req(nas_user_t *user, const OctetString *data); #endif /* __LOWERLAYER_H__*/ diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 8c26b42818..49668d61ab 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -446,18 +446,18 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm EPS_SESSION_MANAGEMENT_MESSAGE) { const OctetString data = {bytes, (uint8_t *)plain_msg}; /* Foward ESM data to EPS session management */ - rc = lowerlayer_data_ind(user, msg->ueid, &data); + rc = lowerlayer_data_ind(user, &data); } free(plain_msg); } } else { /* Process successfull lower layer transfer indication */ - rc = lowerlayer_success(user, msg->ueid); + rc = lowerlayer_success(user); } } else { /* Process lower layer transmission failure of NAS message */ - rc = lowerlayer_failure(user, msg->ueid); + rc = lowerlayer_failure(user); } LOG_FUNC_RETURN (rc); @@ -496,7 +496,7 @@ static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg } else { /* The initial NAS message has been successfully delivered to * lower layers */ - rc = lowerlayer_success(user, 0); + rc = lowerlayer_success(user); LOG_FUNC_RETURN (rc); } @@ -571,7 +571,7 @@ static int _emm_as_establish_rej(nas_user_t *user) "failure"); /* Process lower layer transmission failure of initial NAS message */ - rc = lowerlayer_failure(user, 0); + rc = lowerlayer_failure(user); LOG_FUNC_RETURN (rc); } diff --git a/openair3/NAS/UE/EMM/SAP/emm_esm.c b/openair3/NAS/UE/EMM/SAP/emm_esm.c index b3a494ad49..798e682b11 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esm.c +++ b/openair3/NAS/UE/EMM/SAP/emm_esm.c @@ -149,7 +149,7 @@ int emm_esm_send(nas_user_t *user, const emm_esm_t *msg) case _EMMESM_UNITDATA_REQ: /* ESM requests EMM to transfer ESM data unit to lower layer */ - rc = lowerlayer_data_req(user, msg->ueid, &msg->u.data.msg); + rc = lowerlayer_data_req(user, &msg->u.data.msg); break; default: diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 53b0520933..2b41123446 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -71,6 +71,7 @@ void *nas_ue_task(void *args_p) nas_user_t user_value = {}; nas_user_t *user = &user_value; + user->ueid = 0; itti_mark_task_ready (TASK_NAS_UE); MSC_START_USE(); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index c92a5a9388..a30e13663a 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -59,6 +59,7 @@ Description NAS type definition to manage a user equipment #include "at_response.h" typedef struct { + int ueid; /* UE lower layer identifier */ int fd; proc_data_t proc; // Eps Session Management From 38d7adc7e34bd903e7e56f81fbd1c99c491fef89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 10:55:59 +0200 Subject: [PATCH 174/571] UE/*: fix ueid = 0 --- openair3/NAS/UE/EMM/Attach.c | 2 +- openair3/NAS/UE/EMM/Authentication.c | 4 ++-- openair3/NAS/UE/EMM/Detach.c | 4 ++-- openair3/NAS/UE/EMM/Identification.c | 2 +- openair3/NAS/UE/EMM/SAP/emm_as.c | 2 +- openair3/NAS/UE/EMM/SecurityModeControl.c | 2 +- openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c | 4 ++-- openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c | 5 ++--- openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c | 2 +- openair3/NAS/UE/ESM/EsmStatusHdl.c | 2 +- openair3/NAS/UE/ESM/PdnConnectivity.c | 4 ++-- openair3/NAS/UE/ESM/PdnDisconnect.c | 4 ++-- openair3/NAS/UE/nas_proc.c | 6 +++--- 13 files changed, 21 insertions(+), 22 deletions(-) diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 12be189d9b..d765ff0fa7 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -440,7 +440,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, */ emm_sap.primitive = EMMAS_DATA_REQ; emm_sap.u.emm_as.u.data.guti = user->emm_data->guti; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, user->emm_data->security, FALSE, TRUE); diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index cb448388f7..56ec2bd833 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -304,7 +304,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.emm_cause = EMM_CAUSE_SUCCESS; emm_sap.u.emm_as.u.security.res = &res; @@ -648,7 +648,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.emm_cause = emm_cause; emm_sap.u.emm_as.u.security.auts = auts; diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index 58148205a3..e59d8b7d94 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -151,7 +151,7 @@ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_of emm_as->switch_off = switch_off; /* Set the EPS mobile identity */ emm_as->guti = user->emm_data->guti; - emm_as->ueid = 0; + emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); @@ -402,7 +402,7 @@ void *emm_detach_t3421_handler(void *args) emm_as->switch_off = emm_detach_data->switch_off; /* Set the EPS mobile identity */ emm_as->guti = user->emm_data->guti; - emm_as->ueid = 0; + emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c index 53bc008cab..e894e9e045 100644 --- a/openair3/NAS/UE/EMM/Identification.c +++ b/openair3/NAS/UE/EMM/Identification.c @@ -195,7 +195,7 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t */ emm_sap.primitive = EMMAS_SECURITY_RES; emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 49668d61ab..dfe055f4d6 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -194,7 +194,7 @@ int emm_as_send(nas_user_t *user, const emm_as_t *msg) int emm_cause = EMM_CAUSE_SUCCESS; emm_as_primitive_t primitive = msg->primitive; - uint32_t ueid = 0; + uint32_t ueid = user->ueid; LOG_TRACE(INFO, "EMMAS-SAP - Received primitive %s (%d)", _emm_as_primitive_str[primitive - _EMMAS_START - 1], primitive); diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 5a90b43cde..43a5db1ff4 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -323,7 +323,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, emm_sap_t emm_sap; emm_sap.primitive = EMMAS_SECURITY_RES; emm_sap.u.emm_as.u.security.guti = user->emm_data->guti; - emm_sap.u.emm_as.u.security.ueid = 0; + emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_SMC; emm_sap.u.emm_as.u.security.imeisv_request = imeisv_request; emm_sap.u.emm_as.u.security.emm_cause = emm_cause; diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 068ec2aef0..3a32d3040d 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -224,7 +224,7 @@ int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standa * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); @@ -292,7 +292,7 @@ int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standa * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 92ae9dcd99..71421a475d 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -194,7 +194,7 @@ int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalo * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); @@ -269,8 +269,7 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - // FIXME REVIEW - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index 0ffb683bf1..6ba5e6e1cc 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -292,7 +292,7 @@ int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_stand * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/ESM/EsmStatusHdl.c b/openair3/NAS/UE/ESM/EsmStatusHdl.c index f42cdb02ae..4c8e0aafc1 100644 --- a/openair3/NAS/UE/ESM/EsmStatusHdl.c +++ b/openair3/NAS/UE/ESM/EsmStatusHdl.c @@ -176,7 +176,7 @@ int esm_proc_status(nas_user_t *user, int is_standalone, * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_sap.u.emm_esm.u.data.msg.length = msg->length; emm_sap.u.emm_esm.u.data.msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 15ec49b2d0..c51d08cdbc 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -296,7 +296,7 @@ int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int p * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); @@ -631,7 +631,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) * has to be sent again */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = data->msg.length; emm_esm->msg.value = data->msg.value; rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 445c0a6c34..4b5c0f06e5 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -183,7 +183,7 @@ int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti * Notity EMM that ESM PDU has to be forwarded to lower layers */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = msg->length; emm_esm->msg.value = msg->value; rc = emm_sap_send(user, &emm_sap); @@ -402,7 +402,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) * has to be sent again */ emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = 0; + emm_sap.u.emm_esm.ueid = user->ueid; emm_esm->msg.length = data->msg.length; emm_esm->msg.value = data->msg.value; rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index b77e112370..44d3201c4a 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -1185,7 +1185,7 @@ int nas_proc_ul_transfer_cnf(nas_user_t *user) * receiver side */ emm_sap.primitive = EMMAS_DATA_IND; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; emm_sap.u.emm_as.u.data.delivered = TRUE; emm_sap.u.emm_as.u.data.NASmsg.length = 0; rc = emm_sap_send(user, &emm_sap); @@ -1222,7 +1222,7 @@ int nas_proc_ul_transfer_rej(nas_user_t *user) * from lower layers */ emm_sap.primitive = EMMAS_DATA_IND; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; emm_sap.u.emm_as.u.data.delivered = FALSE; emm_sap.u.emm_as.u.data.NASmsg.length = 0; rc = emm_sap_send(user, &emm_sap); @@ -1259,7 +1259,7 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) * indication has been received from the Access-Stratum sublayer */ emm_sap.primitive = EMMAS_DATA_IND; - emm_sap.u.emm_as.u.data.ueid = 0; + emm_sap.u.emm_as.u.data.ueid = user->ueid; emm_sap.u.emm_as.u.data.delivered = TRUE; emm_sap.u.emm_as.u.data.NASmsg.length = len; emm_sap.u.emm_as.u.data.NASmsg.value = (uint8_t *)data; From 64e296ed6777c18d0a261f6f021bbb5576b233d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 11:11:19 +0200 Subject: [PATCH 175/571] UE/API/USER: remove fd from nas_user_t --- openair3/NAS/UE/API/USER/user_api.c | 43 ++++++----------------------- openair3/NAS/UE/API/USER/user_api.h | 6 ++-- openair3/NAS/UE/UEprocess.c | 20 +++++++------- openair3/NAS/UE/nas_ue_task.c | 5 ++-- openair3/NAS/UE/nas_user.c | 4 +-- openair3/NAS/UE/user_defs.h | 1 - 6 files changed, 25 insertions(+), 54 deletions(-) diff --git a/openair3/NAS/UE/API/USER/user_api.c b/openair3/NAS/UE/API/USER/user_api.c index 21e4eacf9d..a1300ea059 100644 --- a/openair3/NAS/UE/API/USER/user_api.c +++ b/openair3/NAS/UE/API/USER/user_api.c @@ -225,8 +225,6 @@ const void* user_api_get_data(user_at_commands_t *commands, int index) ** ** ** Description: Read data received from the user application layer ** ** ** - ** Inputs: fd: File descriptor of the connection endpoint ** - ** from which data have been received ** ** Others: _user_api_id ** ** ** ** Outputs: Return: The number of bytes read when success; ** @@ -234,20 +232,12 @@ const void* user_api_get_data(user_at_commands_t *commands, int index) ** Others: user_api_id->recv_buffer, _user_api_id ** ** ** ***************************************************************************/ -int user_api_read_data(user_api_id_t *user_api_id, int fd) +int user_api_read_data(user_api_id_t *user_api_id) { LOG_FUNC_IN; int rbytes; - /* Sanity check */ - int sfd = user_api_get_fd(user_api_id); - - if (fd != sfd) { - LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); - LOG_FUNC_RETURN (RETURNerror); - } - memset(user_api_id->recv_buffer, 0, USER_API_RECV_BUFFER_SIZE); /* Receive data from the user application layer */ @@ -303,8 +293,6 @@ int user_api_set_data(user_api_id_t *user_api_id, char *message) ** ** ** Description: Send data to the user application layer ** ** ** - ** Inputs: fd: File descriptor of the connection endpoint ** - ** to which data have to be sent ** ** length: Number of bytes to send ** ** ** ** Outputs: Return: The number of bytes sent when success; ** @@ -329,18 +317,15 @@ static int _user_api_send_data(user_api_id_t *user_api_id, int length) return sbytes; } -int user_api_send_data(user_api_id_t *user_api_id, int fd, int length) + +/**************************************************************************** + ** ** + ** Name: user_api_close() ** + ***************************************************************************/ + int user_api_send_data(user_api_id_t *user_api_id, int length) { LOG_FUNC_IN; - /* Sanity check */ - int sfd = user_api_get_fd(user_api_id); - - if (fd != sfd) { - LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); - LOG_FUNC_RETURN (RETURNerror); - } - /* Send data to the user application layer */ int sbytes = 0; @@ -358,27 +343,15 @@ int user_api_send_data(user_api_id_t *user_api_id, int fd, int length) ** Description: Close the user API from which the NAS layer sent/received ** ** messages to/from the user application layer ** ** ** - ** Inputs: fd: File descriptor of the connection endpoint ** - ** allocated by the system to communicate ** - ** with the user application layer ** ** Others: None ** ** ** ** Outputs: Return: None ** ** ** ***************************************************************************/ -void user_api_close(user_api_id_t *user_api_id, int fd) +void user_api_close(user_api_id_t *user_api_id) { LOG_FUNC_IN; - /* Sanity check */ - int sfd = user_api_get_fd(user_api_id); - - if (fd != sfd) { - LOG_TRACE(ERROR, "USR-API - Endpoint %d is not the one created for communication with the user application layer (%d)", fd, sfd); - LOG_FUNC_OUT; - return; - } - /* Cleanup the connection endpoint */ user_api_id->close(user_api_id->endpoint) ; user_api_id->endpoint = NULL; diff --git a/openair3/NAS/UE/API/USER/user_api.h b/openair3/NAS/UE/API/USER/user_api.h index 513a44e4fb..6536144165 100644 --- a/openair3/NAS/UE/API/USER/user_api.h +++ b/openair3/NAS/UE/API/USER/user_api.h @@ -66,10 +66,10 @@ int user_api_esm_callback(user_api_id_t *user_api_id, int cid, network_pdn_state int user_api_get_fd(user_api_id_t *user_api_id); const void* user_api_get_data(user_at_commands_t *commands, int index); -int user_api_read_data(user_api_id_t *user_api_id, int fd); +int user_api_read_data(user_api_id_t *user_api_id); int user_api_set_data(user_api_id_t *user_api_id, char *message); -int user_api_send_data(user_api_id_t *user_api_id, int fd, int length); -void user_api_close(user_api_id_t *user_api_id, int fd); +int user_api_send_data(user_api_id_t *user_api_id, int length); +void user_api_close(user_api_id_t *user_api_id); int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length); int user_api_encode_data(user_api_id_t *user_api_id, const void* data, int add_success_code); diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 122ee72f6e..72035da6c8 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -70,7 +70,7 @@ static void *_nas_network_mngr(void *); static int _nas_set_signal_handler(int signal, void (handler)(int)); static void _nas_signal_handler(int signal); -static void _nas_clean(user_api_id_t *user_api_id, int usr_fd, int net_fd); +static void _nas_clean(user_api_id_t *user_api_id, int net_fd); uint8_t usim_test = 0; // FIXME user must be set up with right itti message instance @@ -126,7 +126,7 @@ int main(int argc, const char *argv[]) */ if (network_api_initialize (nhost, nport) != RETURNok) { LOG_TRACE (ERROR, "UE-MAIN - network_api_initialize() failed"); - user_api_close (user_api_id, user_fd); + user_api_close (user_api_id); exit (EXIT_FAILURE); } @@ -163,7 +163,7 @@ int main(int argc, const char *argv[]) if (pthread_create (&user_mngr, &attr, _nas_user_mngr, &user_fd) != 0) { LOG_TRACE (ERROR, "UE-MAIN - " "Failed to create the user management thread"); - user_api_close (user_api_id, user_fd); + user_api_close (user_api_id); network_api_close (network_fd); exit (EXIT_FAILURE); } @@ -177,7 +177,7 @@ int main(int argc, const char *argv[]) &network_fd) != 0) { LOG_TRACE (ERROR, "UE-MAIN - " "Failed to create the network management thread"); - user_api_close (user_api_id, user_fd); + user_api_close (user_api_id); network_api_close (network_fd); exit (EXIT_FAILURE); } @@ -195,7 +195,7 @@ int main(int argc, const char *argv[]) } /* Termination cleanup */ - _nas_clean (user_api_id, user_fd, network_fd); + _nas_clean (user_api_id, network_fd); LOG_TRACE (WARNING, "UE-MAIN - NAS main process exited"); @@ -236,7 +236,7 @@ static void *_nas_user_mngr(void *args) } /* Close the connection to the user application layer */ - user_api_close (user->user_api_id, *fd); + user_api_close (user->user_api_id); LOG_TRACE (WARNING, "UE-MAIN - " "The user connection endpoint manager exited"); @@ -386,7 +386,7 @@ static void _nas_signal_handler(int signal) LOG_TRACE (WARNING, "UE-MAIN - Signal %d received", signal); // FIXME acces to global - _nas_clean (user->user_api_id, user_api_get_fd (user->user_api_id), network_api_get_fd ()); + _nas_clean (user->user_api_id, network_api_get_fd ()); exit (EXIT_SUCCESS); LOG_FUNC_OUT @@ -407,7 +407,7 @@ static void _nas_signal_handler(int signal) ** Others: None ** ** ** ***************************************************************************/ -static void _nas_clean(user_api_id_t *user_api_id, int usr_fd, int net_fd) +static void _nas_clean(user_api_id_t *user_api_id, int net_fd) { LOG_FUNC_IN; @@ -418,8 +418,8 @@ static void _nas_clean(user_api_id_t *user_api_id, int usr_fd, int net_fd) LOG_TRACE (INFO, "UE-MAIN - " "Closing user connection %d and network connection %d", - usr_fd, net_fd); - user_api_close (user_api_id, usr_fd); + user_api_get_fd (user_api_id), net_fd); + user_api_close (user_api_id); network_api_close (net_fd); LOG_FUNC_OUT diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 2b41123446..6b4b7d97d9 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -48,7 +48,7 @@ static int nas_ue_process_events(nas_user_t *user, struct epoll_event *events, i for (event = 0; event < nb_events; event++) { if (events[event].events != 0) { /* If the event has not been yet been processed (not an itti message) */ - if (events[event].data.fd == user->fd) { + if (events[event].data.fd == user_api_get_fd(user->user_api_id)) { exit_loop = nas_user_receive_and_process(user, NULL); } else { LOG_E(NAS, "[UE] Received an event from an unknown fd %d!\n", events[event].data.fd); @@ -94,8 +94,7 @@ void *nas_ue_task(void *args_p) exit (EXIT_FAILURE); } - user->fd = user_api_get_fd (user_api_id); - itti_subscribe_event_fd (TASK_NAS_UE, user->fd); + itti_subscribe_event_fd (TASK_NAS_UE, user_api_get_fd(user_api_id)); } user->user_at_commands = calloc(1, sizeof(user_at_commands_t)); diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 065bbca17d..120037d366 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -223,7 +223,7 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) bytes = user_api_set_data(user_api_id, message); } else { /* Read the user data message */ - bytes = user_api_read_data (user_api_id, user->fd); + bytes = user_api_read_data (user_api_id); if (bytes == RETURNerror) { /* Failed to read data from the user application layer; @@ -279,7 +279,7 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) } /* Send the data message to the user */ - bytes = user_api_send_data (user_api_id, user->fd, bytes); + bytes = user_api_send_data (user_api_id, bytes); if (bytes == RETURNerror) { /* Failed to send data to the user application layer; diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index a30e13663a..993e0d6674 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -60,7 +60,6 @@ Description NAS type definition to manage a user equipment typedef struct { int ueid; /* UE lower layer identifier */ - int fd; proc_data_t proc; // Eps Session Management esm_data_t *esm_data; // ESM internal data (used within ESM only) From fcf2444ee14158fe693db23744938ba67ca359a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 11:21:21 +0200 Subject: [PATCH 176/571] UE/EMM: remove redondant ueid in prototypes --- openair3/NAS/UE/EMM/EmmStatusHdl.c | 4 ++-- openair3/NAS/UE/EMM/SAP/emm_as.c | 13 +++++-------- openair3/NAS/UE/EMM/emm_proc.h | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/openair3/NAS/UE/EMM/EmmStatusHdl.c b/openair3/NAS/UE/EMM/EmmStatusHdl.c index 320ca985ff..89dd50207f 100644 --- a/openair3/NAS/UE/EMM/EmmStatusHdl.c +++ b/openair3/NAS/UE/EMM/EmmStatusHdl.c @@ -115,7 +115,7 @@ int emm_proc_status_ind(unsigned int ueid, int emm_cause) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_status(nas_user_t *user, unsigned int ueid, int emm_cause) +int emm_proc_status(nas_user_t *user, int emm_cause) { LOG_FUNC_IN; @@ -132,7 +132,7 @@ int emm_proc_status(nas_user_t *user, unsigned int ueid, int emm_cause) */ emm_sap.primitive = EMMAS_STATUS_IND; emm_sap.u.emm_as.u.status.emm_cause = emm_cause; - emm_sap.u.emm_as.u.status.ueid = ueid; + emm_sap.u.emm_as.u.status.ueid = user->ueid; emm_sap.u.emm_as.u.status.guti = user->emm_data->guti; sctx = user->emm_data->security; diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index dfe055f4d6..2112b59164 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -97,7 +97,7 @@ static const char *_emm_as_primitive_str[] = { * Functions executed to process EMM procedures upon receiving * data from the network */ -static int _emm_as_recv(nas_user_t *user, unsigned int ueid, const char *msg, int len, +static int _emm_as_recv(nas_user_t *user, const char *msg, int len, int *emm_cause); static int _emm_as_establish_cnf(nas_user_t *user, const emm_as_establish_t *msg, int *emm_cause); @@ -194,15 +194,12 @@ int emm_as_send(nas_user_t *user, const emm_as_t *msg) int emm_cause = EMM_CAUSE_SUCCESS; emm_as_primitive_t primitive = msg->primitive; - uint32_t ueid = user->ueid; - LOG_TRACE(INFO, "EMMAS-SAP - Received primitive %s (%d)", _emm_as_primitive_str[primitive - _EMMAS_START - 1], primitive); switch (primitive) { case _EMMAS_DATA_IND: rc = _emm_as_data_ind(user, &msg->u.data, &emm_cause); - ueid = msg->u.data.ueid; break; @@ -264,7 +261,7 @@ int emm_as_send(nas_user_t *user, const emm_as_t *msg) LOG_TRACE(WARNING, "EMMAS-SAP - Received EMM message is not valid " "(cause=%d)", emm_cause); /* Return an EMM status message */ - rc = emm_proc_status(user, ueid, emm_cause); + rc = emm_proc_status(user, emm_cause); } if (rc != RETURNok) { @@ -304,7 +301,7 @@ int emm_as_send(nas_user_t *user, const emm_as_t *msg) ** Others: None ** ** ** ***************************************************************************/ -static int _emm_as_recv(nas_user_t *user, unsigned int ueid, const char *msg, int len, +static int _emm_as_recv(nas_user_t *user, const char *msg, int len, int *emm_cause) { LOG_FUNC_IN; @@ -336,7 +333,7 @@ static int _emm_as_recv(nas_user_t *user, unsigned int ueid, const char *msg, in switch (emm_msg->header.message_type) { case EMM_STATUS: - rc = emm_recv_status(ueid, &emm_msg->emm_status, emm_cause); + rc = emm_recv_status(user->ueid, &emm_msg->emm_status, emm_cause); break; case IDENTITY_REQUEST: @@ -441,7 +438,7 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm } else if (header.protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) { /* Process EMM data */ - rc = _emm_as_recv(user, msg->ueid, plain_msg, bytes, emm_cause); + rc = _emm_as_recv(user, plain_msg, bytes, emm_cause); } else if (header.protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) { const OctetString data = {bytes, (uint8_t *)plain_msg}; diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 333343b6ca..3abf554ef7 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -66,7 +66,7 @@ Description Defines the EPS Mobility Management procedures executed at *--------------------------------------------------------------------------- */ int emm_proc_status_ind(unsigned int ueid, int emm_cause); -int emm_proc_status(nas_user_t *user, unsigned int ueid, int emm_cause); +int emm_proc_status(nas_user_t *user, int emm_cause); /* *--------------------------------------------------------------------------- From 556d5a65e96c1e5d7d267e1ef5d897d3cc1c4937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 10:10:46 +0200 Subject: [PATCH 177/571] UE/*: exit on error --- openair3/NAS/UE/EMM/IdleMode.c | 2 +- openair3/NAS/UE/EMM/emm_main.c | 8 ++++---- openair3/NAS/UE/ESM/esm_ebr.c | 2 +- openair3/NAS/UE/ESM/esm_main.c | 4 ++-- openair3/NAS/UE/ESM/esm_pt.c | 2 +- openair3/NAS/UE/nas_proc.c | 4 ++-- openair3/NAS/UE/nas_ue_task.c | 6 +++--- openair3/NAS/UE/nas_user.c | 9 +++------ 8 files changed, 17 insertions(+), 20 deletions(-) diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index 8cff0b4ca5..e087fe26cd 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -109,7 +109,7 @@ void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) emm_plmn_list_t *emm_plmn_list = calloc(1, sizeof(emm_plmn_list_t)); if ( emm_plmn_list == NULL ) { LOG_TRACE(ERROR, "EMM - Can't alloc emm_plmn_list"); - // FIXME stop here + exit(EXIT_FAILURE); } user->emm_plmn_list = emm_plmn_list; /* Initialize the list of available PLMNs */ diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 7ec228d963..3b2b87c6f0 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -137,7 +137,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data = calloc(1, sizeof(emm_data_t)); if ( user->emm_data == NULL ) { LOG_TRACE(ERROR, "EMM-MAIN - Failed to get allocate emm_data"); - // FIXME stop here + exit(EXIT_FAILURE); } /* USIM validity indicator */ user->emm_data->usim_is_valid = FALSE; @@ -400,7 +400,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data->emm_timers = calloc(1, sizeof(emm_timers_t)); if ( user->emm_data->emm_timers == NULL ) { LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); - // FIXME stop here + exit(EXIT_FAILURE); } _emm_timers_initialize(user->emm_data->emm_timers); @@ -410,7 +410,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data->emm_detach_data = calloc(1, sizeof(emm_detach_data_t)); if ( user->emm_data->emm_detach_data == NULL ) { LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); - // FIXME stop here + exit(EXIT_FAILURE); } _emm_detach_initialize(user->emm_data->emm_detach_data); @@ -420,7 +420,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data->emm_attach_data = calloc(1, sizeof(emm_attach_data_t)); if ( user->emm_data->emm_attach_data == NULL ) { LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); - // FIXME stop here + exit(EXIT_FAILURE); } _emm_attach_initialize(user->emm_data->emm_attach_data); diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 1cf1d4a4e5..7c04043233 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -119,7 +119,7 @@ esm_ebr_data_t *esm_ebr_initialize(void) if ( esm_ebr_data == NULL ) { LOG_TRACE(ERROR, "ESM-EBR - Can't malloc esm_ebr_data"); - // FIXME Stop here !!! + exit(EXIT_FAILURE); } esm_ebr_data->index = 0; diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index 1b4099ce5b..96d387a0e3 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -81,14 +81,14 @@ void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) esm_data_t *esm_data = calloc(1, sizeof(esm_data_t)); if ( esm_data == NULL ) { LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc esm_data"); - // FIXME Stop here !!! + exit(EXIT_FAILURE); } user->esm_data = esm_data; default_eps_bearer_context_data_t *default_eps_bearer_context = calloc(1, sizeof(default_eps_bearer_context_data_t)); if ( default_eps_bearer_context == NULL ) { LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc default_eps_bearer_context"); - // FIXME Stop here !!! + exit(EXIT_FAILURE); } default_eps_bearer_context->ebi = ESM_EBI_UNASSIGNED; user->default_eps_bearer_context_data = default_eps_bearer_context; diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index 331ac6d8cf..12cebc9aa1 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -89,7 +89,7 @@ esm_pt_data_t *esm_pt_initialize(void) if ( esm_pt_data == NULL ) { LOG_TRACE(ERROR, "ESM-PT - Can't alloc esm_pt_data"); - // FIXME Stop here !!! + exit(EXIT_FAILURE); } esm_pt_data->index = 0; diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 44d3201c4a..bea7770b0d 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -100,13 +100,13 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->authentication_data = calloc(1, sizeof(authentication_data_t)); if ( user->authentication_data == NULL ) { LOG_TRACE(ERROR, "NAS-PROC - Failed to alloc authentication_data"); - // FIXME stop here + exit(EXIT_FAILURE); } user->security_data = calloc(1, sizeof(security_data_t)); if ( user->security_data == NULL ) { LOG_TRACE(ERROR, "NAS-PROC - Failed to alloc security_data"); - // FIXME stop here + exit(EXIT_FAILURE); } /* Initialize the EMM procedure manager */ diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 6b4b7d97d9..bca60babc7 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -83,7 +83,7 @@ void *nas_ue_task(void *args_p) if (user_api_id == NULL) { LOG_E(NAS, "[UE] Failed to alloc user_api_id_t"); - // FIXME stop here + exit(EXIT_FAILURE); } user->user_api_id = user_api_id; @@ -100,13 +100,13 @@ void *nas_ue_task(void *args_p) user->user_at_commands = calloc(1, sizeof(user_at_commands_t)); if ( user->user_at_commands == NULL ) { LOG_E(NAS, "[UE %d] Can't allocate memory for user_at_commands\n", 0); - // FIXME stop here + exit(EXIT_FAILURE); } user->at_response = calloc(1, sizeof(at_response_t)); if ( user->at_response == NULL ) { LOG_E(NAS, "[UE %d] Can't allocate memory for user_at_commands\n", 0); - // FIXME stop here + exit(EXIT_FAILURE); } /* Initialize NAS user */ diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 120037d366..f7fb6a0759 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -161,8 +161,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->nas_user_nvdata = calloc(1, sizeof(user_nvdata_t)); if ( user->nas_user_nvdata == NULL ) { LOG_TRACE(ERROR, "USR-MAIN - Failed to alloc nas_user_nvdata"); - // FIXME stop here - return; + exit(EXIT_FAILURE); } /* Get UE's data pathname */ @@ -170,8 +169,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, if (path == NULL) { LOG_TRACE(ERROR, "USR-MAIN - Failed to get UE's data pathname"); - // FIXME return an error code or exit - return; + exit(EXIT_FAILURE); } /* Get UE data stored in the non-volatile memory device */ @@ -184,8 +182,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->nas_user_context = calloc(1, sizeof(nas_user_context_t)); if ( user->nas_user_context == NULL ) { LOG_TRACE(ERROR, "USR-MAIN - Failed to alloc nas_user_context"); - // FIXME stop here - return; + exit(EXIT_FAILURE); } _nas_user_context_initialize(user->nas_user_context, version); From 8d34217ce440766d270bbebc37cd9f02f495a3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 27 Jul 2016 07:15:46 -0500 Subject: [PATCH 178/571] UE: add user instance to itti messages --- openair3/NAS/UE/EMM/SAP/emm_as.c | 12 ++++++++---- openair3/NAS/UE/nas_itti_messaging.c | 16 ++++++++-------- openair3/NAS/UE/nas_itti_messaging.h | 8 ++++---- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index 2112b59164..d833b5bba0 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -991,7 +991,8 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) case AS_CELL_INFO_REQ: { nas_itti_cell_info_req( as_msg.msg.cell_info_req.plmnID, - as_msg.msg.cell_info_req.rat); + as_msg.msg.cell_info_req.rat, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; @@ -1003,7 +1004,8 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) as_msg.msg.nas_establish_req.s_tmsi, as_msg.msg.nas_establish_req.plmnID, as_msg.msg.nas_establish_req.initialNasMsg.data, - as_msg.msg.nas_establish_req.initialNasMsg.length); + as_msg.msg.nas_establish_req.initialNasMsg.length, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; @@ -1012,7 +1014,8 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) nas_itti_ul_data_req( as_msg.msg.ul_info_transfer_req.UEid, as_msg.msg.ul_info_transfer_req.nasMsg.data, - as_msg.msg.ul_info_transfer_req.nasMsg.length); + as_msg.msg.ul_info_transfer_req.nasMsg.length, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; @@ -1021,7 +1024,8 @@ static int _emm_as_send(const nas_user_t *user, const emm_as_t *msg) nas_itti_rab_establish_rsp( as_msg.msg.rab_establish_rsp.s_tmsi, as_msg.msg.rab_establish_rsp.rabID, - as_msg.msg.rab_establish_rsp.errCode); + as_msg.msg.rab_establish_rsp.errCode, + user->ueid); LOG_FUNC_RETURN (RETURNok); } break; diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c index 7667ad50a4..b6b2126dfb 100644 --- a/openair3/NAS/UE/nas_itti_messaging.c +++ b/openair3/NAS/UE/nas_itti_messaging.c @@ -213,7 +213,7 @@ int nas_itti_kenb_refresh_req(const Byte_t kenb[32]) return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); } -int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat) +int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) { MessageDef *message_p; @@ -230,10 +230,10 @@ int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat) plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3, plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3); - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } -int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length) +int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length, int user_id) { MessageDef *message_p; @@ -255,10 +255,10 @@ int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t plmnID.MCCdigit1, plmnID.MCCdigit2, plmnID.MCCdigit3, plmnID.MNCdigit1, plmnID.MNCdigit2, plmnID.MNCdigit3); - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } -int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length) +int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length, int user_id) { MessageDef *message_p; @@ -268,10 +268,10 @@ int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = data; NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = length; - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } -int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode) +int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id) { MessageDef *message_p; @@ -287,5 +287,5 @@ int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, NULL,0, "0 NAS_RAB_ESTABLI_RSP MME code %u m-TMSI %u rb id %u status %u", s_tmsi.MMEcode, s_tmsi.m_tmsi,rabID, errCode ); - return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + 0 /* TODO to be virtualized */, message_p); + return itti_send_msg_to_task(TASK_RRC_UE, NB_eNB_INST + user_id, message_p); } diff --git a/openair3/NAS/UE/nas_itti_messaging.h b/openair3/NAS/UE/nas_itti_messaging.h index 22c09f109b..f4f1f18414 100644 --- a/openair3/NAS/UE/nas_itti_messaging.h +++ b/openair3/NAS/UE/nas_itti_messaging.h @@ -50,12 +50,12 @@ int nas_itti_protected_msg( int nas_itti_kenb_refresh_req(const Byte_t kenb[32]); -int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat); +int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id); -int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data_pP, uint32_t lengthP); +int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data_pP, uint32_t lengthP, int user_id); -int nas_itti_ul_data_req(const uint32_t ue_idP, void *const data_pP, const uint32_t lengthP); +int nas_itti_ul_data_req(const uint32_t ue_idP, void *const data_pP, const uint32_t lengthP, int user_id); -int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode); +int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id); # endif #endif /* NAS_ITTI_MESSAGING_H_ */ From 1ca4d551b85136f0d426c176a2afec04701678c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 08:48:38 +0200 Subject: [PATCH 179/571] UE: review and annotate code with FIXME --- openair3/NAS/UE/API/USER/at_command.c | 2 ++ openair3/NAS/UE/API/USER/at_error.c | 1 + openair3/NAS/UE/EMM/SAP/EmmDeregistered.c | 1 - openair3/NAS/UE/EMM/emm_proc.h | 1 - openair3/NAS/UE/ESM/esmData.h | 1 + openair3/NAS/UE/ESM/esm_ip.c | 1 + openair3/NAS/UE/nas_ue_task.c | 2 ++ 7 files changed, 7 insertions(+), 2 deletions(-) diff --git a/openair3/NAS/UE/API/USER/at_command.c b/openair3/NAS/UE/API/USER/at_command.c index 89793a55ae..8f40ba93c4 100644 --- a/openair3/NAS/UE/API/USER/at_command.c +++ b/openair3/NAS/UE/API/USER/at_command.c @@ -54,6 +54,7 @@ Description Defines the ATtention (AT) command set supported by the NAS /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ +// FIXME Put this in .h extern int at_response_format_v1; extern int at_error_code_suppression_q1; extern at_error_format_t at_error_format; @@ -278,6 +279,7 @@ int at_command_decode(const char* buffer, int length, at_command_t* at_command) char* buf = strdup(buffer+2); char* cmd = strtok(buf, ";"); + // FIXME check overflow for (i=0; cmd && (rc != RETURNerror); i++) { rc = ParseString(cmd, &at_command[i]); cmd = strtok(NULL, ";"); diff --git a/openair3/NAS/UE/API/USER/at_error.c b/openair3/NAS/UE/API/USER/at_error.c index 443c6a3300..7548fb513e 100644 --- a/openair3/NAS/UE/API/USER/at_error.c +++ b/openair3/NAS/UE/API/USER/at_error.c @@ -49,6 +49,7 @@ Description Defines error codes returned when execution of AT command /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ +// FIXME put this in .h extern int at_response_format_v1; /* diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c index 21f07ba385..a2a93c4d78 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregistered.c @@ -97,7 +97,6 @@ int EmmDeregistered(nas_user_t *user, const emm_reg_t *evt) /* Delete the authentication data RAND and RES */ - // FIXME REVIEW rc = emm_proc_authentication_delete(user); if (rc != RETURNok) { diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 3abf554ef7..a6a32448a4 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -107,7 +107,6 @@ int emm_proc_attach_release(void *args); int emm_proc_attach_restart(nas_user_t *user); int emm_proc_attach_set_emergency(emm_data_t *emm_data); -// FIXME check prototype int emm_proc_attach_set_detach(void *user); diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index ef7f523435..02bc0dd930 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -204,6 +204,7 @@ typedef esm_data_context_t esm_data_t; /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ +// FIXME prototype and buffer allocation extern char ip_addr_str[100]; extern char *esm_data_get_ipv4_addr(const OctetString *ip_addr); diff --git a/openair3/NAS/UE/ESM/esm_ip.c b/openair3/NAS/UE/ESM/esm_ip.c index 23d8ecce97..2638221a8f 100644 --- a/openair3/NAS/UE/ESM/esm_ip.c +++ b/openair3/NAS/UE/ESM/esm_ip.c @@ -25,6 +25,7 @@ // FIXME don't work for reentrant calls char ip_addr_str[100]; +// FIXME can't be extern and inline at same time ! inline char *esm_data_get_ipv4_addr(const OctetString *ip_addr) { if (ip_addr->length > 0) { diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index bca60babc7..9b1531b549 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -33,8 +33,10 @@ #include "nas_user.h" +// FIXME make command line option for NAS_UE_AUTOSTART # define NAS_UE_AUTOSTART 1 +// FIXME review these externs extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; From 5367d5dc3f610a712e2d4a242538728692253c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 14:12:34 +0200 Subject: [PATCH 180/571] UE/EMM: move _lowerlayer_data to nas_user_t --- openair3/NAS/UE/EMM/LowerLayer.c | 45 ++++++++++----------------- openair3/NAS/UE/EMM/LowerLayer.h | 19 +---------- openair3/NAS/UE/EMM/LowerLayer_defs.h | 33 ++++++++++++++++++++ openair3/NAS/UE/nas_ue_task.c | 8 ++++- openair3/NAS/UE/user_defs.h | 2 ++ 5 files changed, 60 insertions(+), 47 deletions(-) create mode 100644 openair3/NAS/UE/EMM/LowerLayer_defs.h diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c index 2d67cf6417..b5555b2c2f 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.c +++ b/openair3/NAS/UE/EMM/LowerLayer.c @@ -60,17 +60,6 @@ Description Defines EMM procedures executed by the Non-Access Stratum /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -/* - * Data structure used to handle EMM procedures executed by the UE upon - * receiving lower layer notifications - */ -static struct { - lowerlayer_success_callback_t success; /* Successful data delivery */ - lowerlayer_failure_callback_t failure; /* Lower layer failure */ - lowerlayer_release_callback_t release; /* NAS signalling release */ - void *args; /* EMM procedure argument parameters */ -} _lowerlayer_data; - /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ @@ -293,17 +282,17 @@ int lowerlayer_data_req(nas_user_t *user, const OctetString *data) ** Others: _lowerlayer_data ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, +int emm_proc_lowerlayer_initialize(lowerlayer_data_t *lowerlayer_data, lowerlayer_success_callback_t success, lowerlayer_failure_callback_t failure, lowerlayer_release_callback_t release, void *args) { LOG_FUNC_IN; - _lowerlayer_data.success = success; - _lowerlayer_data.failure = failure; - _lowerlayer_data.release = release; - _lowerlayer_data.args = args; + lowerlayer_data->success = success; + lowerlayer_data->failure = failure; + lowerlayer_data->release = release; + lowerlayer_data->args = args; LOG_FUNC_RETURN (RETURNok); } @@ -324,17 +313,17 @@ int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_success(void) +int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data) { LOG_FUNC_IN; int rc = RETURNok; - lowerlayer_success_callback_t emm_callback = _lowerlayer_data.success; + lowerlayer_success_callback_t emm_callback = lowerlayer_data->success; if (emm_callback) { - rc = (*emm_callback)(_lowerlayer_data.args); - _lowerlayer_data.success = NULL; + rc = (*emm_callback)(lowerlayer_data->args); + lowerlayer_data->success = NULL; } LOG_FUNC_RETURN (rc); @@ -356,17 +345,17 @@ int emm_proc_lowerlayer_success(void) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_failure(int is_initial) +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial) { LOG_FUNC_IN; int rc = RETURNok; - lowerlayer_failure_callback_t emm_callback = _lowerlayer_data.failure; + lowerlayer_failure_callback_t emm_callback = lowerlayer_data->failure; if (emm_callback) { - rc = (*emm_callback)(is_initial, _lowerlayer_data.args); - _lowerlayer_data.failure = NULL; + rc = (*emm_callback)(is_initial, lowerlayer_data->args); + lowerlayer_data->failure = NULL; } LOG_FUNC_RETURN (rc); @@ -387,17 +376,17 @@ int emm_proc_lowerlayer_failure(int is_initial) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_release(void) +int emm_proc_lowerlayer_release(lowerlayer_data_t *lowerlayer_data) { LOG_FUNC_IN; int rc = RETURNok; - lowerlayer_release_callback_t emm_callback = _lowerlayer_data.release; + lowerlayer_release_callback_t emm_callback = lowerlayer_data->release; if (emm_callback) { - rc = (*emm_callback)(_lowerlayer_data.args); - _lowerlayer_data.release = NULL; + rc = (*emm_callback)(lowerlayer_data->args); + lowerlayer_data->release = NULL; } LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/LowerLayer.h b/openair3/NAS/UE/EMM/LowerLayer.h index 019803936c..1e56316c69 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.h +++ b/openair3/NAS/UE/EMM/LowerLayer.h @@ -49,28 +49,11 @@ Description Defines EMM procedures executed by the Non-Access Stratum /********************* G L O B A L C O N S T A N T S *******************/ /****************************************************************************/ -/* - * Type of EMM procedure callback function executed whenever data are - * successfully delivered to the network - */ -typedef int (*lowerlayer_success_callback_t)(void *); - -/* - * Type of EMM procedure callback function executed when data are not - * delivered to the network because a lower layer failure occurred - */ -typedef int (*lowerlayer_failure_callback_t)(int, void *); - -/* - * Type of EMM procedure callback function executed when NAS signalling - * connection is released - */ -typedef int (*lowerlayer_release_callback_t)(void *); - /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ + /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ /****************************************************************************/ diff --git a/openair3/NAS/UE/EMM/LowerLayer_defs.h b/openair3/NAS/UE/EMM/LowerLayer_defs.h new file mode 100644 index 0000000000..6035d4ed12 --- /dev/null +++ b/openair3/NAS/UE/EMM/LowerLayer_defs.h @@ -0,0 +1,33 @@ +#ifndef _LOWER_LAYER_DEFS_H +#define _LOWER_LAYER_DEFS_H + +/* + * Type of EMM procedure callback function executed whenever data are + * successfully delivered to the network + */ +typedef int (*lowerlayer_success_callback_t)(void *); + +/* + * Type of EMM procedure callback function executed when data are not + * delivered to the network because a lower layer failure occurred + */ +typedef int (*lowerlayer_failure_callback_t)(int, void *); + +/* + * Type of EMM procedure callback function executed when NAS signalling + * connection is released + */ +typedef int (*lowerlayer_release_callback_t)(void *); + +/* + * Data structure used to handle EMM procedures executed by the UE upon + * receiving lower layer notifications + */ +typedef struct { + lowerlayer_success_callback_t success; /* Successful data delivery */ + lowerlayer_failure_callback_t failure; /* Lower layer failure */ + lowerlayer_release_callback_t release; /* NAS signalling release */ + void *args; /* EMM procedure argument parameters */ +} lowerlayer_data_t; + +#endif diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 9b1531b549..05bd17fa63 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -107,7 +107,13 @@ void *nas_ue_task(void *args_p) user->at_response = calloc(1, sizeof(at_response_t)); if ( user->at_response == NULL ) { - LOG_E(NAS, "[UE %d] Can't allocate memory for user_at_commands\n", 0); + LOG_E(NAS, "[UE %d] Can't allocate memory for at_response\n", 0); + exit(EXIT_FAILURE); + } + + user->lowerlayer_data = calloc(1, sizeof(lowerlayer_data_t)); + if ( user->lowerlayer_data == NULL ) { + LOG_E(NAS, "[UE %d] Can't allocate memory for lowerlayer_data\n", 0); exit(EXIT_FAILURE); } diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 993e0d6674..53cab4edb4 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -52,6 +52,7 @@ Description NAS type definition to manage a user equipment #include "EMM/emmData.h" #include "EMM/Authentication.h" #include "EMM/IdleMode_defs.h" +#include "EMM/LowerLayer_defs.h" #include "API/USIM/usim_api.h" #include "API/USER/user_api_defs.h" #include "SecurityModeControl.h" @@ -81,6 +82,7 @@ typedef struct { // user_at_commands_t *user_at_commands; //decoded data received from the user application layer user_api_id_t *user_api_id; + lowerlayer_data_t *lowerlayer_data; } nas_user_t; #endif From dcf35b2af1acacdd38a8da7668e29e636d14ec99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 14:45:00 +0200 Subject: [PATCH 181/571] UE/EMM: fix emm_proc_lowerlayer_* prototype --- openair3/NAS/UE/EMM/Attach.c | 8 ++++---- openair3/NAS/UE/EMM/Authentication.c | 2 +- openair3/NAS/UE/EMM/Detach.c | 8 ++++---- openair3/NAS/UE/EMM/Identification.c | 2 +- openair3/NAS/UE/EMM/LowerLayer.h | 14 ++++++++++++++ .../UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c | 4 ++-- openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c | 2 +- .../NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c | 6 +++--- .../NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c | 6 +++--- openair3/NAS/UE/EMM/SAP/EmmRegistered.c | 6 +++--- openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c | 6 +++--- openair3/NAS/UE/EMM/SecurityModeControl.c | 2 +- openair3/NAS/UE/EMM/emm_proc.h | 13 ------------- 13 files changed, 40 insertions(+), 39 deletions(-) diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index d765ff0fa7..c0c82b9b4c 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -240,7 +240,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) if (rc != RETURNerror) { /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_attach_request, + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, emm_proc_attach_request, emm_proc_attach_failure, emm_proc_attach_release, user); @@ -423,7 +423,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, if ( (rc != RETURNerror) && (esm_sap.err == ESM_SAP_SUCCESS) ) { /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_attach_complete, + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, emm_proc_attach_complete, emm_proc_attach_failure, NULL, user); @@ -721,7 +721,7 @@ int emm_proc_attach_complete(void *args) LOG_TRACE(INFO, "EMM-PROC - EPS attach complete"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Reset the attach attempt counter */ emm_attach_data->attempt_count = 0; @@ -787,7 +787,7 @@ int emm_proc_attach_failure(int is_initial, void *args) LOG_TRACE(WARNING, "EMM-PROC - EPS attach failure"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3410 if still running */ if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 56ec2bd833..e49bdd2db7 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -289,7 +289,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); if (rc != RETURNok) { LOG_TRACE(WARNING, diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index e59d8b7d94..fd2db1b617 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -132,7 +132,7 @@ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_of /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(emm_proc_detach_request, + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, emm_proc_detach_request, emm_proc_detach_failure, emm_proc_detach_release, user); @@ -240,7 +240,7 @@ int emm_proc_detach_accept(void* args) LOG_TRACE(INFO, "EMM-PROC - UE initiated detach procedure completion"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + (void) emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3421 */ emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); @@ -292,7 +292,7 @@ int emm_proc_detach_failure(int is_initial, void *args) LOG_TRACE(WARNING, "EMM-PROC - Network detach failure"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + (void) emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3421 */ emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); @@ -458,7 +458,7 @@ static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type) LOG_TRACE(WARNING, "EMM-PROC - Abort the detach procedure"); /* Reset EMM procedure handler */ - (void) emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); /* Stop timer T3421 */ emm_timers->T3421.id = nas_timer_stop(emm_timers->T3421.id); diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c index e894e9e045..7cf2e765c6 100644 --- a/openair3/NAS/UE/EMM/Identification.c +++ b/openair3/NAS/UE/EMM/Identification.c @@ -115,7 +115,7 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); if (rc != RETURNok) { LOG_TRACE(WARNING, diff --git a/openair3/NAS/UE/EMM/LowerLayer.h b/openair3/NAS/UE/EMM/LowerLayer.h index 1e56316c69..00e271feaa 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.h +++ b/openair3/NAS/UE/EMM/LowerLayer.h @@ -62,6 +62,20 @@ Description Defines EMM procedures executed by the Non-Access Stratum /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ +/* + *--------------------------------------------------------------------------- + * Lower layer procedure + *--------------------------------------------------------------------------- + */ +int emm_proc_lowerlayer_initialize(lowerlayer_data_t *lowerlayer_data, lowerlayer_success_callback_t success, + lowerlayer_failure_callback_t failure, + lowerlayer_release_callback_t release, + void *args); +int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data); +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial); +int emm_proc_lowerlayer_release(lowerlayer_data_t *lowerlayer_data); + + int lowerlayer_success(nas_user_t *user); int lowerlayer_failure(nas_user_t *user); int lowerlayer_establish(nas_user_t *user); diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c index 3415eee99f..7ddfac03db 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c @@ -113,14 +113,14 @@ int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *evt) /* * Data successfully delivered to the network */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Data failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c index 6706d144b6..d18b66a316 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredInitiated.c @@ -124,7 +124,7 @@ int EmmDeregisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * before the Detach Accept is received */ // FIXME review - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c index 04c60aef01..3943254415 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c @@ -126,21 +126,21 @@ int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) * Initial NAS message has been successfully delivered * to the network */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); break; case _EMMREG_LOWERLAYER_RELEASE: /* * NAS signalling connection has been released */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index fd31eaf6dc..3ec7a96ba8 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -134,21 +134,21 @@ int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) * Initial NAS message has been successfully delivered * to the network */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); break; case _EMMREG_LOWERLAYER_RELEASE: /* * NAS signalling connection has been released */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; case _EMMREG_ATTACH_CNF: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c index cb1db33985..dbc51e5155 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c @@ -136,21 +136,21 @@ int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) /* * Data transfer message has been successfully delivered */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: /* * Data transfer message failed to be delivered */ - rc = emm_proc_lowerlayer_failure(FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); break; case _EMMREG_LOWERLAYER_RELEASE: /* * NAS signalling connection has been released */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index c0d5f50ebc..d10f0d1053 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -230,7 +230,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * any message transfered by EMM common procedures requested * by the network. */ - rc = emm_proc_lowerlayer_success(); + rc = emm_proc_lowerlayer_success(user->lowerlayer_data); break; case _EMMREG_LOWERLAYER_FAILURE: @@ -240,7 +240,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * any message transfered by EMM common procedures requested * by the network. */ - rc = emm_proc_lowerlayer_failure(FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); break; case _EMMREG_LOWERLAYER_RELEASE: @@ -249,7 +249,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * Accept, Attach Reject, or any message transfered by EMM common * procedures requested by the network, is received. */ - rc = emm_proc_lowerlayer_release(); + rc = emm_proc_lowerlayer_release(user->lowerlayer_data); break; default: diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 43a5db1ff4..46d2a4fc2e 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -308,7 +308,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, /* Setup EMM procedure handler to be executed upon receiving * lower layer notification */ - rc = emm_proc_lowerlayer_initialize(NULL, NULL, NULL, NULL); + rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL); if (rc != RETURNok) { LOG_TRACE(WARNING, diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index a6a32448a4..4505257335 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -68,19 +68,6 @@ Description Defines the EPS Mobility Management procedures executed at int emm_proc_status_ind(unsigned int ueid, int emm_cause); int emm_proc_status(nas_user_t *user, int emm_cause); -/* - *--------------------------------------------------------------------------- - * Lower layer procedure - *--------------------------------------------------------------------------- - */ -int emm_proc_lowerlayer_initialize(lowerlayer_success_callback_t success, - lowerlayer_failure_callback_t failure, - lowerlayer_release_callback_t release, - void *args); -int emm_proc_lowerlayer_success(void); -int emm_proc_lowerlayer_failure(int is_initial); -int emm_proc_lowerlayer_release(void); - /* *--------------------------------------------------------------------------- * UE's Idle mode procedure From e36aee0b7f53fbebc854da672828be6f517fb1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 16:30:58 +0200 Subject: [PATCH 182/571] UE: factorize calloc() calls and exit on failure --- cmake_targets/CMakeLists.txt | 2 + cmake_targets/at_commands/CMakeLists.txt | 5 +- common/utils/Makefile.inc | 59 ------------------------ common/utils/utils.c | 23 +++++++++ common/utils/utils.h | 9 ++++ openair3/NAS/UE/EMM/IdleMode.c | 7 +-- openair3/NAS/UE/EMM/emm_main.c | 25 ++-------- openair3/NAS/UE/ESM/esm_ebr.c | 8 +--- openair3/NAS/UE/ESM/esm_main.c | 7 +-- openair3/NAS/UE/ESM/esm_pt.c | 8 +--- openair3/NAS/UE/nas_proc.c | 14 ++---- openair3/NAS/UE/nas_ue_task.c | 29 ++---------- openair3/NAS/UE/nas_user.c | 13 ++---- 13 files changed, 62 insertions(+), 147 deletions(-) delete mode 100644 common/utils/Makefile.inc create mode 100644 common/utils/utils.c create mode 100644 common/utils/utils.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 94ff4b239a..9d94e75d6c 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1757,6 +1757,7 @@ add_executable(lte-softmodem ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c ${GTPU_need_ITTI} ${HW_SOURCE} ${TRANSPORT_SOURCE} @@ -1886,6 +1887,7 @@ add_executable(oaisim ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c ${GTPU_need_ITTI} ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${HW_SOURCE} diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index a459649081..bf964cec46 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -410,7 +410,6 @@ target_include_directories(emm PRIVATE # esm LIB ################################################################################ set(esm_SRC - ${OPENAIR_NAS_DIR}/UE/ESM/esm_main.c ${OPENAIR_NAS_DIR}/UE/ESM/DedicatedEpsBearerContextActivation.c ${OPENAIR_NAS_DIR}/UE/ESM/DefaultEpsBearerContextActivation.c ${OPENAIR_NAS_DIR}/UE/ESM/EpsBearerContextDeactivation.c @@ -482,11 +481,13 @@ set(esm_HDR ${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_recv.h ${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_sap.h ${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_send.h + ${OPENAIR_DIR}/common/utils/utils.h ) add_library(esm ${esm_SRC} ${esm_HDR}) target_include_directories(esm PRIVATE + ${OPENAIR_DIR}/common/utils ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/UE/API/USER ${OPENAIR_NAS_DIR}/UE/ESM @@ -673,6 +674,7 @@ target_include_directories(ies PRIVATE ################################################################################ include_directories( ${OPENAIR_NAS_DIR}/UE + ${OPENAIR_DIR}/common/utils ${OPENAIR_DIR}/common/utils/msc ${OPENAIR3_DIR}/COMMON ${OPENAIR3_DIR}/SECU @@ -694,6 +696,7 @@ ADD_EXECUTABLE(at_nas_ue ${OPENAIR_NAS_DIR}/UE/UEprocess.c ${OPENAIR_NAS_DIR}/UE/nas_parser.c ${OPENAIR_NAS_DIR}/UE/nas_proc.c ${OPENAIR_NAS_DIR}/UE/nas_user.c + ${OPENAIR_DIR}/common/utils/utils.c ) target_link_libraries (at_nas_ue diff --git a/common/utils/Makefile.inc b/common/utils/Makefile.inc deleted file mode 100644 index 33c126b8d7..0000000000 --- a/common/utils/Makefile.inc +++ /dev/null @@ -1,59 +0,0 @@ -export KERNEL_DIR=/lib/modules/$(shell uname -r)/ -CC=gcc -CCC=gcc -linux := $(shell if [ `uname` = "Linux" ] ; then echo "1" ; else echo "0" ; fi) - - -CFLAGS += -std=gnu99 -CFLAGS += -Wall -g -ggdb -Wstrict-prototypes -fno-strict-aliasing - -# Need to force this option because default kernel module builder is wrong -CFLAGS += $(call cc-option,-mpreferred-stack-boundary=4) - -#For performance, if some option doesn't exist in all gcc versions, use $(call cc-option,MY_OPTION) -#CFLAGS += -O2 -#CFLAGS += -funroll-loops -CFLAGS += -Wno-packed-bitfield-compat - -# This is the minimum CPU faetures for OAI -CFLAGS += -mmmx -msse -msse2 -mssse3 -msse4.1 -# Add CPU features from local CPU -#CFLAGS += -march=native - -ifeq ($(OSTYPE),Cygwin) -cygwin=1 -CFLAGS += -DCYGWIN -else -cygwin=0 -endif - -ifeq ($(linux),1) -CFLAGS += -LDFLAGS += -endif - -ITTI_DIR = $(COMMON_UTILS_DIR)/itti - -ITTI_OBJS = $(ITTI_DIR)/intertask_interface.o -ITTI_OBJS += $(ITTI_DIR)/intertask_interface_dump.o -ITTI_OBJS += $(ITTI_DIR)/backtrace.o -ITTI_OBJS += $(ITTI_DIR)/memory_pools.o -ITTI_OBJS += $(ITTI_DIR)/signals.o -ITTI_OBJS += $(ITTI_DIR)/timer.o - - -HASHTABLE_DIR = $(COMMON_UTILS_DIR)/collection/hashtable -MSC_DIR = $(COMMON_UTILS_DIR)/msc - -HASHTABLE_OBJS = $(HASHTABLE_DIR)/hashtable.o -HASHTABLE_OBJS += $(HASHTABLE_DIR)/obj_hashtable.o - -UTILS_OBJS = $(ITTI_OBJS) $(HASHTABLE_OBJS) - -UTILS_incl = \ - -I$(COMMON_UTILS_DIR) \ - -I$(HASHTABLE_DIR) \ - -I$(ITTI_DIR) \ - -I$(MSC_DIR) - -print-% : ; @echo $* = $($*) diff --git a/common/utils/utils.c b/common/utils/utils.c new file mode 100644 index 0000000000..7d292cc84d --- /dev/null +++ b/common/utils/utils.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include "utils.h" + +void *calloc_or_fail(size_t size) { + void *ptr = calloc(1, size); + if (ptr == NULL) { + fprintf(stderr, "[UE] Failed to calloc %zu bytes", size); + exit(EXIT_FAILURE); + } + return ptr; +} + +void *malloc_or_fail(size_t size) { + void *ptr = malloc(size); + if (ptr == NULL) { + fprintf(stderr, "[UE] Failed to malloc %zu bytes", size); + exit(EXIT_FAILURE); + } + return ptr; +} diff --git a/common/utils/utils.h b/common/utils/utils.h new file mode 100644 index 0000000000..db455485a2 --- /dev/null +++ b/common/utils/utils.h @@ -0,0 +1,9 @@ +#ifndef _UTILS_H +#define _UTILS_H + +#include + +void *calloc_or_fail(size_t size); +void *malloc_or_fail(size_t size); + +#endif diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index e087fe26cd..159a3b2a2c 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -59,6 +59,7 @@ Description Defines EMM procedures executed by the Non-Access Stratum #include "emm_proc.h" #include "nas_log.h" +#include "utils.h" #include "emm_sap.h" @@ -106,11 +107,7 @@ static IdleMode_callback_t _emm_indication_notify; ***************************************************************************/ void IdleMode_initialize(nas_user_t *user, IdleMode_callback_t cb) { - emm_plmn_list_t *emm_plmn_list = calloc(1, sizeof(emm_plmn_list_t)); - if ( emm_plmn_list == NULL ) { - LOG_TRACE(ERROR, "EMM - Can't alloc emm_plmn_list"); - exit(EXIT_FAILURE); - } + emm_plmn_list_t *emm_plmn_list = calloc_or_fail( sizeof(emm_plmn_list_t)); user->emm_plmn_list = emm_plmn_list; /* Initialize the list of available PLMNs */ emm_plmn_list->n_plmns = 0; diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 3b2b87c6f0..2de879506a 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -39,6 +39,7 @@ Description Defines the EPS Mobility Management procedure call manager, #include "emm_main.h" #include "nas_log.h" +#include "utils.h" #include "emmData.h" #include "MobileIdentity.h" #include "emm_proc_defs.h" @@ -134,11 +135,7 @@ void _emm_detach_initialize(emm_detach_data_t *emm_detach) { void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei) { LOG_FUNC_IN; - user->emm_data = calloc(1, sizeof(emm_data_t)); - if ( user->emm_data == NULL ) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get allocate emm_data"); - exit(EXIT_FAILURE); - } + user->emm_data = calloc_or_fail(sizeof(emm_data_t)); /* USIM validity indicator */ user->emm_data->usim_is_valid = FALSE; /* The IMEI read from the UE's non-volatile memory */ @@ -397,31 +394,19 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* * Initialize EMM timers */ - user->emm_data->emm_timers = calloc(1, sizeof(emm_timers_t)); - if ( user->emm_data->emm_timers == NULL ) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); - exit(EXIT_FAILURE); - } + user->emm_data->emm_timers = calloc_or_fail(sizeof(emm_timers_t)); _emm_timers_initialize(user->emm_data->emm_timers); /* * Initialize Internal data used for detach procedure */ - user->emm_data->emm_detach_data = calloc(1, sizeof(emm_detach_data_t)); - if ( user->emm_data->emm_detach_data == NULL ) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); - exit(EXIT_FAILURE); - } + user->emm_data->emm_detach_data = calloc_or_fail(sizeof(emm_detach_data_t)); _emm_detach_initialize(user->emm_data->emm_detach_data); /* * Initialize Internal data used for attach procedure */ - user->emm_data->emm_attach_data = calloc(1, sizeof(emm_attach_data_t)); - if ( user->emm_data->emm_attach_data == NULL ) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to alloc emm_timers"); - exit(EXIT_FAILURE); - } + user->emm_data->emm_attach_data = calloc_or_fail(sizeof(emm_attach_data_t)); _emm_attach_initialize(user->emm_data->emm_attach_data); /* diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 7c04043233..330da2fb23 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -44,6 +44,7 @@ Description Defines functions used to handle state of EPS bearer contexts #include "esm_ebr.h" #include "commonDef.h" #include "nas_log.h" +#include "utils.h" /****************************************************************************/ @@ -115,12 +116,7 @@ esm_ebr_data_t *esm_ebr_initialize(void) LOG_FUNC_IN; int i; - esm_ebr_data_t *esm_ebr_data = calloc(1, sizeof(esm_ebr_data_t)); - - if ( esm_ebr_data == NULL ) { - LOG_TRACE(ERROR, "ESM-EBR - Can't malloc esm_ebr_data"); - exit(EXIT_FAILURE); - } + esm_ebr_data_t *esm_ebr_data = calloc_or_fail(sizeof(esm_ebr_data_t)); esm_ebr_data->index = 0; diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index 96d387a0e3..6c110abb52 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -40,6 +40,7 @@ Description Defines the EPS Session Management procedure call manager, #include "esm_main.h" #include "commonDef.h" #include "nas_log.h" +#include "utils.h" #include "emmData.h" #include "esmData.h" @@ -78,11 +79,7 @@ void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) int i; - esm_data_t *esm_data = calloc(1, sizeof(esm_data_t)); - if ( esm_data == NULL ) { - LOG_TRACE(ERROR, "ESM-MAIN - Can't malloc esm_data"); - exit(EXIT_FAILURE); - } + esm_data_t *esm_data = calloc_or_fail(sizeof(esm_data_t)); user->esm_data = esm_data; default_eps_bearer_context_data_t *default_eps_bearer_context = calloc(1, sizeof(default_eps_bearer_context_data_t)); diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index 12cebc9aa1..9f8e948954 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -42,6 +42,7 @@ Description Defines functions used to handle ESM procedure transactions. #include "commonDef.h" #include "nas_log.h" +#include "utils.h" #include // malloc, free #include // memcpy @@ -84,14 +85,9 @@ static int _esm_pt_get_available_entry(esm_pt_data_t *esm_pt_data); esm_pt_data_t *esm_pt_initialize(void) { LOG_FUNC_IN; - esm_pt_data_t *esm_pt_data = calloc(1, sizeof(esm_pt_data_t)); + esm_pt_data_t *esm_pt_data = calloc_or_fail(sizeof(esm_pt_data_t)); int i; - if ( esm_pt_data == NULL ) { - LOG_TRACE(ERROR, "ESM-PT - Can't alloc esm_pt_data"); - exit(EXIT_FAILURE); - } - esm_pt_data->index = 0; for (i = 0; i < ESM_PT_DATA_SIZE + 1; i++) { diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index bea7770b0d..b5ecc6a6ed 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -39,6 +39,7 @@ Description NAS procedure call manager #include "nas_proc.h" #include "nas_log.h" #include "nas_user.h" +#include "utils.h" #include "emm_main.h" #include "emm_sap.h" @@ -97,17 +98,8 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->proc.rsrq = NAS_PROC_RSRQ_UNKNOWN; user->proc.rsrp = NAS_PROC_RSRP_UNKNOWN; - user->authentication_data = calloc(1, sizeof(authentication_data_t)); - if ( user->authentication_data == NULL ) { - LOG_TRACE(ERROR, "NAS-PROC - Failed to alloc authentication_data"); - exit(EXIT_FAILURE); - } - - user->security_data = calloc(1, sizeof(security_data_t)); - if ( user->security_data == NULL ) { - LOG_TRACE(ERROR, "NAS-PROC - Failed to alloc security_data"); - exit(EXIT_FAILURE); - } + user->authentication_data = calloc_or_fail(sizeof(authentication_data_t)); + user->security_data = calloc_or_fail( sizeof(security_data_t)); /* Initialize the EMM procedure manager */ emm_main_initialize(user, emm_cb, imei); diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 05bd17fa63..eeef8c0e58 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "utils.h" #if defined(ENABLE_ITTI) # include "assertions.h" # include "intertask_interface.h" @@ -81,13 +82,7 @@ void *nas_ue_task(void *args_p) { /* Initialize user interface (to exchange AT commands with user process) */ { - user_api_id_t *user_api_id = calloc(1, sizeof(user_api_id_t)); - - if (user_api_id == NULL) { - LOG_E(NAS, "[UE] Failed to alloc user_api_id_t"); - exit(EXIT_FAILURE); - } - + user_api_id_t *user_api_id = calloc_or_fail(sizeof(user_api_id_t)); user->user_api_id = user_api_id; if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL, @@ -99,23 +94,9 @@ void *nas_ue_task(void *args_p) itti_subscribe_event_fd (TASK_NAS_UE, user_api_get_fd(user_api_id)); } - user->user_at_commands = calloc(1, sizeof(user_at_commands_t)); - if ( user->user_at_commands == NULL ) { - LOG_E(NAS, "[UE %d] Can't allocate memory for user_at_commands\n", 0); - exit(EXIT_FAILURE); - } - - user->at_response = calloc(1, sizeof(at_response_t)); - if ( user->at_response == NULL ) { - LOG_E(NAS, "[UE %d] Can't allocate memory for at_response\n", 0); - exit(EXIT_FAILURE); - } - - user->lowerlayer_data = calloc(1, sizeof(lowerlayer_data_t)); - if ( user->lowerlayer_data == NULL ) { - LOG_E(NAS, "[UE %d] Can't allocate memory for lowerlayer_data\n", 0); - exit(EXIT_FAILURE); - } + user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); + user->at_response = calloc_or_fail(sizeof(at_response_t)); + user->lowerlayer_data = calloc_or_fail(sizeof(lowerlayer_data_t)); /* Initialize NAS user */ nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index f7fb6a0759..3756570ea0 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -47,6 +47,7 @@ Description NAS procedure functions triggered by the user #include "user_indication.h" #include "nas_proc.h" #include "nas_user.h" +#include "utils.h" #include "user_api.h" #include // memset, strncpy, strncmp @@ -158,11 +159,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, { LOG_FUNC_IN; - user->nas_user_nvdata = calloc(1, sizeof(user_nvdata_t)); - if ( user->nas_user_nvdata == NULL ) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to alloc nas_user_nvdata"); - exit(EXIT_FAILURE); - } + user->nas_user_nvdata = calloc_or_fail(sizeof(user_nvdata_t)); /* Get UE's data pathname */ char *path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); @@ -179,11 +176,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, } free(path); - user->nas_user_context = calloc(1, sizeof(nas_user_context_t)); - if ( user->nas_user_context == NULL ) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to alloc nas_user_context"); - exit(EXIT_FAILURE); - } + user->nas_user_context = calloc_or_fail(sizeof(nas_user_context_t)); _nas_user_context_initialize(user->nas_user_context, version); /* Initialize the internal NAS processing data */ From 9af3599153dc6db993081c2cb314ee466fba08ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 22 Jul 2016 16:39:25 +0200 Subject: [PATCH 183/571] UE: add nas_user_api_id_initialize() function --- openair3/NAS/UE/nas_ue_task.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index eeef8c0e58..1860007b3a 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -62,6 +62,20 @@ static int nas_ue_process_events(nas_user_t *user, struct epoll_event *events, i return (exit_loop); } +// Initialize user api id and port number +void nas_user_api_id_initialize(nas_user_t *user) { + user_api_id_t *user_api_id = calloc_or_fail(sizeof(user_api_id_t)); + user->user_api_id = user_api_id; + + if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL, + NULL) != RETURNok) { + LOG_E(NAS, "[UE %d] user interface initialization failed!", user->ueid); + exit (EXIT_FAILURE); + } + + itti_subscribe_event_fd (TASK_NAS_UE, user_api_get_fd(user_api_id)); +} + void *nas_ue_task(void *args_p) { int nb_events; @@ -81,23 +95,10 @@ void *nas_ue_task(void *args_p) /* Initialize UE NAS (EURECOM-NAS) */ { /* Initialize user interface (to exchange AT commands with user process) */ - { - user_api_id_t *user_api_id = calloc_or_fail(sizeof(user_api_id_t)); - user->user_api_id = user_api_id; - - if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL, - NULL) != RETURNok) { - LOG_E(NAS, "[UE] user interface initialization failed!"); - exit (EXIT_FAILURE); - } - - itti_subscribe_event_fd (TASK_NAS_UE, user_api_get_fd(user_api_id)); - } - + nas_user_api_id_initialize(user); user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); user->at_response = calloc_or_fail(sizeof(at_response_t)); user->lowerlayer_data = calloc_or_fail(sizeof(lowerlayer_data_t)); - /* Initialize NAS user */ nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); } From 45fccb0203d8a7c366f09e88edd4b7940817c44c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 26 Jul 2016 08:47:57 +0200 Subject: [PATCH 184/571] UE/API/USIM: move hex functions to common/utils.c --- cmake_targets/nas_sim_tools/CMakeLists.txt | 4 ++ common/utils/utils.c | 51 ++++++++++++++++++++ common/utils/utils.h | 6 +++ openair3/NAS/UE/API/USIM/usim_api.c | 56 +--------------------- 4 files changed, 63 insertions(+), 54 deletions(-) diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 732ede3f94..897e4a1773 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -27,6 +27,7 @@ set(usim_SRC ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.c + ${OPENAIR_DIR}/common/utils/utils.c ) set(usim_HDR ${OPENAIR_DIR}/openair3/NAS/TOOLS/network.h @@ -36,8 +37,11 @@ set(usim_HDR ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.h ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.h ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.h + ${OPENAIR_DIR}/common/utils/utils.h ) include_directories( + ${OPENAIR_DIR}/common/utils + ${OPENAIR_DIR}/openair3/NAS/UE ${OPENAIR_DIR}/openair3/NAS/COMMON ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM ${OPENAIR_DIR}/openair3/NAS/UE/EMM/ diff --git a/common/utils/utils.c b/common/utils/utils.c index 7d292cc84d..fed85c4213 100644 --- a/common/utils/utils.c +++ b/common/utils/utils.c @@ -21,3 +21,54 @@ void *malloc_or_fail(size_t size) { } return ptr; } + +/**************************************************************************** + ** ** + ** Name: hex_char_to_hex_value() ** + ** ** + ** Description: Converts an hexadecimal ASCII coded digit into its value. ** + ** ** + ** Inputs: c: A char holding the ASCII coded value ** + ** Others: None ** + ** ** + ** Outputs: None ** + ** Return: Converted value ** + ** Others: None ** + ** ** + ***************************************************************************/ +uint8_t hex_char_to_hex_value (char c) +{ + if (c >= 'A') { + /* Remove case bit */ + c &= ~('a' ^ 'A'); + + return (c - 'A' + 10); + } else { + return (c - '0'); + } +} + +/**************************************************************************** + ** ** + ** Name: hex_string_to_hex_value() ** + ** ** + ** Description: Converts an hexadecimal ASCII coded string into its value.** + ** ** + ** Inputs: hex_value: A pointer to the location to store the ** + ** conversion result ** + ** size: The size of hex_value in bytes ** + ** Others: None ** + ** ** + ** Outputs: hex_value: Converted value ** + ** Return: None ** + ** Others: None ** + ** ** + ***************************************************************************/ +void hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size) +{ + int i; + + for (i=0; i < size; i++) { + hex_value[i] = (hex_char_to_hex_value(hex_string[2 * i]) << 4) | hex_char_to_hex_value(hex_string[2 * i + 1]); + } +} diff --git a/common/utils/utils.h b/common/utils/utils.h index db455485a2..3114569b4e 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -1,9 +1,15 @@ #ifndef _UTILS_H #define _UTILS_H +#include #include void *calloc_or_fail(size_t size); void *malloc_or_fail(size_t size); +// Converts an hexadecimal ASCII coded digit into its value. ** +uint8_t hex_char_to_hex_value (char c); +// Converts an hexadecimal ASCII coded string into its value.** +void hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); + #endif diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index 73aeda709d..00252d2c03 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -41,6 +41,7 @@ Description Implements the API used by the NAS layer to read/write #include "usim_api.h" #include "nas_log.h" +#include "utils.h" #include "memory.h" #include #include "aka_functions.h" @@ -66,8 +67,6 @@ Description Implements the API used by the NAS layer to read/write */ #define USIM_API_NVRAM_DIRNAME "USIM_DIR" -static uint8_t _usim_api_hex_char_to_hex_value (char c); -static void _usim_api_hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); static int _usim_api_check_sqn(uint32_t seq, uint8_t ind); /****************************************************************************/ @@ -110,7 +109,7 @@ int usim_api_read(usim_data_t* data) } /* initialize the subscriber authentication security key */ - _usim_api_hex_string_to_hex_value(data->keys.usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); + hex_string_to_hex_value(data->keys.usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); // initialize OP /* PFT OP used currently in HSS (OPENAIRHSS/auc/kdf.c) */ @@ -497,57 +496,6 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co /********************* L O C A L F U N C T I O N S *********************/ /****************************************************************************/ -/**************************************************************************** - ** ** - ** Name: _usim_api_hex_char_to_hex_value() ** - ** ** - ** Description: Converts an hexadecimal ASCII coded digit into its value. ** - ** ** - ** Inputs: c: A char holding the ASCII coded value ** - ** Others: None ** - ** ** - ** Outputs: None ** - ** Return: Converted value ** - ** Others: None ** - ** ** - ***************************************************************************/ -static uint8_t _usim_api_hex_char_to_hex_value (char c) -{ - if (c >= 'A') { - /* Remove case bit */ - c &= ~('a' ^ 'A'); - - return (c - 'A' + 10); - } else { - return (c - '0'); - } -} - -/**************************************************************************** - ** ** - ** Name: _usim_api_hex_string_to_hex_value() ** - ** ** - ** Description: Converts an hexadecimal ASCII coded string into its value.** - ** ** - ** Inputs: hex_value: A pointer to the location to store the ** - ** conversion result ** - ** size: The size of hex_value in bytes ** - ** Others: None ** - ** ** - ** Outputs: hex_value: Converted value ** - ** Return: None ** - ** Others: None ** - ** ** - ***************************************************************************/ -static void _usim_api_hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size) -{ - int i; - - for (i=0; i < size; i++) { - hex_value[i] = (_usim_api_hex_char_to_hex_value(hex_string[2 * i]) << 4) | _usim_api_hex_char_to_hex_value(hex_string[2 * i + 1]); - } -} - /**************************************************************************** ** ** ** Name: _usim_api_check_sqn() ** From 5fc045644cdd573f4119765a2058907f83ceb1be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 26 Jul 2016 11:19:23 +0200 Subject: [PATCH 185/571] UE/USIM/API: fix interface for storing usim_data --- openair3/NAS/TOOLS/usim_data.c | 15 +++++++-- openair3/NAS/UE/API/USIM/usim_api.c | 47 +++++------------------------ openair3/NAS/UE/API/USIM/usim_api.h | 15 +++++++-- openair3/NAS/UE/EMM/emm_main.c | 2 +- openair3/NAS/UE/nas_ue_task.c | 8 +++++ openair3/NAS/UE/user_defs.h | 1 + 6 files changed, 43 insertions(+), 45 deletions(-) diff --git a/openair3/NAS/TOOLS/usim_data.c b/openair3/NAS/TOOLS/usim_data.c index 23eba29bb1..4e3027691f 100644 --- a/openair3/NAS/TOOLS/usim_data.c +++ b/openair3/NAS/TOOLS/usim_data.c @@ -100,6 +100,16 @@ int main (int argc, const char* argv[]) unsigned char gen_data; + /* Get USIM application pathname */ + char* path = memory_get_path(USIM_API_NVRAM_DIRNAME, + USIM_API_NVRAM_FILENAME); + + if (path == NULL) { + fprintf(stderr, "USIM-API - Failed to get USIM pathname"); + free(path); + exit(EXIT_FAILURE); + } + /* * Read command line parameters */ @@ -415,7 +425,7 @@ int main (int argc, const char* argv[]) /* * Write USIM application data */ - rc = usim_api_write(&usim_data); + rc = usim_api_write(path, &usim_data); if (rc != RETURNok) { perror("ERROR\t: usim_api_write() failed"); @@ -427,7 +437,7 @@ int main (int argc, const char* argv[]) * Read USIM application data */ memset(&usim_data, 0, sizeof(usim_data_t)); - rc = usim_api_read(&usim_data); + rc = usim_api_read(path, &usim_data); if (rc != RETURNok) { perror("ERROR\t: usim_api_read() failed"); @@ -443,7 +453,6 @@ int main (int argc, const char* argv[]) /* * Display USIM file location */ - char* path = memory_get_path("USIM_DIR", ".usim.nvram"); printf("\nUSIM data file: %s\n", path); free(path); diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index 00252d2c03..ef6b4f9101 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -47,6 +47,7 @@ Description Implements the API used by the NAS layer to read/write #include "aka_functions.h" #include // memcpy, memset #include // malloc, free +#include /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -56,17 +57,6 @@ Description Implements the API used by the NAS layer to read/write /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -/* - * The name of the file where are stored data of the USIM application - */ -#define USIM_API_NVRAM_FILENAME ".usim.nvram" - -/* - * The name of the environment variable which defines the directory - * where the USIM application file is located - */ -#define USIM_API_NVRAM_DIRNAME "USIM_DIR" - static int _usim_api_check_sqn(uint32_t seq, uint8_t ind); /****************************************************************************/ @@ -87,24 +77,14 @@ static int _usim_api_check_sqn(uint32_t seq, uint8_t ind); ** Others: None ** ** ** ***************************************************************************/ -int usim_api_read(usim_data_t* data) +int usim_api_read(const char *filename, usim_data_t* data) { LOG_FUNC_IN; - /* Get USIM application pathname */ - char* path = memory_get_path(USIM_API_NVRAM_DIRNAME, - USIM_API_NVRAM_FILENAME); - - if (path == NULL) { - LOG_TRACE(ERROR, "USIM-API - Failed to get USIM pathname"); - LOG_FUNC_RETURN (RETURNerror); - } - /* Read USIM application data */ - if (memory_read(path, data, sizeof(usim_data_t)) != RETURNok) { + if (memory_read(filename, data, sizeof(usim_data_t)) != RETURNok) { LOG_TRACE(ERROR, "USIM-API - %s file is either not valid " - "or not present", path); - free(path); + "or not present", filename); LOG_FUNC_RETURN (RETURNerror); } @@ -123,7 +103,7 @@ int usim_api_read(usim_data_t* data) 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; #endif memcpy(data->keys.op, _op, sizeof(_op)); - free(path); + LOG_FUNC_RETURN (RETURNok); } @@ -141,28 +121,17 @@ int usim_api_read(usim_data_t* data) ** Others: None ** ** ** ***************************************************************************/ -int usim_api_write(const usim_data_t* data) +int usim_api_write(const char *filename, const usim_data_t* data) { LOG_FUNC_IN; - /* Get USIM application pathname */ - char* path = memory_get_path(USIM_API_NVRAM_DIRNAME, - USIM_API_NVRAM_FILENAME); - - if (path == NULL) { - LOG_TRACE(ERROR, "USIM-API - Failed to get USIM pathname"); - LOG_FUNC_RETURN (RETURNerror); - } - /* Write USIM application data */ - if (memory_write(path, data, sizeof(usim_data_t)) != RETURNok) { + if (memory_write(filename, data, sizeof(usim_data_t)) != RETURNok) { - LOG_TRACE(ERROR, "USIM-API - Unable to write USIM file %s", path); - free(path); + LOG_TRACE(ERROR, "USIM-API - Unable to write USIM file %s", filename); LOG_FUNC_RETURN (RETURNerror); } - free(path); LOG_FUNC_RETURN (RETURNok); } diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index 9114150396..74123029dd 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -54,6 +54,17 @@ Description Implements the API used by the NAS layer to read/write #define USIM_API_K_SIZE 16 #define USIM_API_K_VALUE "fec86ba6eb707ed08905757b1bb44b8f" +/* + * The name of the file where are stored data of the USIM application + */ +#define USIM_API_NVRAM_FILENAME ".usim.nvram" + +/* + * The name of the environment variable which defines the directory + * where the USIM application file is located + */ +#define USIM_API_NVRAM_DIRNAME "USIM_DIR" + /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ /****************************************************************************/ @@ -366,9 +377,9 @@ typedef struct { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int usim_api_read(usim_data_t* data); +int usim_api_read(const char *filename, usim_data_t* data); -int usim_api_write(const usim_data_t* data); +int usim_api_write(const char *filename, const usim_data_t* data); int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts, OctetString* res, diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 2de879506a..980deb1583 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -193,7 +193,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* * Get USIM application data */ - if ( usim_api_read(&user->usim_data) != RETURNok ) { + if ( usim_api_read(user->usim_data_store, &user->usim_data) != RETURNok ) { /* The USIM application may not be present or not valid */ LOG_TRACE(WARNING, "EMM-MAIN - Failed to read USIM application data"); } else { diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 1860007b3a..3d45f5ac1b 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -31,6 +31,7 @@ # include "nas_parser.h" # include "nas_proc.h" # include "msc.h" +# include "memory.h" #include "nas_user.h" @@ -94,6 +95,13 @@ void *nas_ue_task(void *args_p) MSC_START_USE(); /* Initialize UE NAS (EURECOM-NAS) */ { + /* Get USIM data application filename */ + user->usim_data_store = memory_get_path(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME); + if ( user->usim_data_store == NULL ) { + LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); + exit(EXIT_FAILURE); + } + /* Initialize user interface (to exchange AT commands with user process) */ nas_user_api_id_initialize(user); user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 53cab4edb4..caa2017f8d 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -75,6 +75,7 @@ typedef struct { security_data_t *security_data; //Internal data used for security mode control procedure // Hardware persistent storage usim_data_t usim_data; // USIM application data + const char *usim_data_store; // USIM application data filename user_nvdata_t *nas_user_nvdata; //UE parameters stored in the UE's non-volatile memory device // nas_user_context_t *nas_user_context; From 260e696c8b184a72eb4b836ab2555ba611ddfabd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 26 Jul 2016 11:38:03 +0200 Subject: [PATCH 186/571] UE: move nvram data filename to nas_user_t --- openair3/NAS/UE/nas_ue_task.c | 7 +++++++ openair3/NAS/UE/nas_user.c | 13 ++----------- openair3/NAS/UE/user_defs.h | 1 + 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 3d45f5ac1b..af176bd169 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -102,6 +102,13 @@ void *nas_ue_task(void *args_p) exit(EXIT_FAILURE); } + /* Get UE's data pathname */ + user->user_nvdata_store = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); + if ( user->user_nvdata_store == NULL ) { + LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); + exit(EXIT_FAILURE); + } + /* Initialize user interface (to exchange AT commands with user process) */ nas_user_api_id_initialize(user); user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 3756570ea0..27f632831e 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -161,20 +161,11 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->nas_user_nvdata = calloc_or_fail(sizeof(user_nvdata_t)); - /* Get UE's data pathname */ - char *path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); - - if (path == NULL) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to get UE's data pathname"); - exit(EXIT_FAILURE); - } - /* Get UE data stored in the non-volatile memory device */ - int rc = memory_read(path, user->nas_user_nvdata, sizeof(user_nvdata_t)); + int rc = memory_read(user->usim_data_store, user->nas_user_nvdata, sizeof(user_nvdata_t)); if (rc != RETURNok) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", path); + LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", user->nas_user_nvdata); } - free(path); user->nas_user_context = calloc_or_fail(sizeof(nas_user_context_t)); _nas_user_context_initialize(user->nas_user_context, version); diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index caa2017f8d..ac16e39ef6 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -77,6 +77,7 @@ typedef struct { usim_data_t usim_data; // USIM application data const char *usim_data_store; // USIM application data filename user_nvdata_t *nas_user_nvdata; //UE parameters stored in the UE's non-volatile memory device + const char *user_nvdata_store; //UE parameters stored in the UE's non-volatile memory device // nas_user_context_t *nas_user_context; at_response_t *at_response; // data structure returned to the user as the result of NAS procedure function call From 8bc36c3b96e0c7d4260ce47c4f2883631fdabf8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 26 Jul 2016 11:59:11 +0200 Subject: [PATCH 187/571] UE/EMM: move emm_nvram filename to nas_user_t --- openair3/NAS/UE/EMM/emm_main.c | 89 +++++++++++++++------------------- openair3/NAS/UE/EMM/emm_main.h | 2 +- openair3/NAS/UE/nas_proc.c | 2 +- openair3/NAS/UE/nas_ue_task.c | 9 +++- openair3/NAS/UE/user_defs.h | 1 + 5 files changed, 50 insertions(+), 53 deletions(-) diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 980deb1583..c64fd6df26 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -344,50 +344,43 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c */ memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); user->emm_data->nvdata.eplmn.n_plmns = 0; - /* Get EMM data pathname */ - char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); - if (path == NULL) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); - } else { - /* Get EMM data stored in the non-volatile memory device */ - int rc = memory_read(path, &user->emm_data->nvdata, sizeof(emm_nvdata_t)); + /* Get EMM data stored in the non-volatile memory device */ + int rc = memory_read(user->emm_nvdata_store, &user->emm_data->nvdata, sizeof(emm_nvdata_t)); - if (rc != RETURNok) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to read %s", path); - } else { - /* Check the IMSI */ - LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); - user->emm_data->imsi = &user->usim_data.imsi; - int imsi_ok = _emm_main_imsi_cmp(&user->emm_data->nvdata.imsi, - &user->usim_data.imsi); + if (rc != RETURNok) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to read %s", user->emm_nvdata_store); + exit(EXIT_FAILURE); + } - if (!imsi_ok) { - LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed nvram: " - "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x, " - "usim: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", - user->emm_data->nvdata.imsi.u.value[0], - user->emm_data->nvdata.imsi.u.value[1], - user->emm_data->nvdata.imsi.u.value[2], - user->emm_data->nvdata.imsi.u.value[3], - user->emm_data->nvdata.imsi.u.value[4], - user->emm_data->nvdata.imsi.u.value[5], - user->emm_data->nvdata.imsi.u.value[6], - user->emm_data->nvdata.imsi.u.value[7], - user->usim_data.imsi.u.value[0], - user->usim_data.imsi.u.value[1], - user->usim_data.imsi.u.value[2], - user->usim_data.imsi.u.value[3], - user->usim_data.imsi.u.value[4], - user->usim_data.imsi.u.value[5], - user->usim_data.imsi.u.value[6], - user->usim_data.imsi.u.value[7]); - memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); - user->emm_data->nvdata.eplmn.n_plmns = 0; - } - } + /* Check the IMSI */ + LOG_TRACE(INFO, "EMM-MAIN - EMM data successfully read"); + user->emm_data->imsi = &user->usim_data.imsi; + int imsi_ok = _emm_main_imsi_cmp(&user->emm_data->nvdata.imsi, + &user->usim_data.imsi); - free(path); + if (!imsi_ok) { + LOG_TRACE(WARNING, "EMM-MAIN - IMSI checking failed nvram: " + "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x, " + "usim: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", + user->emm_data->nvdata.imsi.u.value[0], + user->emm_data->nvdata.imsi.u.value[1], + user->emm_data->nvdata.imsi.u.value[2], + user->emm_data->nvdata.imsi.u.value[3], + user->emm_data->nvdata.imsi.u.value[4], + user->emm_data->nvdata.imsi.u.value[5], + user->emm_data->nvdata.imsi.u.value[6], + user->emm_data->nvdata.imsi.u.value[7], + user->usim_data.imsi.u.value[0], + user->usim_data.imsi.u.value[1], + user->usim_data.imsi.u.value[2], + user->usim_data.imsi.u.value[3], + user->usim_data.imsi.u.value[4], + user->usim_data.imsi.u.value[5], + user->usim_data.imsi.u.value[6], + user->usim_data.imsi.u.value[7]); + memset(&user->emm_data->nvdata.rplmn, 0xFF, sizeof(plmn_t)); + user->emm_data->nvdata.eplmn.n_plmns = 0; } } @@ -437,10 +430,12 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c ** Others: None ** ** ** ***************************************************************************/ -void emm_main_cleanup(emm_data_t *emm_data) +void emm_main_cleanup(nas_user_t *user) { LOG_FUNC_IN; + emm_data_t *emm_data = user->emm_data; + if (emm_data->usim_is_valid) { /* * TODO: Update USIM application data @@ -452,16 +447,10 @@ void emm_main_cleanup(emm_data_t *emm_data) * - Registered PLMN * - List of equivalent PLMNs */ - char *path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); + int rc = memory_write(user->emm_nvdata_store, &emm_data->nvdata, sizeof(emm_nvdata_t)); - if (path == NULL) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to get EMM data pathname"); - } else { - int rc = memory_write(path, &emm_data->nvdata, sizeof(emm_nvdata_t)); - - if (rc != RETURNok) { - LOG_TRACE(ERROR, "EMM-MAIN - Failed to write %s", path); - } + if (rc != RETURNok) { + LOG_TRACE(ERROR, "EMM-MAIN - Failed to write %s", user->emm_nvdata_store); } /* Release dynamically allocated memory */ diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index 1885a42469..aa98965b04 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -70,7 +70,7 @@ typedef int (*emm_indication_callback_t) (user_api_id_t *user_api_id, Stat_t, ta void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const char *imei); -void emm_main_cleanup(emm_data_t *emm_data); +void emm_main_cleanup(nas_user_t *user); /* User's getter of UE's identity */ diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index b5ecc6a6ed..97ecea8e5a 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -138,7 +138,7 @@ void nas_proc_cleanup(nas_user_t *user) /* Perform the EPS Mobility Manager's clean up procedure */ - emm_main_cleanup(user->emm_data); + emm_main_cleanup(user); /* Perform the EPS Session Manager's clean up procedure */ esm_main_cleanup(user->esm_data); diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index af176bd169..8393f0c786 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -105,7 +105,14 @@ void *nas_ue_task(void *args_p) /* Get UE's data pathname */ user->user_nvdata_store = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); if ( user->user_nvdata_store == NULL ) { - LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); + LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid); + exit(EXIT_FAILURE); + } + + /* Get EMM data pathname */ + user->emm_nvdata_store = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); + if ( user->emm_nvdata_store == NULL ) { + LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid); exit(EXIT_FAILURE); } diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index ac16e39ef6..63eb860d80 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -70,6 +70,7 @@ typedef struct { // Eps Mobility Management emm_fsm_state_t emm_fsm_status; // Current EPS Mobility Management status emm_data_t *emm_data; // EPS mobility management data + const char *emm_nvdata_store; emm_plmn_list_t *emm_plmn_list; // list of PLMN identities authentication_data_t *authentication_data; security_data_t *security_data; //Internal data used for security mode control procedure From b43c6cbfdd1604a1fc6eddf738a458ee605ce90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 25 Jul 2016 09:06:58 +0200 Subject: [PATCH 188/571] nas_ue_task: add support for multiple UE --- common/utils/utils.c | 13 ++++++++ common/utils/utils.h | 2 ++ openair3/NAS/UE/nas_ue_task.c | 58 +++++++++++++++++++++++++++++------ openair3/NAS/UE/nas_ue_task.h | 12 ++++++++ targets/COMMON/create_tasks.c | 4 ++- 5 files changed, 78 insertions(+), 11 deletions(-) diff --git a/common/utils/utils.c b/common/utils/utils.c index fed85c4213..cf5673fa56 100644 --- a/common/utils/utils.c +++ b/common/utils/utils.c @@ -72,3 +72,16 @@ void hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int si hex_value[i] = (hex_char_to_hex_value(hex_string[2 * i]) << 4) | hex_char_to_hex_value(hex_string[2 * i + 1]); } } + +char *itoa(int i) { + char buffer[64]; + int ret; + + ret = snprintf(buffer, sizeof(buffer), "%d",i); + if ( ret <= 0 ) { + return NULL; + } + + return strdup(buffer); +} + diff --git a/common/utils/utils.h b/common/utils/utils.h index 3114569b4e..a4444a7793 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -12,4 +12,6 @@ uint8_t hex_char_to_hex_value (char c); // Converts an hexadecimal ASCII coded string into its value.** void hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); +char *itoa(int i); + #endif diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 8393f0c786..efb17a13c2 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -42,7 +42,9 @@ extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; -static int nas_ue_process_events(nas_user_t *user, struct epoll_event *events, int nb_events) +char *make_port_str_from_ueid(const char *base_port_str, int ueid); + +static int nas_ue_process_events(nas_user_container_t *users, struct epoll_event *events, int nb_events) { int event; int exit_loop = FALSE; @@ -52,7 +54,8 @@ static int nas_ue_process_events(nas_user_t *user, struct epoll_event *events, i for (event = 0; event < nb_events; event++) { if (events[event].events != 0) { /* If the event has not been yet been processed (not an itti message) */ - if (events[event].data.fd == user_api_get_fd(user->user_api_id)) { + nas_user_t *user = find_user_from_fd(users, events[event].data.fd); + if ( user != NULL ) { exit_loop = nas_user_receive_and_process(user, NULL); } else { LOG_E(NAS, "[UE] Received an event from an unknown fd %d!\n", events[event].data.fd); @@ -67,13 +70,17 @@ static int nas_ue_process_events(nas_user_t *user, struct epoll_event *events, i void nas_user_api_id_initialize(nas_user_t *user) { user_api_id_t *user_api_id = calloc_or_fail(sizeof(user_api_id_t)); user->user_api_id = user_api_id; - - if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, NAS_PARSER_DEFAULT_USER_PORT_NUMBER, NULL, + char *port = make_port_str_from_ueid(NAS_PARSER_DEFAULT_USER_PORT_NUMBER, user->ueid); + if ( port == NULL ) { + LOG_E(NAS, "[UE %d] can't get port from ueid %d !", user->ueid); + exit (EXIT_FAILURE); + } + if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, port, NULL, NULL) != RETURNok) { LOG_E(NAS, "[UE %d] user interface initialization failed!", user->ueid); exit (EXIT_FAILURE); } - + free(port); itti_subscribe_event_fd (TASK_NAS_UE, user_api_get_fd(user_api_id)); } @@ -86,15 +93,16 @@ void *nas_ue_task(void *args_p) instance_t instance; unsigned int Mod_id; int result; - nas_user_t user_value = {}; - nas_user_t *user = &user_value; - - user->ueid = 0; + nas_user_container_t *users=args_p; itti_mark_task_ready (TASK_NAS_UE); MSC_START_USE(); /* Initialize UE NAS (EURECOM-NAS) */ + for (int i=0; i < users->count; i++) { + nas_user_t *user = &users->item[i]; + user->ueid=i; + /* Get USIM data application filename */ user->usim_data_store = memory_get_path(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME); if ( user->usim_data_store == NULL ) { @@ -118,6 +126,7 @@ void *nas_ue_task(void *args_p) /* Initialize user interface (to exchange AT commands with user process) */ nas_user_api_id_initialize(user); + /* allocate needed structures */ user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); user->at_response = calloc_or_fail(sizeof(at_response_t)); user->lowerlayer_data = calloc_or_fail(sizeof(lowerlayer_data_t)); @@ -141,6 +150,7 @@ void *nas_ue_task(void *args_p) msg_name = ITTI_MSG_NAME (msg_p); instance = ITTI_MSG_INSTANCE (msg_p); Mod_id = instance - NB_eNB_INST; + nas_user_t *user = &users->item[Mod_id]; switch (ITTI_MSG_ID(msg_p)) { case INITIALIZE_MESSAGE: @@ -251,10 +261,38 @@ void *nas_ue_task(void *args_p) nb_events = itti_get_events(TASK_NAS_UE, &events); if ((nb_events > 0) && (events != NULL)) { - if (nas_ue_process_events(user, events, nb_events) == TRUE) { + if (nas_ue_process_events(users, events, nb_events) == TRUE) { LOG_E(NAS, "[UE] Received exit loop\n"); } } } } + +nas_user_t *find_user_from_fd(nas_user_container_t *users, int fd) { + for (int i=0; icount; i++) { + nas_user_t *user = &users->item[i]; + if (fd == user_api_get_fd(user->user_api_id)) { + return user; + } + } + return NULL; +} + +char *make_port_str_from_ueid(const char *base_port_str, int ueid) { + int port; + int base_port; + char *endptr = NULL; + + base_port = strtol(base_port_str, &endptr, 10); + if ( base_port_str == endptr ) { + return NULL; + } + + port = base_port + ueid; + if ( port<1 || port > 65535 ) { + return NULL; + } + + return itoa(port); +} #endif diff --git a/openair3/NAS/UE/nas_ue_task.h b/openair3/NAS/UE/nas_ue_task.h index bc58072681..4c7cd14249 100644 --- a/openair3/NAS/UE/nas_ue_task.h +++ b/openair3/NAS/UE/nas_ue_task.h @@ -22,6 +22,18 @@ #ifndef NAS_UE_TASK_H_ #define NAS_UE_TASK_H_ +// FIXME There is multiple definition of NUMBER_OF_UE_MAX +#include "defs.h" +#include "user_defs.h" + +// XXX simple array container for multiple users +typedef struct { + size_t count; + nas_user_t item[NUMBER_OF_UE_MAX]; +} nas_user_container_t; + +nas_user_t *find_user_from_fd(nas_user_container_t *users, int fd); + # if defined(ENABLE_ITTI) void *nas_ue_task(void *args_p); # endif diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 9a1a14baeb..d786cde511 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -85,7 +85,9 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) # if defined(NAS_BUILT_IN_UE) if (ue_nb > 0) { - if (itti_create_task (TASK_NAS_UE, nas_ue_task, NULL) < 0) { + nas_user_container_t users; + users.count = ue_nb; + if (itti_create_task (TASK_NAS_UE, nas_ue_task, &users) < 0) { LOG_E(NAS, "Create task for NAS UE failed\n"); return -1; } From c4707bd8b73728128c6eb553c5f8b2b25c31e03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 3 Aug 2016 08:47:45 -0500 Subject: [PATCH 189/571] UE: fix nvram_data load filename --- openair3/NAS/UE/nas_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 27f632831e..3108858d06 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -162,7 +162,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, user->nas_user_nvdata = calloc_or_fail(sizeof(user_nvdata_t)); /* Get UE data stored in the non-volatile memory device */ - int rc = memory_read(user->usim_data_store, user->nas_user_nvdata, sizeof(user_nvdata_t)); + int rc = memory_read(user->user_nvdata_store, user->nas_user_nvdata, sizeof(user_nvdata_t)); if (rc != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", user->nas_user_nvdata); } From 17d155325a29ec1ca650b608b733f8797fbf8fb2 Mon Sep 17 00:00:00 2001 From: Imad ALAWE Date: Tue, 26 Jul 2016 14:06:57 +0200 Subject: [PATCH 190/571] feat: add conf2uedata tool for generating .*.nvram This patch adds the conf2uedata tool for generating .ue.nvram* .ue.emm.nvram* and .usim.nvram* files from a textual configuration file. The configuration file define most usefull values like plmns, mnc, mcc, msin, K, OPc for several users. The files generated will always ends with a number corresponding to the user entry in the configuration file. This breaks oai5g because other script have not be updated for using conf2uedata. This breaks also the at_nas_ue command. Examples of configuration files are in openair3/NAS/TOOLS/ --- cmake_targets/build_oai | 44 +- cmake_targets/nas_sim_tools/CMakeLists.txt | 54 +- cmake_targets/tools/build_helper | 19 +- openair3/NAS/COMMON/UTIL/memory.c | 24 + openair3/NAS/COMMON/UTIL/memory.h | 2 + openair3/NAS/TOOLS/Makefile | 79 - openair3/NAS/TOOLS/conf2uedata.c | 1146 +++++++++ openair3/NAS/TOOLS/conf2uedata.h | 153 ++ openair3/NAS/TOOLS/ue_bcom_test.conf | 2334 +++++++++++++++++++ openair3/NAS/TOOLS/ue_data.c | 536 ----- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 112 + openair3/NAS/TOOLS/usim_data.c | 668 ------ openair3/NAS/UE/API/USIM/aka_functions.c | 16 +- openair3/NAS/UE/API/USIM/usim_api.c | 24 +- openair3/NAS/UE/API/USIM/usim_api.h | 2 +- openair3/NAS/UE/nas_ue_task.c | 8 +- 16 files changed, 3827 insertions(+), 1394 deletions(-) delete mode 100644 openair3/NAS/TOOLS/Makefile create mode 100644 openair3/NAS/TOOLS/conf2uedata.c create mode 100644 openair3/NAS/TOOLS/conf2uedata.h create mode 100644 openair3/NAS/TOOLS/ue_bcom_test.conf delete mode 100644 openair3/NAS/TOOLS/ue_data.c create mode 100644 openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf delete mode 100644 openair3/NAS/TOOLS/usim_data.c diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 0a64c0a672..ea28a7131a 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -82,7 +82,7 @@ Options --eNB Makes the LTE softmodem --UE - Makes the UE specific parts (ue_ip, usim, nvram) + Makes the UE specific parts (ue_ip, usim, nvram) from the given configuration file --RRH Makes the RRH -a | --agent @@ -145,6 +145,10 @@ Usage (Regular): function main() { + + local gen_nvram_path=$OPENAIR_DIR/targets/bin + local conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf + until [ -z "$1" ] do case "$1" in @@ -182,7 +186,16 @@ function main() { --UE) UE=1 echo_info "Will compile UE" - shift;; + shift + if test -n "$1" + then + [ -f "$1" ] || echo_fatal "file invalid for --UE" + conf_nvram_path=$(readlink -f "$1") + shift 1 + fi;; + --UE-OUTPUT) + gen_nvram_path=$(readlink -f $2) + shift 2;; --RRH) RRH=1 echo_info "Will compile RRH" @@ -507,20 +520,12 @@ function main() { cmake .. compilations \ - nas_sim_tools usim \ - usim $dbin/usim - compilations \ - nas_sim_tools nvram \ - nvram $dbin/nvram + nas_sim_tools conf2uedata \ + conf2uedata $dbin/conf2uedata # generate USIM data - if [ -f $dbin/nvram ]; then - install_nas_tools $dbin $dconf - echo_info "Copying UE specific part to $DIR/$lte_build_dir/build" - cp -Rvf $dbin/.ue_emm.nvram $DIR/$lte_build_dir/build - cp -Rvf $dbin/.ue.nvram $DIR/$lte_build_dir/build - cp -Rvf $dbin/.usim.nvram $DIR/$lte_build_dir/build - + if [ -f $dbin/conf2uedata ]; then + install_nas_tools $conf_nvram_path $gen_nvram_path else echo_warning "not generated UE NAS files: binaries not found" fi @@ -637,15 +642,12 @@ function main() { cd $DIR/nas_sim_tools/build cmake .. compilations \ - nas_sim_tools usim \ - usim $dbin/usim - compilations \ - nas_sim_tools nvram \ - nvram $dbin/nvram + nas_sim_tools conf2uedata \ + conf2uedata $dbin/conf2uedata # generate USIM data - if [ -f $dbin/nvram ]; then - install_nas_tools $dbin $dconf + if [ -f $dbin/conf2uedata ]; then + install_nas_tools $conf_nvram_path $gen_nvram_path else echo_warning "not generated UE NAS files: binaries not found" fi diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 897e4a1773..123b274714 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -2,25 +2,21 @@ cmake_minimum_required(VERSION 2.8) project(NAS_SIM_TOOLS) +include(FindPkgConfig) +pkg_search_module(CONFIG libconfig REQUIRED) +include_directories(${CONFIG_INCLUDE_DIRS}) +add_definitions(-std=gnu99) ENABLE_LANGUAGE(C) -#Sends the -std=c99 flag to the gcc compiler -add_definitions(-std=c99) -add_definitions(-DNAS_UE) + +set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat") set(OPENAIR_DIR $ENV{OPENAIR_DIR}) -set(OPENAIR1_DIR $ENV{OPENAIR_DIR}/openair1) -set(OPENAIR2_DIR $ENV{OPENAIR_DIR}/openair2) set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3) -set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3) -set(OPENAIR_TARGETS $ENV{OPENAIR_DIR}/targets) -#set(EXECUTABLE_OUTPUT_PATH ${OPENAIR_DIR}/targets/bin) - - -# Add .h files for dependancies -set(usim_SRC - ${OPENAIR_DIR}/openair3/NAS/TOOLS/usim_data.c +set(conf2uedata_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c @@ -29,8 +25,9 @@ set(usim_SRC ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.c ${OPENAIR_DIR}/common/utils/utils.c ) -set(usim_HDR - ${OPENAIR_DIR}/openair3/NAS/TOOLS/network.h + +set(conf2uedata_HDR + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.h ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.h ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.h ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h @@ -39,37 +36,18 @@ set(usim_HDR ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.h ${OPENAIR_DIR}/common/utils/utils.h ) + include_directories( ${OPENAIR_DIR}/common/utils ${OPENAIR_DIR}/openair3/NAS/UE ${OPENAIR_DIR}/openair3/NAS/COMMON + ${OPENAIR_DIR}/openair3/NAS/UE/API/USER ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM ${OPENAIR_DIR}/openair3/NAS/UE/EMM/ ${OPENAIR_DIR}/openair3/NAS/UE/ESM/ ${OPENAIR_DIR}/openair3/NAS/COMMON/IES/ ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL ) -ADD_EXECUTABLE(usim ${usim_SRC} ${usim_HDR}) - - - -set(nvram_SRC - ${OPENAIR_DIR}/openair3/NAS/TOOLS/ue_data.c - ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c - ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c -) - -set(nvram_HDR - ${OPENAIR_DIR}/openair3/NAS/UE/EMM/emmData.h - ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h - ${OPENAIR_DIR}/openair3/NAS/COMMON/userDef.h -) - -ADD_EXECUTABLE(nvram ${nvram_SRC} ${nvram_HDR}) - -#install (TARGETS usim DESTINATION ${EXECUTABLE_OUTPUT_PATH}) -#install (TARGETS nvram DESTINATION ${EXECUTABLE_OUTPUT_PATH}) - -#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/nvram --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)") -#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/usim --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)") +ADD_EXECUTABLE(conf2uedata ${conf2uedata_SRC} ${conf2uedata_HDR}) +target_link_libraries(conf2uedata ${CONFIG_LIBRARIES}) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 448d54f334..8a9d64b6d8 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -450,24 +450,13 @@ install_asn1c_from_source(){ ################################################ install_nas_tools() { - cd $1 - if [ ! -f .ue.nvram ]; then - echo_success "generate .ue_emm.nvram .ue.nvram" - ./nvram --gen - else - [ ./nvram -nt .ue.nvram -o ./nvram -nt .ue_emm.nvram ] && ./nvram --gen + if [ ! -f $2/§.ue.nvram -o ! -f $2/.usim.nvram ]; then + cd $OPENAIR_DIR/targets/bin + ./conf2uedata -c $1 -o $2 + echo_success "$1 $2" fi - - if [ ! -f .usim.nvram ]; then - echo_success "generate .usim.nvram" - ./usim --gen - else - [ ./usim -nt .usim.nvram ] && ./usim --gen - fi - } - ################################ # set_openair_env ############################### diff --git a/openair3/NAS/COMMON/UTIL/memory.c b/openair3/NAS/COMMON/UTIL/memory.c index df94d40cfc..3b3b6e7f9e 100644 --- a/openair3/NAS/COMMON/UTIL/memory.c +++ b/openair3/NAS/COMMON/UTIL/memory.c @@ -103,6 +103,30 @@ char* memory_get_path(const char* dirname, const char* filename) return data_filename; } +char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid) +{ + /* Get non-volatile data directory */ + const char* path = getenv(dirname); + char buffer[2048]; + + if (path == NULL) { + path = getenv(DEFAULT_NAS_PATH); + } + + if (path == NULL) { + LOG_TRACE(WARNING, "MEMORY - %s and %s environment variables are not defined trying local directory", dirname, DEFAULT_NAS_PATH); + path = "."; + } + + /* Append non-volatile data file name */ + if ( snprintf(buffer, sizeof(buffer), "%s/%s%d", path, filename, ueid) < 0 ) { + return NULL; + } + + return strdup(buffer); +} + + /**************************************************************************** ** ** ** Name: memory_read() ** diff --git a/openair3/NAS/COMMON/UTIL/memory.h b/openair3/NAS/COMMON/UTIL/memory.h index f41f4d586b..f7f0733044 100644 --- a/openair3/NAS/COMMON/UTIL/memory.h +++ b/openair3/NAS/COMMON/UTIL/memory.h @@ -58,6 +58,8 @@ Description Memory access utilities char* memory_get_path(const char* dirname, const char* filename); +char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid); + int memory_read(const char* datafile, void* data, size_t size); int memory_write(const char* datafile, const void* data, size_t size); diff --git a/openair3/NAS/TOOLS/Makefile b/openair3/NAS/TOOLS/Makefile deleted file mode 100644 index ca2e884c11..0000000000 --- a/openair3/NAS/TOOLS/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -#/* -# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more -# * contributor license agreements. See the NOTICE file distributed with -# * this work for additional information regarding copyright ownership. -# * The OpenAirInterface Software Alliance licenses this file to You under -# * the OAI Public License, Version 1.0 (the "License"); you may not use this file -# * except in compliance with the License. -# * You may obtain a copy of the License at -# * -# * http://www.openairinterface.org/?page_id=698 -# * -# * Unless required by applicable law or agreed to in writing, software -# * distributed under the License is distributed on an "AS IS" BASIS, -# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# * See the License for the specific language governing permissions and -# * limitations under the License. -# *------------------------------------------------------------------------------- -# * For more information about the OpenAirInterface (OAI) Software Alliance: -# * contact@openairinterface.org -# */ - -export PROCESS = UE - -ifndef PROJDIR -PROJDIR = $(PWD)/.. -endif - -include $(PROJDIR)/Makerules -include $(PROJDIR)/Makefile.inc -include $(PROJDIR)/../Makefile.tools - -export LD_RUN_PATH = $(LIBDIR):$(LIBPROCESS) - -LIBS = -luenas.a -lrt -INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(USIMAPIDIR) -I$(EMMDIR) -I$(ESMDIR) -I$(IESDIR) - -#LIBSUTIL = $(LIBDIR)/$(LIBUTIL).a $(LIBDIR)/$(LIBUTIL).so - -USIM_OBJ = usim_data.o -UE_OBJ = ue_data.o - -USIM_TARGET = usim_data -UE_TARGET = ue_data - -TARGETS = $(USIM_TARGET) $(UE_TARGET) - -all: $(TARGETS) - -#-DIMSI_USA_MNC_3DIGITS -%.o: %.c Makefile - $(CC) $(CFLAGS) -c $< -o $@ - -$(USIM_TARGET): $(USIM_OBJ) $(LIBSUTIL) - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -lnettle -lcrypto -lm - @echo Replacing $@ to $(BINDIR) - @$(RM) $(BINDIR)/$@ - @$(CP) $@ $(BINDIR) - -$(UE_TARGET): $(UE_OBJ) $(LIBSUTIL) - $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -lnettle -lcrypto -lm - @echo Replacing $@ to $(BINDIR) - @$(RM) $(BINDIR)/$@ - @$(CP) $@ $(BINDIR) - -clean: - $(RM) $(OBJS) *.bak *~ - -veryclean: clean - $(RM) $(TARGETS) - -veryveryclean: veryclean - $(RM) -Rf *.o $(PROJDIR) - $(RM) -Rf *.a $(PROJDIR) - -depend: - makedepend -- ${CFLAGS} -- ${SRCS} - -# DO NOT DELETE THIS LINE -- make depend depends on it. - diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c new file mode 100644 index 0000000000..a5aaf9ccb0 --- /dev/null +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -0,0 +1,1146 @@ +#include // perror, printf, fprintf, snprintf +#include // exit, free +#include // memset, strncpy + +#include "conf2uedata.h" +#include "user_api.h" +#include "utils.h" + +char * make_filename(const char *output_dir, const char *filename, int ueid); + +int main(int argc, char**argv) { + int rc = EXIT_SUCCESS; + int option; + while ((option = getopt(argc, argv, options)) != -1) { + switch (option) { + case 'c': + parse_data = TRUE; + conf_file = optarg; + break; + case 'o': + output_dir = optarg; + output = TRUE; + break; + case 'h': + _display_usage(); + return EXIT_SUCCESS; + break; + default: + break; + } + } + if (output == FALSE && parse_data == TRUE) { + printf("No output option found\n"); + _display_usage(); + return EXIT_FAILURE; + } else if (output == TRUE && parse_data == FALSE) { + printf("No Configuration file is given\n"); + _display_usage(); + return EXIT_FAILURE; + } else if (parse_data == FALSE && print_data == FALSE) { + printf("No options found\n"); + _display_usage(); + return EXIT_FAILURE; + } else if (parse_data) { + int ue_nb = 0; + config_t cfg; + config_setting_t *root_setting = NULL; + config_setting_t *ue_setting = NULL; + config_setting_t *all_plmn_setting = NULL; + char user[10]; + config_init(&cfg); + if (conf_file != NULL) { + /* Read the file. If there is an error, report it and exit. */ + if (!config_read_file(&cfg, conf_file)) { + fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), + config_error_line(&cfg), config_error_text(&cfg)); + config_destroy(&cfg); + return (EXIT_FAILURE); + } + } else { + config_destroy(&cfg); + perror("ERROR\t: config_read failed"); + exit(EXIT_FAILURE); + } + root_setting = config_root_setting(&cfg); + ue_nb = config_setting_length(root_setting) - 1; + all_plmn_setting = config_setting_get_member(root_setting, PLMN); + if (all_plmn_setting != NULL) { + rc = parse_plmns(all_plmn_setting); + if (rc == EXIT_FAILURE) { + return rc; + } + fill_network_record_list(); + for (int i = 0; i < ue_nb; i++) { + sprintf(user, "%s%d", UE, i); + ue_setting = config_setting_get_member(root_setting, user); + if (ue_setting != NULL) { + rc = parse_ue_user_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + printf("Problem in USER section for UE%d. EXITING...\n", + i); + return EXIT_FAILURE; + } + _display_ue_data(i); + rc = parse_ue_sim_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + printf("Problem in SIM section for UE%d. EXITING...\n", + i); + return EXIT_FAILURE; + } + rc = parse_ue_plmn_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + return EXIT_FAILURE; + } + gen_emm_data(i); + _display_emm_data(i); + gen_usim_data(i); + _display_usim_data(i); + } else { + printf("Check UE%d settings\n", i); + return EXIT_FAILURE; + } + } + config_destroy(&cfg); + + } else { + printf("NO PLMN SECTION...EXITING...\n"); + return (EXIT_FAILURE); + } + } + exit(EXIT_SUCCESS); + +} + +void gen_usim_data(int user_id) { + usim_data_t usim_data = { }; + memset(&usim_data, 0, sizeof(usim_data_t)); + usim_data.imsi.length = 8; + usim_data.imsi.u.num.parity = get_msin_parity(msin); + + usim_data.imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; + usim_data.imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; + usim_data.imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + + usim_data.imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; + usim_data.imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; + + if (strlen(user_plmn_list[hplmn_index].mnc) == 2) { + usim_data.imsi.u.num.digit6 = msin[0]; + usim_data.imsi.u.num.digit7 = msin[1]; + usim_data.imsi.u.num.digit8 = msin[2]; + usim_data.imsi.u.num.digit9 = msin[3]; + usim_data.imsi.u.num.digit10 = msin[4]; + usim_data.imsi.u.num.digit11 = msin[5]; + usim_data.imsi.u.num.digit12 = msin[6]; + usim_data.imsi.u.num.digit13 = msin[7]; + usim_data.imsi.u.num.digit14 = msin[8]; + usim_data.imsi.u.num.digit15 = msin[9]; + } else { + usim_data.imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + usim_data.imsi.u.num.digit7 = msin[0]; + usim_data.imsi.u.num.digit8 = msin[1]; + usim_data.imsi.u.num.digit9 = msin[2]; + usim_data.imsi.u.num.digit10 = msin[3]; + usim_data.imsi.u.num.digit11 = msin[4]; + usim_data.imsi.u.num.digit12 = msin[5]; + usim_data.imsi.u.num.digit13 = msin[6]; + usim_data.imsi.u.num.digit14 = msin[7]; + usim_data.imsi.u.num.digit15 = msin[8]; + } + + /* + * Ciphering and Integrity Keys + */ + usim_data.keys.ksi = KSI; + memset(&usim_data.keys.ck, 0, USIM_CK_SIZE); + memset(&usim_data.keys.ik, 0, USIM_IK_SIZE); + /* + * Higher Priority PLMN search period + */ + usim_data.hpplmn = 0x00; /* Disable timer */ + + /* + * List of Forbidden PLMNs + */ + for (int i = 0; i < USIM_FPLMN_MAX; i++) { + memset(&usim_data.fplmn[i], 0xff, sizeof(plmn_t)); + } + if (fplmn_nb > 0) { + for (int i = 0; i < fplmn_nb; i++) { + usim_data.fplmn[i] = user_network_record_list[fplmn[i]].plmn; + } + } + + /* + * Location Information + */ + usim_data.loci.tmsi = DEFAULT_TMSI; + usim_data.loci.lai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data.loci.lai.lac = DEFAULT_LAC; + usim_data.loci.status = USIM_LOCI_NOT_UPDATED; + /* + * Packet Switched Location Information + */ + usim_data.psloci.p_tmsi = DEFAULT_P_TMSI; + usim_data.psloci.signature[0] = 0x01; + usim_data.psloci.signature[1] = 0x02; + usim_data.psloci.signature[2] = 0x03; + usim_data.psloci.rai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data.psloci.rai.lac = DEFAULT_LAC; + usim_data.psloci.rai.rac = DEFAULT_RAC; + usim_data.psloci.status = USIM_PSLOCI_NOT_UPDATED; + /* + * Administrative Data + */ + usim_data.ad.UE_Operation_Mode = USIM_NORMAL_MODE; + usim_data.ad.Additional_Info = 0xffff; + usim_data.ad.MNC_Length = strlen(user_plmn_list[hplmn_index].mnc); + /* + * EPS NAS security context + */ + usim_data.securityctx.length = 52; + usim_data.securityctx.KSIasme.type = USIM_KSI_ASME_TAG; + usim_data.securityctx.KSIasme.length = 1; + usim_data.securityctx.KSIasme.value[0] = KSI_ASME; + usim_data.securityctx.Kasme.type = USIM_K_ASME_TAG; + usim_data.securityctx.Kasme.length = USIM_K_ASME_SIZE; + memset(usim_data.securityctx.Kasme.value, 0, + usim_data.securityctx.Kasme.length); + usim_data.securityctx.ulNAScount.type = USIM_UL_NAS_COUNT_TAG; + usim_data.securityctx.ulNAScount.length = USIM_UL_NAS_COUNT_SIZE; + memset(usim_data.securityctx.ulNAScount.value, 0, + usim_data.securityctx.ulNAScount.length); + usim_data.securityctx.dlNAScount.type = USIM_DL_NAS_COUNT_TAG; + usim_data.securityctx.dlNAScount.length = USIM_DL_NAS_COUNT_SIZE; + memset(usim_data.securityctx.dlNAScount.value, 0, + usim_data.securityctx.dlNAScount.length); + usim_data.securityctx.algorithmID.type = USIM_INT_ENC_ALGORITHMS_TAG; + usim_data.securityctx.algorithmID.length = 1; + usim_data.securityctx.algorithmID.value[0] = SECURITY_ALGORITHMS; + /* + * Subcriber's Number + */ + usim_data.msisdn.length = 7; + usim_data.msisdn.number.ext = 1; + usim_data.msisdn.number.ton = MSISDN_TON_UNKNOWKN; + usim_data.msisdn.number.npi = MSISDN_NPI_ISDN_TELEPHONY; + usim_data.msisdn.conf1_record_id = 0xff; /* Not used */ + usim_data.msisdn.ext1_record_id = 0xff; /* Not used */ + int j = 0; + for (int i = 0; i < strlen(msisdn); i += 2) { + usim_data.msisdn.number.digit[j].msb = msisdn[i]; + j++; + } + j = 0; + for (int i = 1; i < strlen(msisdn); i += 2) { + usim_data.msisdn.number.digit[j].lsb = msisdn[i]; + j++; + + } + if (strlen(msisdn) % 2 == 0) { + for (int i = strlen(msisdn) / 2; i < 10; i++) { + usim_data.msisdn.number.digit[i].msb = 0xf; + usim_data.msisdn.number.digit[i].lsb = 0xf; + } + } else { + usim_data.msisdn.number.digit[strlen(msisdn) / 2].lsb = 0xf; + for (int i = (strlen(msisdn) / 2) + 1; i < 10; i++) { + usim_data.msisdn.number.digit[i].msb = 0xf; + usim_data.msisdn.number.digit[i].lsb = 0xf; + } + } + /* + * PLMN Network Name and Operator PLMN List + */ + for (int i = 0; i < oplmn_nb; i++) { + network_record_t record = user_network_record_list[oplmn[i]]; + usim_data.pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; + usim_data.pnn[i].fullname.length = strlen(record.fullname); + strncpy((char*) usim_data.pnn[i].fullname.value, record.fullname, + usim_data.pnn[i].fullname.length); + usim_data.pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG; + usim_data.pnn[i].shortname.length = strlen(record.shortname); + strncpy((char*) usim_data.pnn[i].shortname.value, record.shortname, + usim_data.pnn[i].shortname.length); + usim_data.opl[i].plmn = record.plmn; + usim_data.opl[i].start = record.tac_start; + usim_data.opl[i].end = record.tac_end; + usim_data.opl[i].record_id = i; + } + if (oplmn_nb < USIM_OPL_MAX) { + for (int i = oplmn_nb; i < USIM_OPL_MAX; i++) { + memset(&usim_data.opl[i].plmn, 0xff, sizeof(plmn_t)); + } + } + + /* + * List of Equivalent HPLMNs + */ + for (int i = 0; i < ehplmn_nb; i++) { + usim_data.ehplmn[i] = user_network_record_list[ehplmn[i]].plmn; + } + if (ehplmn_nb < USIM_EHPLMN_MAX) { + for (int i = ehplmn_nb; i < USIM_EHPLMN_MAX; i++) { + memset(&usim_data.ehplmn[i], 0xff, sizeof(plmn_t)); + } + } + /* + * Home PLMN Selector with Access Technology + */ + usim_data.hplmn.plmn = user_network_record_list[hplmn_index].plmn; + usim_data.hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); + + /* + * List of user controlled PLMN selector with Access Technology + */ + for (int i = 0; i < USIM_PLMN_MAX; i++) { + memset(&usim_data.plmn[i], 0xff, sizeof(plmn_t)); + } + if (ucplmn_nb > 0) { + for (int i = 0; i < ucplmn_nb; i++) { + usim_data.plmn[i].plmn = user_network_record_list[ucplmn[i]].plmn; + } + } + + // List of operator controlled PLMN selector with Access Technology + + for (int i = 0; i < USIM_OPLMN_MAX; i++) { + memset(&usim_data.oplmn[i], 0xff, sizeof(plmn_t)); + } + if (ocplmn_nb > 0) { + for (int i = 0; i < ocplmn_nb; i++) { + usim_data.oplmn[i].plmn = user_network_record_list[ocplmn[i]].plmn; + usim_data.oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN + | USIM_ACT_EUTRAN); + } + } + /* + * EPS Location Information + */ + usim_data.epsloci.guti.gummei.plmn = + user_network_record_list[hplmn_index].plmn; + usim_data.epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID; + usim_data.epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE; + usim_data.epsloci.guti.m_tmsi = DEFAULT_M_TMSI; + usim_data.epsloci.tai.plmn = usim_data.epsloci.guti.gummei.plmn; + usim_data.epsloci.tai.tac = DEFAULT_TAC; + usim_data.epsloci.status = USIM_EPSLOCI_UPDATED; + /* + * Non-Access Stratum configuration + */ + usim_data.nasconfig.NAS_SignallingPriority.type = + USIM_NAS_SIGNALLING_PRIORITY_TAG; + usim_data.nasconfig.NAS_SignallingPriority.length = 1; + usim_data.nasconfig.NAS_SignallingPriority.value[0] = 0x00; + usim_data.nasconfig.NMO_I_Behaviour.type = USIM_NMO_I_BEHAVIOUR_TAG; + usim_data.nasconfig.NMO_I_Behaviour.length = 1; + usim_data.nasconfig.NMO_I_Behaviour.value[0] = 0x00; + usim_data.nasconfig.AttachWithImsi.type = USIM_ATTACH_WITH_IMSI_TAG; + usim_data.nasconfig.AttachWithImsi.length = 1; +#if defined(START_WITH_GUTI) + usim_data.nasconfig.AttachWithImsi.value[0] = 0x00; +#else + usim_data.nasconfig.AttachWithImsi.value[0] = 0x01; +#endif + usim_data.nasconfig.MinimumPeriodicSearchTimer.type = + USIM_MINIMUM_PERIODIC_SEARCH_TIMER_TAG; + usim_data.nasconfig.MinimumPeriodicSearchTimer.length = 1; + usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0] = 0x00; + usim_data.nasconfig.ExtendedAccessBarring.type = + USIM_EXTENDED_ACCESS_BARRING_TAG; + usim_data.nasconfig.ExtendedAccessBarring.length = 1; + usim_data.nasconfig.ExtendedAccessBarring.value[0] = 0x00; + usim_data.nasconfig.Timer_T3245_Behaviour.type = + USIM_TIMER_T3245_BEHAVIOUR_TAG; + usim_data.nasconfig.Timer_T3245_Behaviour.length = 1; + usim_data.nasconfig.Timer_T3245_Behaviour.value[0] = 0x00; + + /* initialize the subscriber authentication security key */ + hex_string_to_hex_value(usim_data.keys.usim_api_k, + usim_api_k, USIM_API_K_SIZE); + hex_string_to_hex_value(usim_data.keys.opc, opc, + OPC_SIZE); + + char *path = make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); + usim_api_write(path, &usim_data); + free(path); +} +void gen_emm_data(int user_id) { + hplmn_index = get_plmn_index(hplmn); + emm_nvdata_t emm_data; + int rc; + memset(&emm_data, 0, sizeof(emm_nvdata_t)); + int hplmn_index = get_plmn_index(hplmn); + emm_data.imsi.length = 8; + emm_data.imsi.u.num.parity = get_msin_parity(msin); + emm_data.imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; + emm_data.imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; + emm_data.imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + + emm_data.imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; + emm_data.imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; + + if (strlen(user_plmn_list[hplmn_index].mnc) == 3) { + emm_data.rplmn.MNCdigit3 = user_plmn_list[hplmn_index].mnc[2]; + + emm_data.imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + emm_data.imsi.u.num.digit7 = msin[0]; + emm_data.imsi.u.num.digit8 = msin[1]; + emm_data.imsi.u.num.digit9 = msin[2]; + emm_data.imsi.u.num.digit10 = msin[3]; + emm_data.imsi.u.num.digit11 = msin[4]; + emm_data.imsi.u.num.digit12 = msin[5]; + emm_data.imsi.u.num.digit13 = msin[6]; + emm_data.imsi.u.num.digit14 = msin[7]; + emm_data.imsi.u.num.digit15 = msin[8]; + + } else { + emm_data.rplmn.MNCdigit3 = 0xf; + + emm_data.imsi.u.num.digit6 = msin[0]; + emm_data.imsi.u.num.digit7 = msin[1]; + emm_data.imsi.u.num.digit8 = msin[2]; + emm_data.imsi.u.num.digit9 = msin[3]; + emm_data.imsi.u.num.digit10 = msin[4]; + emm_data.imsi.u.num.digit11 = msin[5]; + emm_data.imsi.u.num.digit12 = msin[6]; + emm_data.imsi.u.num.digit13 = msin[7]; + emm_data.imsi.u.num.digit14 = msin[8]; + emm_data.imsi.u.num.digit15 = msin[9]; + + } + + emm_data.rplmn.MCCdigit1 = user_plmn_list[hplmn_index].mcc[0]; + emm_data.rplmn.MCCdigit2 = user_plmn_list[hplmn_index].mcc[1]; + emm_data.rplmn.MCCdigit3 = user_plmn_list[hplmn_index].mcc[2]; + emm_data.rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; + emm_data.rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; + + emm_data.eplmn.n_plmns = ehplmn_nb; + + char* path = make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); + rc = memory_write(path, &emm_data, sizeof(emm_nvdata_t)); + free(path); + if (rc != RETURNok) { + perror("ERROR\t: memory_write() failed"); + exit(EXIT_FAILURE); + } + +} + +int parse_plmn_param(config_setting_t *plmn_setting, int index) { + int rc = 0; + rc = config_setting_lookup_string(plmn_setting, + FULLNAME, &user_plmn_list[index].fullname); + if (rc != 1) { + printf("Check PLMN%d FULLNAME. Exiting\n", index); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(plmn_setting, + SHORTNAME, &user_plmn_list[index].shortname); + if (rc != 1) { + printf("Check PLMN%d SHORTNAME. Exiting\n", index); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(plmn_setting, + MNC, &user_plmn_list[index].mnc); + if (rc != 1 || strlen(user_plmn_list[index].mnc) > 3 + || strlen(user_plmn_list[index].mnc) < 2) { + printf("Check PLMN%d MNC. Exiting\n", index); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(plmn_setting, + MCC, &user_plmn_list[index].mcc); + if (rc != 1 || strlen(user_plmn_list[index].mcc) != 3) { + printf("Check PLMN%d MCC. Exiting\n", index); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +int parse_plmns(config_setting_t *all_plmn_setting) { + config_setting_t *plmn_setting = NULL; + char plmn[10]; + int rc = EXIT_SUCCESS; + plmn_nb = config_setting_length(all_plmn_setting); + user_plmn_list = malloc(sizeof(plmn_conf_param_t) * plmn_nb); + user_network_record_list = malloc(sizeof(network_record_t) * plmn_nb); + for (int i = 0; i < plmn_nb; i++) { + memset(&user_network_record_list[i], 0xff, sizeof(network_record_t)); + memset(&user_plmn_list[i], 0xff, sizeof(plmn_conf_param_t)); + } + for (int i = 0; i < plmn_nb; i++) { + sprintf(plmn, "%s%d", PLMN, i); + plmn_setting = config_setting_get_member(all_plmn_setting, plmn); + if (plmn_setting != NULL) { + rc = parse_plmn_param(plmn_setting, i); + if (rc == EXIT_FAILURE) { + return rc; + } + } else { + printf("Problem in PLMN%d. Exiting...\n", i); + return EXIT_FAILURE; + } + } + return rc; +} + +int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id) { + int rc = EXIT_SUCCESS; + config_setting_t *setting = NULL; + rc = config_setting_lookup_string(ue_setting, HPLMN, &hplmn); + if (rc != 1) { + printf("Check HPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } else if (get_plmn_index(hplmn) == -1) { + printf("HPLMN for UE%d is not defined in PLMN section. Exiting\n", + user_id); + return EXIT_FAILURE; + } + setting = config_setting_get_member(ue_setting, UCPLMN); + if (setting == NULL) { + printf("Check UCPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = fill_ucplmn(setting, user_id); + if (rc != EXIT_SUCCESS) { + printf("Check UCPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + setting = config_setting_get_member(ue_setting, OPLMN); + if (setting == NULL) { + printf("Check OPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = fill_oplmn(setting, user_id); + if (rc != EXIT_SUCCESS) { + printf("Check OPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + setting = config_setting_get_member(ue_setting, OCPLMN); + if (setting == NULL) { + printf("Check OCPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = fill_ocplmn(setting, user_id); + if (rc != EXIT_SUCCESS) { + printf("Check OCPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + setting = config_setting_get_member(ue_setting, FPLMN); + if (setting == NULL) { + printf("Check FPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = fill_fplmn(setting, user_id); + if (rc != EXIT_SUCCESS) { + printf("Check FPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + setting = config_setting_get_member(ue_setting, EHPLMN); + if (setting == NULL) { + printf("Check EHPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = fill_ehplmn(setting, user_id); + if (rc != EXIT_SUCCESS) { + printf("Check EHPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +int parse_ue_sim_param(config_setting_t *ue_setting, int user_id) { + int rc = EXIT_SUCCESS; + config_setting_t *ue_param_setting = NULL; + ue_param_setting = config_setting_get_member(ue_setting, SIM); + if (ue_param_setting == NULL) { + printf("Check SIM section for UE%d. EXITING...\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MSIN, &msin); + if (rc != 1 || strlen(msin) > 10 || strlen(msin) < 9) { + printf("Check SIM MSIN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, USIM_API_K, + &usim_api_k); + if (rc != 1) { + printf("Check SIM USIM_API_K section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, OPC, &opc); + if (rc != 1) { + printf("Check SIM OPC section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MSISDN, &msisdn); + if (rc != 1) { + printf("Check SIM MSISDN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +int parse_ue_user_param(config_setting_t *ue_setting, int user_id) { + config_setting_t *ue_param_setting = NULL; + user_nvdata_t user_data; + const char* imei = NULL; + const char* manufacturer = NULL; + const char* model = NULL; + const char* pin = NULL; + + int rc = EXIT_SUCCESS; + ue_param_setting = config_setting_get_member(ue_setting, USER); + if (ue_param_setting == NULL) { + printf("Check USER section of UE%d. EXITING...\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, UE_IMEI, &imei); + if (rc != 1) { + printf("Check USER IMEI section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MANUFACTURER, + &manufacturer); + if (rc != 1) { + printf("Check USER MANUFACTURER for UE%d FULLNAME. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MODEL, &model); + if (rc != 1) { + printf("Check USER MODEL for UE%d FULLNAME. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, PINCODE, &pin); + if (rc != 1) { + printf("Check USER PIN for UE%d FULLNAME. Exiting\n", user_id); + return EXIT_FAILURE; + } + memset(&user_data, 0, sizeof(user_nvdata_t)); + snprintf(user_data.IMEI, USER_IMEI_SIZE + 1, "%s%d", imei, _luhn(imei)); + /* + * Manufacturer identifier + */ + strncpy(user_data.manufacturer, manufacturer, USER_MANUFACTURER_SIZE); + /* + * Model identifier + */ + strncpy(user_data.model, model, USER_MODEL_SIZE); + /* + * SIM Personal Identification Number + */ + strncpy(user_data.PIN, pin, USER_PIN_SIZE); + + char* path = make_filename(output_dir, USER_NVRAM_FILENAME, user_id); + rc = memory_write(path, &user_data, sizeof(user_nvdata_t)); + free(path); + if (rc != RETURNok) { + perror("ERROR\t: memory_write() failed"); + exit(EXIT_FAILURE); + } + return EXIT_SUCCESS; +} + +int fill_ucplmn(config_setting_t* setting, int user_id) { + int rc; + ucplmn_nb = config_setting_length(setting); + ucplmn = malloc(ucplmn_nb * sizeof(int)); + for (int i = 0; i < ucplmn_nb; i++) { + const char *mccmnc = config_setting_get_string_elem(setting, i); + if (mccmnc == NULL) { + printf("Check UCPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = get_plmn_index(mccmnc); + if (rc == -1) { + printf("The PLMN %s is not defined in PLMN section. Exiting...\n", + mccmnc); + return EXIT_FAILURE; + } + ucplmn[i] = rc; + } + return EXIT_SUCCESS; +} +int fill_oplmn(config_setting_t* setting, int user_id) { + int rc; + oplmn_nb = config_setting_length(setting); + oplmn = malloc(oplmn_nb * sizeof(int)); + for (int i = 0; i < oplmn_nb; i++) { + const char *mccmnc = config_setting_get_string_elem(setting, i); + if (mccmnc == NULL) { + printf("Check OPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = get_plmn_index(mccmnc); + if (rc == -1) { + printf("The PLMN %s is not defined in PLMN section. Exiting...\n", + mccmnc); + return EXIT_FAILURE; + } + oplmn[i] = rc; + } + return EXIT_SUCCESS; +} +int fill_ocplmn(config_setting_t* setting, int user_id) { + int rc; + ocplmn_nb = config_setting_length(setting); + ocplmn = malloc(ocplmn_nb * sizeof(int)); + for (int i = 0; i < ocplmn_nb; i++) { + const char *mccmnc = config_setting_get_string_elem(setting, i); + if (mccmnc == NULL) { + printf("Check OCPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = get_plmn_index(mccmnc); + if (rc == -1) { + printf("The PLMN %s is not defined in PLMN section. Exiting...\n", + mccmnc); + return EXIT_FAILURE; + } + ocplmn[i] = rc; + } + return EXIT_SUCCESS; +} +int fill_fplmn(config_setting_t* setting, int user_id) { + int rc; + fplmn_nb = config_setting_length(setting); + fplmn = malloc(fplmn_nb * sizeof(int)); + for (int i = 0; i < fplmn_nb; i++) { + const char *mccmnc = config_setting_get_string_elem(setting, i); + if (mccmnc == NULL) { + printf("Check FPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = get_plmn_index(mccmnc); + if (rc == -1) { + printf("The PLMN %s is not defined in PLMN section. Exiting...\n", + mccmnc); + return EXIT_FAILURE; + } + fplmn[i] = rc; + } + return EXIT_SUCCESS; +} +int fill_ehplmn(config_setting_t* setting, int user_id) { + int rc; + ehplmn_nb = config_setting_length(setting); + ehplmn = malloc(ehplmn_nb * sizeof(int)); + for (int i = 0; i < ehplmn_nb; i++) { + const char *mccmnc = config_setting_get_string_elem(setting, i); + if (mccmnc == NULL) { + printf("Check EHPLMN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = get_plmn_index(mccmnc); + if (rc == -1) { + printf("The PLMN %s is not defined in PLMN section. Exiting...\n", + mccmnc); + return EXIT_FAILURE; + } + ehplmn[i] = rc; + } + return EXIT_SUCCESS; +} + +int get_plmn_index(const char * mccmnc) { + char mcc[4]; + char mnc[strlen(mccmnc) - 2]; + strncpy(mcc, mccmnc, 3); + mcc[3] = '\0'; + strncpy(mnc, mccmnc + 3, 3); + mnc[strlen(mccmnc) - 3] = '\0'; + for (int i = 0; i < plmn_nb; i++) { + if (strcmp(user_plmn_list[i].mcc, mcc) == 0) { + if (strcmp(user_plmn_list[i].mnc, mnc) == 0) { + return i; + } + } + } + return -1; +} + +int get_msin_parity(const char * msin) { + int imsi_size = strlen(msin) + strlen(user_plmn_list[hplmn_index].mcc) + + strlen(user_plmn_list[hplmn_index].mnc); + int result = (imsi_size % 2 == 0) ? 0 : 1; + return result; + +} + +void fill_network_record_list() { + for (int i = 0; i < plmn_nb; i++) { + strcpy(user_network_record_list[i].fullname, + user_plmn_list[i].fullname); + strcpy(user_network_record_list[i].shortname, + user_plmn_list[i].shortname); + char num[6]; + sprintf(num, "%s%s", user_plmn_list[i].mcc, user_plmn_list[i].mnc); + user_network_record_list[i].num = atoi(num); + user_network_record_list[i].plmn.MCCdigit2 = user_plmn_list[i].mcc[1]; + user_network_record_list[i].plmn.MCCdigit1 = user_plmn_list[i].mcc[0]; + user_network_record_list[i].plmn.MCCdigit3 = user_plmn_list[i].mcc[2]; + user_network_record_list[i].plmn.MNCdigit2 = user_plmn_list[i].mnc[1]; + user_network_record_list[i].plmn.MNCdigit1 = user_plmn_list[i].mnc[0]; + user_network_record_list[i].tac_end = 0xfffd; + user_network_record_list[i].tac_start = 0x0001; + if (strlen(user_plmn_list[i].mnc) > 2) { + user_network_record_list[i].plmn.MNCdigit3 = + user_plmn_list[i].mnc[2]; + } + + } +} + +/* + * Computes the check digit using Luhn algorithm + */ +int _luhn(const char* cc) { + const int m[] = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }; + int odd = 1, sum = 0; + + for (int i = strlen(cc); i--; odd = !odd) { + int digit = cc[i] - '0'; + sum += odd ? m[digit] : digit; + } + + return 10 - (sum % 10); +} + +void _display_usim_data(int user_id) { + + int rc; + usim_data_t data = { }; + /* + * Read USIM application data + */ + memset(&data, 0, sizeof(usim_data_t)); + char *path = make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); + rc = usim_api_read(path, &data); + free(path); + + if (rc != RETURNok) { + perror("ERROR\t: usim_api_read() failed"); + exit(EXIT_FAILURE); + } + + /* + * Display USIM application data + */ + printf("\nUSIM data:\n\n"); + int digits; + + printf("Administrative Data:\n"); + printf("\tUE_Operation_Mode\t= 0x%.2x\n", data.ad.UE_Operation_Mode); + printf("\tAdditional_Info\t\t= 0x%.4x\n", data.ad.Additional_Info); + printf("\tMNC_Length\t\t= %d\n\n", data.ad.MNC_Length); + + printf("IMSI:\n"); + printf("\tlength\t= %d\n", data.imsi.length); + printf("\tparity\t= %s\n", + data.imsi.u.num.parity == EVEN_PARITY ? "Even" : "Odd"); + digits = (data.imsi.length * 2) - 1 + - (data.imsi.u.num.parity == EVEN_PARITY ? 1 : 0); + printf("\tdigits\t= %d\n", digits); + printf("\tdigits\t= %u%u%u%u%u%x%u%u%u%u", + data.imsi.u.num.digit1, // MCC digit 1 + data.imsi.u.num.digit2, // MCC digit 2 + data.imsi.u.num.digit3, // MCC digit 3 + data.imsi.u.num.digit4, // MNC digit 1 + data.imsi.u.num.digit5, // MNC digit 2 + data.imsi.u.num.digit6, // MNC digit 3 + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10); + + if (digits >= 11) + printf("%x", data.imsi.u.num.digit11); + + if (digits >= 12) + printf("%x", data.imsi.u.num.digit12); + + if (digits >= 13) + printf("%x", data.imsi.u.num.digit13); + + if (digits >= 14) + printf("%x", data.imsi.u.num.digit14); + + if (digits >= 15) + printf("%x", data.imsi.u.num.digit15); + + printf("\n\n"); + + printf("Ciphering and Integrity Keys:\n"); + printf("\tKSI\t: 0x%.2x\n", data.keys.ksi); + char key[USIM_CK_SIZE + 1]; + key[USIM_CK_SIZE] = '\0'; + memcpy(key, data.keys.ck, USIM_CK_SIZE); + printf("\tCK\t: \"%s\"\n", key); + memcpy(key, data.keys.ik, USIM_IK_SIZE); + printf("\tIK\t: \"%s\"\n", key); + + printf("EPS NAS security context:\n"); + printf("\tKSIasme\t: 0x%.2x\n", data.securityctx.KSIasme.value[0]); + char kasme[USIM_K_ASME_SIZE + 1]; + kasme[USIM_K_ASME_SIZE] = '\0'; + memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE); + printf("\tKasme\t: \"%s\"\n", kasme); + printf("\tulNAScount\t: 0x%.8x\n", + *(uint32_t*) data.securityctx.ulNAScount.value); + printf("\tdlNAScount\t: 0x%.8x\n", + *(uint32_t*) data.securityctx.dlNAScount.value); + printf("\talgorithmID\t: 0x%.2x\n\n", + data.securityctx.algorithmID.value[0]); + + printf("MSISDN\t= %u%u%u %u%u%u%u %u%u%u%u\n\n", + data.msisdn.number.digit[0].msb, data.msisdn.number.digit[0].lsb, + data.msisdn.number.digit[1].msb, data.msisdn.number.digit[1].lsb, + data.msisdn.number.digit[2].msb, data.msisdn.number.digit[2].lsb, + data.msisdn.number.digit[3].msb, data.msisdn.number.digit[3].lsb, + data.msisdn.number.digit[4].msb, data.msisdn.number.digit[4].lsb, + data.msisdn.number.digit[5].msb); + + for (int i = 0; i < USIM_PNN_MAX; i++) { + printf("PNN[%d]\t= {%s, %s}\n", i, data.pnn[i].fullname.value, + data.pnn[i].shortname.value); + } + + printf("\n"); + + for (int i = 0; i < USIM_OPL_MAX; i++) { + printf("OPL[%d]\t= ", i); + PRINT_PLMN(data.opl[i].plmn); + printf(", TAC = [%.4x - %.4x], record_id = %d\n", data.opl[i].start, + data.opl[i].end, data.opl[i].record_id); + } + + printf("\n"); + + printf("HPLMN\t\t= "); + PRINT_PLMN(data.hplmn.plmn); + printf(", AcT = 0x%x\n\n", data.hplmn.AcT); + + for (int i = 0; i < USIM_FPLMN_MAX; i++) { + printf("FPLMN[%d]\t= ", i); + PRINT_PLMN(data.fplmn[i]); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_EHPLMN_MAX; i++) { + printf("EHPLMN[%d]\t= ", i); + PRINT_PLMN(data.ehplmn[i]); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_PLMN_MAX; i++) { + printf("PLMN[%d]\t\t= ", i); + PRINT_PLMN(data.plmn[i].plmn); + printf(", AcTPLMN = 0x%x", data.plmn[i].AcT); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_OPLMN_MAX; i++) { + printf("OPLMN[%d]\t= ", i); + PRINT_PLMN(data.oplmn[i].plmn); + printf(", AcTPLMN = 0x%x", data.oplmn[i].AcT); + printf("\n"); + } + + printf("\n"); + + printf("HPPLMN\t\t= 0x%.2x (%d minutes)\n\n", data.hpplmn, data.hpplmn); + + printf("LOCI:\n"); + printf("\tTMSI = 0x%.4x\n", data.loci.tmsi); + printf("\tLAI\t: PLMN = "); + PRINT_PLMN(data.loci.lai.plmn); + printf(", LAC = 0x%.2x\n", data.loci.lai.lac); + printf("\tstatus\t= %d\n\n", data.loci.status); + + printf("PSLOCI:\n"); + printf("\tP-TMSI = 0x%.4x\n", data.psloci.p_tmsi); + printf("\tsignature = 0x%x 0x%x 0x%x\n", data.psloci.signature[0], + data.psloci.signature[1], data.psloci.signature[2]); + printf("\tRAI\t: PLMN = "); + PRINT_PLMN(data.psloci.rai.plmn); + printf(", LAC = 0x%.2x, RAC = 0x%.1x\n", data.psloci.rai.lac, + data.psloci.rai.rac); + printf("\tstatus\t= %d\n\n", data.psloci.status); + + printf("EPSLOCI:\n"); + printf("\tGUTI\t: GUMMEI\t: (PLMN = "); + PRINT_PLMN(data.epsloci.guti.gummei.plmn); + printf(", MMEgid = 0x%.2x, MMEcode = 0x%.1x)", + data.epsloci.guti.gummei.MMEgid, data.epsloci.guti.gummei.MMEcode); + printf(", M-TMSI = 0x%.4x\n", data.epsloci.guti.m_tmsi); + printf("\tTAI\t: PLMN = "); + PRINT_PLMN(data.epsloci.tai.plmn); + printf(", TAC = 0x%.2x\n", data.epsloci.tai.tac); + printf("\tstatus\t= %d\n\n", data.epsloci.status); + + printf("NASCONFIG:\n"); + printf("\tNAS_SignallingPriority\t\t: 0x%.2x\n", + data.nasconfig.NAS_SignallingPriority.value[0]); + printf("\tNMO_I_Behaviour\t\t\t: 0x%.2x\n", + data.nasconfig.NMO_I_Behaviour.value[0]); + printf("\tAttachWithImsi\t\t\t: 0x%.2x\n", + data.nasconfig.AttachWithImsi.value[0]); + printf("\tMinimumPeriodicSearchTimer\t: 0x%.2x\n", + data.nasconfig.MinimumPeriodicSearchTimer.value[0]); + printf("\tExtendedAccessBarring\t\t: 0x%.2x\n", + data.nasconfig.ExtendedAccessBarring.value[0]); + printf("\tTimer_T3245_Behaviour\t\t: 0x%.2x\n", + data.nasconfig.Timer_T3245_Behaviour.value[0]); + +} + +void _display_ue_data(int user_id) { + user_nvdata_t data; + int rc; + char* path = make_filename(output_dir, USER_NVRAM_FILENAME, user_id); + /* + * Read UE's non-volatile data + */ + memset(&data, 0, sizeof(user_nvdata_t)); + rc = memory_read(path, &data, sizeof(user_nvdata_t)); + free(path); + + if (rc != RETURNok) { + perror("ERROR\t: memory_read() failed"); + exit(EXIT_FAILURE); + } + + /* + * Display UE's non-volatile data + */ + printf("\nUE's non-volatile data:\n\n"); + printf("IMEI\t\t= %s\n", data.IMEI); + printf("manufacturer\t= %s\n", data.manufacturer); + printf("model\t\t= %s\n", data.model); + printf("PIN\t\t= %s\n", data.PIN); +} + +/* + * Displays UE's non-volatile EMM data + */ +void _display_emm_data(int user_id) { + + int rc; + emm_nvdata_t data; + char* path = make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); + + /* + * Read EMM non-volatile data + */ + memset(&data, 0, sizeof(emm_nvdata_t)); + rc = memory_read(path, &data, sizeof(emm_nvdata_t)); + free(path); + if (rc != RETURNok) { + perror("ERROR\t: memory_read() failed "); + exit(EXIT_FAILURE); + } + + /* + * Display EMM non-volatile data + */ + printf("\nEMM non-volatile data:\n\n"); + + printf("IMSI\t\t= "); + + if (data.imsi.u.num.digit6 == 0b1111) { + if (data.imsi.u.num.digit15 == 0b1111) { + printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14); + } else { + printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14, + data.imsi.u.num.digit15); + } + } else { + if (data.imsi.u.num.digit15 == 0b1111) { + printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + data.imsi.u.num.digit6, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14); + } else { + printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + data.imsi.u.num.digit6, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14, + data.imsi.u.num.digit15); + } + } + + printf("RPLMN\t\t= "); + PRINT_PLMN(data.rplmn); + printf("\n"); + + for (int i = 0; i < data.eplmn.n_plmns; i++) { + printf("EPLMN[%d]\t= ", i); + PRINT_PLMN(data.eplmn.plmn[i]); + printf("\n"); + } +} + +/* + * Displays command line usage + */ +void _display_usage(void) { + fprintf(stderr, "usage: conf2uedata [OPTION] [directory] ...\n"); + fprintf(stderr, "\t[-c]\tConfig file to use\n"); + fprintf(stderr, "\t[-o]\toutput file directory\n"); + fprintf(stderr, "\t[-h]\tDisplay this usage\n"); +} + + +char * make_filename(const char *output_dir, const char *filename, int ueid) { + size_t size; + char *str_ueid, *str; + + str_ueid = itoa(ueid); + + if (str_ueid == NULL) { + perror("ERROR\t: itoa() failed"); + exit(EXIT_FAILURE); + } + + size = strlen(output_dir)+strlen(filename) + sizeof(ueid) + 1 + 1; // for \0 and for '/' + str = malloc(size); + if (str == NULL) { + perror("ERROR\t: make_filename() failed"); + exit(EXIT_FAILURE); + } + + snprintf(str, size, "%s/%s%s",output_dir, filename, str_ueid); + free(str_ueid); + + return str; +} diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h new file mode 100644 index 0000000000..06c0027c78 --- /dev/null +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -0,0 +1,153 @@ +#ifndef _CONF2UEDATA_H +#define _CONF2UEDATA_H + +#include +#include "emmData.h" +#include "usim_api.h" +#include "userDef.h" +#include "memory.h" +#include "getopt.h" + +#define USER "USER" +#define UE "UE" +#define SIM "SIM" +#define PLMN "PLMN" + +#define FULLNAME "FULLNAME" +#define SHORTNAME "SHORTNAME" +#define MNC "MNC" +#define MCC "MCC" + +#define MSIN "MSIN" +#define USIM_API_K "USIM_API_K" +#define OPC "OPC" +#define MSISDN "MSISDN" + +#define UE_IMEI "IMEI" +#define MANUFACTURER "MANUFACTURER" +#define MODEL "MODEL" +#define PINCODE "PIN" + +#define HPLMN "HPLMN" +#define UCPLMN "UCPLMN_LIST" +#define OPLMN "OPLMN_LIST" +#define OCPLMN "OCPLMN_LIST" +#define FPLMN "FPLMN_LIST" +#define EHPLMN "EHPLMN_LIST" + +#define KSI USIM_KSI_NOT_AVAILABLE +#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) + +#define PRINT_PLMN(plmn) \ + PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit3) + + +#define KSI_ASME USIM_KSI_NOT_AVAILABLE +#define INT_ALGO USIM_INT_EIA1 +#define ENC_ALGO USIM_ENC_EEA0 +#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO) +#define OPC_SIZE 16 +#define MIN_TAC 0x0000 +#define MAX_TAC 0xFFFE + +#define DEFAULT_TMSI 0x0000000D +#define DEFAULT_P_TMSI 0x0000000D +#define DEFAULT_M_TMSI 0x0000000D +#define DEFAULT_LAC 0xFFFE +#define DEFAULT_RAC 0x01 +#define DEFAULT_TAC 0x0001 + +#define DEFAULT_MME_ID 0x0102 +#define DEFAULT_MME_CODE 0x0F + +#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) + +#define PRINT_PLMN(plmn) \ + PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit3) + +/* + * PLMN network operator record + */ +typedef struct { + unsigned int num; + plmn_t plmn; + char fullname[NET_FORMAT_LONG_SIZE + 1]; + char shortname[NET_FORMAT_SHORT_SIZE + 1]; + tac_t tac_start; + tac_t tac_end; +} network_record_t; + +typedef struct { + const char* fullname; + const char* shortname; + const char* mnc; + const char* mcc; +} plmn_conf_param_t; + +const char options[]="c:o:h"; +unsigned char parse_data=FALSE; +unsigned char print_data=FALSE; +unsigned char output=FALSE; +const char* conf_file = NULL; +const char* output_dir = NULL; + +const char* imsi=NULL; +const char* msin=NULL; +const char* usim_api_k = NULL; +const char* msisdn = NULL; +const char* opc=NULL; +const char* hplmn=NULL; + +int* ucplmn=NULL; +int* oplmn=NULL; +int* ocplmn=NULL; +int* fplmn=NULL; +int* ehplmn=NULL; + +int hplmn_index =0; +int plmn_nb = 0; +int ucplmn_nb=0; +int oplmn_nb=0; +int ocplmn_nb=0; +int fplmn_nb=0; +int ehplmn_nb=0; + +plmn_conf_param_t* user_plmn_list=NULL; +network_record_t* user_network_record_list = NULL; + +void _display_usim_data(int user_id); + +void _display_usage(void); +void gen_emm_data(int user_id) ; +void gen_usim_data(int user_id); +void fill_network_record_list(void); + +int _luhn(const char* cc); + +void _display_ue_data(int user_id); + +void _display_emm_data(int user_id); +int parse_ue_user_param(config_setting_t *ue_setting, int user_id); +int parse_ue_sim_param(config_setting_t *ue_setting, int user_id); +int parse_plmn_param(config_setting_t *plmn_setting, int index); +int parse_plmns(config_setting_t *all_plmn_setting); +int get_msin_parity(const char * msin); +int get_plmn_index(const char * mccmnc); +int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id); +int fill_ucplmn(config_setting_t* setting, int use_id); +int fill_oplmn(config_setting_t* setting, int use_id); +int fill_ocplmn(config_setting_t* setting, int use_id); +int fill_fplmn(config_setting_t* setting, int use_id); +int fill_ehplmn(config_setting_t* setting, int use_id); + +#endif // _CONF2UEDATA_H diff --git a/openair3/NAS/TOOLS/ue_bcom_test.conf b/openair3/NAS/TOOLS/ue_bcom_test.conf new file mode 100644 index 0000000000..c60b628941 --- /dev/null +++ b/openair3/NAS/TOOLS/ue_bcom_test.conf @@ -0,0 +1,2334 @@ +PLMN: +{ + PLMN0: + { + FULLNAME="B<>COM Cubiq"; + SHORTNAME="BCOM"; + MNC="89"; + MCC="208"; + }; +}; + +UE0: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000000"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000000"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE1: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000001"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000001"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE2: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000002"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000002"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE3: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000003"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000003"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE4: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000004"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000004"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE5: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000005"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000005"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE6: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000006"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000006"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE7: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000007"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000007"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE8: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000008"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000008"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE9: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000009"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000009"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE10: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000010"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000010"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE11: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000011"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000011"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE12: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000012"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000012"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE13: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000013"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000013"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE14: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000014"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000014"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE15: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000015"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000015"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE16: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000016"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000016"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE17: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000017"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000017"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE18: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000018"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000018"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE19: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000019"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000019"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE20: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000020"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000020"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE21: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000021"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000021"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE22: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000022"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000022"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE23: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000023"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000023"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE24: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000024"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000024"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE25: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000025"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000025"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE26: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000026"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000026"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE27: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000027"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000027"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE28: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000028"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000028"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE29: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000029"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000029"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE30: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000030"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000030"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE31: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000031"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000031"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE32: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000032"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000032"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE33: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000033"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000033"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE34: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000034"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000034"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE35: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000035"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000035"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE36: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000036"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000036"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE37: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000037"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000037"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE38: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000038"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000038"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE39: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000039"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000039"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE40: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000040"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000040"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE41: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000041"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000041"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE42: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000042"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000042"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE43: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000043"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000043"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE44: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000044"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000044"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE45: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000045"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000045"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE46: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000046"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000046"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE47: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000047"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000047"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE48: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000048"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000048"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE49: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000049"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000049"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE50: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000050"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000050"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE51: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000051"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000051"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE52: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000052"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000052"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE53: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000053"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000053"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE54: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000054"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000054"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE55: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000055"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000055"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE56: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000056"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000056"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE57: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000057"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000057"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE58: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000058"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000058"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE59: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000059"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000059"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE60: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000060"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000060"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE61: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000061"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000061"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE62: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000062"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000062"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE63: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000063"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000063"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE64: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000064"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000064"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE65: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000065"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000065"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE66: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000066"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000066"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE67: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000067"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000067"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE68: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000068"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000068"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE69: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000069"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000069"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE70: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000070"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000070"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE71: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000071"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000071"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE72: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000072"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000072"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE73: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000073"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000073"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE74: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000074"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000074"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE75: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000075"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000075"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE76: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000076"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000076"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE77: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000077"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000077"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE78: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000078"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000078"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE79: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000079"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000079"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE80: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000080"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000080"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE81: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000081"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000081"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE82: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000082"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000082"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE83: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000083"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000083"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE84: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000084"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000084"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE85: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000085"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000085"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE86: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000086"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000086"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE87: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000087"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000087"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE88: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000088"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000088"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE89: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000089"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000089"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE90: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000090"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000090"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE91: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000091"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000091"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE92: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000092"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000092"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE93: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000093"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000093"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE94: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000094"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000094"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE95: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000095"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000095"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE96: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000096"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000096"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE97: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000097"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000097"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE98: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000098"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000098"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE99: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000099"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000099"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; +UE100: +{ +USER: + { + IMEI="35609204079299"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; +SIM: + { + MSIN="1000000100"; + USIM_API_K="00112233445566778899AABBCCDDEEFF"; + OPC="21C6FD3F84AA71BAC34FA8FCA0EAC64F"; + MSISDN="33600000100"; + }; +HPLMN= "20889"; +UCPLMN_LIST=(); +OPLMN_LIST=("20889"); +OCPLMN_LIST = (); +FPLMN_LIST = (); +EHPLMN_LIST= (); +}; diff --git a/openair3/NAS/TOOLS/ue_data.c b/openair3/NAS/TOOLS/ue_data.c deleted file mode 100644 index 3636ad6ee3..0000000000 --- a/openair3/NAS/TOOLS/ue_data.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/***************************************************************************** -Source ue_data.c - -Version 0.1 - -Date 2012/11/02 - -Product UE data generator - -Subsystem UE data generator main process - -Author Frederic Maurel - -Description Implements the utility used to generate data stored in the - UE's non-volatile memory device - -*****************************************************************************/ - -#include "userDef.h" -#include "memory.h" - -#include "emmData.h" -#include "network.h" - -#include // perror, printf, fprintf, snprintf -#include // exit, free -#include // memset, strncpy - -/****************************************************************************/ -/**************** E X T E R N A L D E F I N I T I O N S ****************/ -/****************************************************************************/ - -#define USER_IMEI "35611302209414" -#define USER_MANUFACTURER "EURECOM" -#define USER_MODEL "LTE Android PC" -//#define USER_MANUFACTURER "SAGEM" -//#define USER_MODEL "my225x" -#define USER_PIN "0000" - -#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) - -#define PRINT_PLMN(plmn) \ - PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit3) - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static void _display_usage(const char* command); - -static void _gen_user_data(user_nvdata_t* data); -static void _gen_emm_data(emm_nvdata_t* data); - -static int _luhn(const char* cc); -static void _display_ue_data(const user_nvdata_t* data); -static void _display_emm_data(const emm_nvdata_t* data); - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -int main (int argc, const char* argv[]) -{ - int rc; - char* path; - user_nvdata_t user_data; - emm_nvdata_t emm_data; - - unsigned char gen_data; - - /* - * ---------------------------- - * Read command line parameters - * ---------------------------- - */ - if (argc != 2) { - fprintf(stderr, "Invalid parameter\n"); - _display_usage(argv[0]); - exit(EXIT_FAILURE); - } else if ( (strcmp(argv[1], "--gen") == 0) || - (strcmp(argv[1], "-g") == 0) ) { - /* Generate UE data files */ - gen_data = TRUE; - } else if ( (strcmp(argv[1], "--print") == 0) || - (strcmp(argv[1], "-p") == 0) ) { - /* Display content of UE data files */ - gen_data = FALSE; - } else { - /* Display usage */ - _display_usage(argv[0]); - exit(EXIT_SUCCESS); - } - /* - * ---------------------- - * UE's non-volatile data - * ---------------------- - */ - path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); - - if (path == NULL) { - perror("ERROR\t: memory_get_path() failed"); - exit(EXIT_FAILURE); - } - - if (gen_data) { - /* - * Initialize UE's non-volatile data - */ - memset(&user_data, 0, sizeof(user_nvdata_t)); - _gen_user_data(&user_data); - /* - * Write UE's non-volatile data - */ - rc = memory_write(path, &user_data, sizeof(user_nvdata_t)); - - if (rc != RETURNok) { - perror("ERROR\t: memory_write() failed"); - free(path); - exit(EXIT_FAILURE); - } - } - - /* - * Read UE's non-volatile data - */ - memset(&user_data, 0, sizeof(user_nvdata_t)); - rc = memory_read(path, &user_data, sizeof(user_nvdata_t)); - - if (rc != RETURNok) { - perror("ERROR\t: memory_read() failed"); - free(path); - exit(EXIT_FAILURE); - } - - free(path); - /* - * Display UE's non-volatile data - */ - printf("\nUE's non-volatile data:\n\n"); - _display_ue_data(&user_data); - - /* - * --------------------- - * EMM non-volatile data - * --------------------- - */ - path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); - - if (path == NULL) { - perror("ERROR\t: memory_get_path() failed"); - exit(EXIT_FAILURE); - } - - if (gen_data) { - /* - * Initialize EMM non-volatile data - */ - memset(&emm_data, 0, sizeof(emm_nvdata_t)); - _gen_emm_data(&emm_data); - /* - * Write EMM non-volatile data - */ - rc = memory_write(path, &emm_data, sizeof(emm_nvdata_t)); - - if (rc != RETURNok) { - perror("ERROR\t: memory_write() failed"); - free(path); - exit(EXIT_FAILURE); - } - } - - /* - * Read EMM non-volatile data - */ - memset(&emm_data, 0, sizeof(emm_nvdata_t)); - rc = memory_read(path, &emm_data, sizeof(emm_nvdata_t)); - - if (rc != RETURNok) { - perror("ERROR\t: memory_read() failed "); - free(path); - exit(EXIT_FAILURE); - } - - free(path); - /* - * Display EMM non-volatile data - */ - printf("\nEMM non-volatile data:\n\n"); - _display_emm_data(&emm_data); - - /* - *--------------- - * Files location - *--------------- - */ - path = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); - printf("\nUE identity data file: %s\n", path); - free(path); - path = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); - printf("EPS Mobility Management data file: %s\n", path); - free(path); - - exit(EXIT_SUCCESS); -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/* - * Displays command line usage - */ -static void _display_usage(const char* command) -{ - fprintf(stderr, "usage: %s [OPTION]\n", command); - fprintf(stderr, "\t[--gen|-g]\tGenerate the UE data files\n"); - fprintf(stderr, "\t[--print|-p]\tDisplay the content of the UE data files\n"); - fprintf(stderr, "\t[--help|-h]\tDisplay this usage\n"); - const char* path = getenv("NVRAM_DIR"); - - if (path != NULL) { - fprintf(stderr, "NVRAM_DIR = %s\n", path); - } else { - fprintf(stderr, "NVRAM_DIR environment variable is not defined\n"); - } -} - -/* - * Generates UE's non-volatile data - */ -static void _gen_user_data(user_nvdata_t* data) -{ - /* - * Product Serial Number Identification - * IMEI = AA-BBBBBB-CCCCCC-D - * AA-BBBBBB: Type Allocation Code (TAC) - * CCCCCC: Serial Number - * D: Luhn check digit - */ - snprintf(data->IMEI, USER_IMEI_SIZE+1, "%s%d", - USER_IMEI, _luhn(USER_IMEI)); - /* - * Manufacturer identifier - */ - strncpy(data->manufacturer, USER_MANUFACTURER, USER_MANUFACTURER_SIZE); - /* - * Model identifier - */ - strncpy(data->model, USER_MODEL, USER_MODEL_SIZE); - /* - * SIM Personal Identification Number - */ - strncpy(data->PIN, USER_PIN, USER_PIN_SIZE); -} - -/* - * Generates UE's non-volatile EMM data - */ -static void _gen_emm_data(emm_nvdata_t* data) -{ -#if (SELECTED_PLMN == FCT1) - /* - * International Mobile Subscriber Identity - * IMSI = MCC + MNC + MSIN = 310 (USA) + 028 (UNKNOWN) + 90832150 - */ -#warning "IMSI 310.028.90832150" - data->imsi.length = 8; - data->imsi.u.num.parity = 0x0; // Type of identity = IMSI, even - data->imsi.u.num.digit1 = 3; // MCC digit 1 - data->imsi.u.num.digit2 = 1; // MCC digit 2 - data->imsi.u.num.digit3 = 0; // MCC digit 3 - data->imsi.u.num.digit4 = 0; // MNC digit 1 - data->imsi.u.num.digit5 = 2; // MNC digit 2 - data->imsi.u.num.digit6 = 8; // MNC digit 3 - data->imsi.u.num.digit7 = 9; - data->imsi.u.num.digit8 = 0; - data->imsi.u.num.digit9 = 8; - data->imsi.u.num.digit10 = 3; - data->imsi.u.num.digit11 = 2; - data->imsi.u.num.digit12 = 1; - data->imsi.u.num.digit13 = 5; - data->imsi.u.num.digit14 = 0; - data->imsi.u.num.digit15 = 0xF; - /* - * Last registered home PLMN - */ - data->rplmn.MCCdigit1 = 3; - data->rplmn.MCCdigit2 = 1; - data->rplmn.MCCdigit3 = 0; - data->rplmn.MNCdigit1 = 0; - data->rplmn.MNCdigit2 = 2; - data->rplmn.MNCdigit3 = 8; -#endif -#if (SELECTED_PLMN == SFR1) - /* - * International Mobile Subscriber Identity - * IMSI = MCC + MNC + MSIN = 208 (France) + 10 (SFR) + 00001234 - */ - data->imsi.length = 8; - data->imsi.u.num.parity = 0x0; // Type of identity = IMSI, even - data->imsi.u.num.digit1 = 2; // MCC digit 1 - data->imsi.u.num.digit2 = 0; // MCC digit 2 - data->imsi.u.num.digit3 = 8; // MCC digit 3 - data->imsi.u.num.digit4 = 1; // MNC digit 1 - data->imsi.u.num.digit5 = 0; // MNC digit 2 - data->imsi.u.num.digit6 = 0;//0xF; // MNC digit 3 - data->imsi.u.num.digit7 = 0; - data->imsi.u.num.digit8 = 0; - data->imsi.u.num.digit9 = 0; - data->imsi.u.num.digit10 = 0; - data->imsi.u.num.digit11 = 1; - data->imsi.u.num.digit12 = 2; - data->imsi.u.num.digit13 = 3; - data->imsi.u.num.digit14 = 4; - data->imsi.u.num.digit15 = 0xF; - - data->rplmn.MCCdigit1 = 2; - data->rplmn.MCCdigit2 = 0; - data->rplmn.MCCdigit3 = 8; - data->rplmn.MNCdigit1 = 1; - data->rplmn.MNCdigit2 = 0; - data->rplmn.MNCdigit3 = 0xf; -#endif -#if (SELECTED_PLMN == OAI_LTEBOX) - /* - * International Mobile Subscriber Identity - * IMSI = MCC + MNC + MSIN = 208 (France) + 93 (OAI) + 00001110 - */ - data->imsi.length = 8; - data->imsi.u.num.parity = ODD_PARITY; // Type of identity = IMSI, even - data->imsi.u.num.digit1 = 2; // MCC digit 1 - data->imsi.u.num.digit2 = 0; // MCC digit 2 - data->imsi.u.num.digit3 = 8; // MCC digit 3 - data->imsi.u.num.digit4 = 9; // MNC digit 1 - data->imsi.u.num.digit5 = 3; // MNC digit 2 - data->imsi.u.num.digit6 = 0; // MNC digit 3 - data->imsi.u.num.digit7 = 1; - data->imsi.u.num.digit8 = 0; - data->imsi.u.num.digit9 = 0; - data->imsi.u.num.digit10 = 0; - data->imsi.u.num.digit11 = 0; - data->imsi.u.num.digit12 = 1; - data->imsi.u.num.digit13 = 1; - data->imsi.u.num.digit14 = 1; - data->imsi.u.num.digit15 = 1; - - data->rplmn.MCCdigit1 = 2; - data->rplmn.MCCdigit2 = 0; - data->rplmn.MCCdigit3 = 8; - data->rplmn.MNCdigit1 = 9; - data->rplmn.MNCdigit2 = 3; - data->rplmn.MNCdigit3 = 0xf; -#endif -#if (SELECTED_PLMN == TEST1) - /* - * International Mobile Subscriber Identity - * IMSI = MCC + MNC + MSIN = 001 + 01 + 00001234 - */ - data->imsi.length = 8; - data->imsi.u.num.parity = 0x0; // Type of identity = IMSI, even - data->imsi.u.num.digit1 = 0; // MCC digit 1 - data->imsi.u.num.digit2 = 0; // MCC digit 2 - data->imsi.u.num.digit3 = 1; // MCC digit 3 - data->imsi.u.num.digit4 = 0; // MNC digit 1 - data->imsi.u.num.digit5 = 1; // MNC digit 2 - data->imsi.u.num.digit6 = 0; - data->imsi.u.num.digit7 = 0; - data->imsi.u.num.digit8 = 0; - data->imsi.u.num.digit9 = 0; - data->imsi.u.num.digit10 = 0; - data->imsi.u.num.digit11 = 1; - data->imsi.u.num.digit12 = 2; - data->imsi.u.num.digit13 = 3; - data->imsi.u.num.digit14 = 4; - data->imsi.u.num.digit15 = 0xF; - - /* - * Last registered home PLMN - */ - data->rplmn.MCCdigit1 = 0; - data->rplmn.MCCdigit2 = 0; - data->rplmn.MCCdigit3 = 1; - data->rplmn.MNCdigit1 = 0; - data->rplmn.MNCdigit2 = 1; - data->rplmn.MNCdigit3 = 0xf; -#endif - /* - * List of Equivalent PLMNs - */ - data->eplmn.n_plmns = 0; -} - -/* - * Computes the check digit using Luhn algorithm - */ -static int _luhn(const char* cc) -{ - const int m[] = {0,2,4,6,8,1,3,5,7,9}; - int odd = 1, sum = 0; - - for (int i = strlen(cc); i--; odd = !odd) { - int digit = cc[i] - '0'; - sum += odd ? m[digit] : digit; - } - - return 10 - (sum % 10); -} - -/* - * Displays UE's non-volatile data - */ -static void _display_ue_data(const user_nvdata_t* data) -{ - printf("IMEI\t\t= %s\n", data->IMEI); - printf("manufacturer\t= %s\n", data->manufacturer); - printf("model\t\t= %s\n", data->model); - printf("PIN\t\t= %s\n", data->PIN); -} - -/* - * Displays UE's non-volatile EMM data - */ -static void _display_emm_data(const emm_nvdata_t* data) -{ - printf("IMSI\t\t= "); - - if (data->imsi.u.num.digit6 == 0b1111) { - if (data->imsi.u.num.digit15 == 0b1111) { - printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u\n", - data->imsi.u.num.digit1, - data->imsi.u.num.digit2, - data->imsi.u.num.digit3, - data->imsi.u.num.digit4, - data->imsi.u.num.digit5, - - data->imsi.u.num.digit7, - data->imsi.u.num.digit8, - data->imsi.u.num.digit9, - data->imsi.u.num.digit10, - data->imsi.u.num.digit11, - data->imsi.u.num.digit12, - data->imsi.u.num.digit13, - data->imsi.u.num.digit14); - } else { - printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u%u\n", - data->imsi.u.num.digit1, - data->imsi.u.num.digit2, - data->imsi.u.num.digit3, - data->imsi.u.num.digit4, - data->imsi.u.num.digit5, - - data->imsi.u.num.digit7, - data->imsi.u.num.digit8, - data->imsi.u.num.digit9, - data->imsi.u.num.digit10, - data->imsi.u.num.digit11, - data->imsi.u.num.digit12, - data->imsi.u.num.digit13, - data->imsi.u.num.digit14, - data->imsi.u.num.digit15); - } - } else { - if (data->imsi.u.num.digit15 == 0b1111) { - printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u\n", - data->imsi.u.num.digit1, - data->imsi.u.num.digit2, - data->imsi.u.num.digit3, - data->imsi.u.num.digit4, - data->imsi.u.num.digit5, - data->imsi.u.num.digit6, - - data->imsi.u.num.digit7, - data->imsi.u.num.digit8, - data->imsi.u.num.digit9, - data->imsi.u.num.digit10, - data->imsi.u.num.digit11, - data->imsi.u.num.digit12, - data->imsi.u.num.digit13, - data->imsi.u.num.digit14); - } else { - printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u%u\n", - data->imsi.u.num.digit1, - data->imsi.u.num.digit2, - data->imsi.u.num.digit3, - data->imsi.u.num.digit4, - data->imsi.u.num.digit5, - data->imsi.u.num.digit6, - - data->imsi.u.num.digit7, - data->imsi.u.num.digit8, - data->imsi.u.num.digit9, - data->imsi.u.num.digit10, - data->imsi.u.num.digit11, - data->imsi.u.num.digit12, - data->imsi.u.num.digit13, - data->imsi.u.num.digit14, - data->imsi.u.num.digit15); - } - } - - printf("RPLMN\t\t= "); - PRINT_PLMN(data->rplmn); - printf("\n"); - - for (int i = 0; i < data->eplmn.n_plmns; i++) { - printf("EPLMN[%d]\t= ", i); - PRINT_PLMN(data->eplmn.plmn[i]); - printf("\n"); - } -} diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf new file mode 100644 index 0000000000..42d174bbbf --- /dev/null +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -0,0 +1,112 @@ +# List of known PLMNS +PLMN: { + PLMN0: { + FULLNAME="Test network"; + SHORTNAME="OAI4G"; + MNC="01"; + MCC="001"; + + }; + PLMN1: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="10"; + MCC="208"; + + }; + PLMN2: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="11"; + MCC="208"; + }; + PLMN3: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="13"; + MCC="208"; + }; + PLMN4: { + FULLNAME="OAI LTEBOX"; + SHORTNAME="OAIALU"; + MNC="93"; + MCC="208"; + }; + PLMN5: { + FULLNAME="T-Mobile USA"; + SHORTNAME="T-Mobile"; + MNC="280"; + MCC="310"; + }; + PLMN6: { + FULLNAME="FICTITIOUS USA"; + SHORTNAME="FICTITIO"; + MNC="028"; + MCC="310"; + }; + PLMN7: { + FULLNAME="Vodafone Italia"; + SHORTNAME="VODAFONE"; + MNC="10"; + MCC="222"; + }; + PLMN8: { + FULLNAME="Vodafone Spain"; + SHORTNAME="VODAFONE"; + MNC="01"; + MCC="214"; + }; + PLMN9: { + FULLNAME="Vodafone Spain"; + SHORTNAME="VODAFONE"; + MNC="06"; + MCC="214"; + }; + PLMN10: { + FULLNAME="Vodafone Germ"; + SHORTNAME="VODAFONE"; + MNC="02"; + MCC="262"; + }; + PLMN11: { + FULLNAME="Vodafone Germ"; + SHORTNAME="VODAFONE"; + MNC="04"; + MCC="262"; + }; +}; + +UE0: +{ + USER: { + IMEI="356113022094149"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="0000001234"; + USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; + OPC="00000000000000000000000000000000"; + MSISDN="33611123456"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "20810"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "310280", "310028"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs + EHPLMN_LIST= ("20811", "20813"); +}; diff --git a/openair3/NAS/TOOLS/usim_data.c b/openair3/NAS/TOOLS/usim_data.c deleted file mode 100644 index 4e3027691f..0000000000 --- a/openair3/NAS/TOOLS/usim_data.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/***************************************************************************** -Source usim_data.c - -Version 0.1 - -Date 2012/10/31 - -Product USIM data generator - -Subsystem USIM data generator main process - -Author Frederic Maurel - -Description Implements the utility used to generate data stored in the - USIM application - - *****************************************************************************/ - -#include "network.h" - -#include "usim_api.h" -#include "memory.h" -#include "network.h" - -#include // perror, printf -#include // exit -#include // memset, memcpy, strncpy - - -/****************************************************************************/ -/**************** E X T E R N A L D E F I N I T I O N S ****************/ -/****************************************************************************/ - -#define KSI USIM_KSI_NOT_AVAILABLE -#define KSI_ASME USIM_KSI_NOT_AVAILABLE -#define INT_ALGO USIM_INT_EIA2 -#define ENC_ALGO USIM_ENC_EEA0 -#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO) - -#define MIN_TAC 0x0000 -#define MAX_TAC 0xFFFE - -#define DEFAULT_TMSI 0x0000000D -#define DEFAULT_P_TMSI 0x0000000D -#define DEFAULT_M_TMSI 0x0000000D -#define DEFAULT_LAC 0xFFFE -#define DEFAULT_RAC 0x01 -#define DEFAULT_TAC 0x0001 - -#define DEFAULT_MME_ID 0x0102 -#define DEFAULT_MME_CODE 0x0F - -#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) - -#define PRINT_PLMN(plmn) \ - PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit3) - -/****************************************************************************/ -/******************* L O C A L D E F I N I T I O N S *******************/ -/****************************************************************************/ - -static void _display_usage(const char* command); - -static void _display_usim_data(const usim_data_t* data); - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -int main (int argc, const char* argv[]) -{ - int rc; - usim_data_t usim_data; - - unsigned char gen_data; - - /* Get USIM application pathname */ - char* path = memory_get_path(USIM_API_NVRAM_DIRNAME, - USIM_API_NVRAM_FILENAME); - - if (path == NULL) { - fprintf(stderr, "USIM-API - Failed to get USIM pathname"); - free(path); - exit(EXIT_FAILURE); - } - - /* - * Read command line parameters - */ - if (argc != 2) { - fprintf(stderr, "Invalid parameter\n"); - _display_usage(argv[0]); - exit(EXIT_FAILURE); - } else if ( (strcmp(argv[1], "--gen") == 0) || - (strcmp(argv[1], "-g") == 0) ) { - /* Generate USIM data files */ - gen_data = TRUE; - } else if ( (strcmp(argv[1], "--print") == 0) || - (strcmp(argv[1], "-p") == 0) ) { - /* Display content of USIM data files */ - gen_data = FALSE; - } else { - /* Display usage */ - _display_usage(argv[0]); - exit(EXIT_SUCCESS); - } - - if (gen_data) { - /* - * Initialize USIM data - */ - memset(&usim_data, 0, sizeof(usim_data_t)); - -#if (SELECTED_PLMN == FCT1) - /* - * International Mobile Subscriber Identity - * IMSI = MCC + MNC + MSIN = 310 (USA) + 028 (UNKNOWN) + 90832150 - */ -#warning "IMSI 310.028.90832150" - usim_data.imsi.length = 8; - usim_data.imsi.u.num.parity = EVEN_PARITY; // Parity: even - usim_data.imsi.u.num.digit1 = 3; // MCC digit 1 - usim_data.imsi.u.num.digit2 = 1; // MCC digit 2 - usim_data.imsi.u.num.digit3 = 0; // MCC digit 3 - usim_data.imsi.u.num.digit4 = 0; // MNC digit 1 - usim_data.imsi.u.num.digit5 = 2; // MNC digit 2 - usim_data.imsi.u.num.digit6 = 8; // MNC digit 3 - usim_data.imsi.u.num.digit7 = 9; - usim_data.imsi.u.num.digit8 = 0; - usim_data.imsi.u.num.digit9 = 8; - usim_data.imsi.u.num.digit10 = 3; - usim_data.imsi.u.num.digit11 = 2; - usim_data.imsi.u.num.digit12 = 1; - usim_data.imsi.u.num.digit13 = 5; - usim_data.imsi.u.num.digit14 = 0; - usim_data.imsi.u.num.digit15 = 0b1111; -#endif -#if (SELECTED_PLMN == SFR1) - - /* - * International Mobile Subscriber Identity - * IMSI = MCC + MNC + MSIN = 208 (France) + 10 (SFR) + 00001234 - */ -#warning "IMSI 208.10.00001234" - - usim_data.imsi.length = 8; - usim_data.imsi.u.num.parity = EVEN_PARITY; // Parity: even - usim_data.imsi.u.num.digit1 = 2; // MCC digit 1 - usim_data.imsi.u.num.digit2 = 0; // MCC digit 2 - usim_data.imsi.u.num.digit3 = 8; // MCC digit 3 - usim_data.imsi.u.num.digit4 = 1; // MNC digit 1 - usim_data.imsi.u.num.digit5 = 0; // MNC digit 2 - usim_data.imsi.u.num.digit6 = 0;//0b1111; // MNC digit 3 - usim_data.imsi.u.num.digit7 = 0; - usim_data.imsi.u.num.digit8 = 0; - usim_data.imsi.u.num.digit9 = 0; - usim_data.imsi.u.num.digit10 = 0; - usim_data.imsi.u.num.digit11 = 1; - usim_data.imsi.u.num.digit12 = 2; - usim_data.imsi.u.num.digit13 = 3; - usim_data.imsi.u.num.digit14 = 4; - usim_data.imsi.u.num.digit15 = 0b1111; -#endif -#if (SELECTED_PLMN == OAI_LTEBOX) - /* - * International Mobile Subscriber Identity - * IMSI = MCC + MNC + MSIN = 208 (France) + 10 (SFR) + 00001234 - */ -#warning "IMSI 208.93.0100001111" - usim_data.imsi.length = 8; - usim_data.imsi.u.num.parity = ODD_PARITY; // Parity: even - usim_data.imsi.u.num.digit1 = 2; // MCC digit 1 - usim_data.imsi.u.num.digit2 = 0; // MCC digit 2 - usim_data.imsi.u.num.digit3 = 8; // MCC digit 3 - usim_data.imsi.u.num.digit4 = 9; // MNC digit 1 - usim_data.imsi.u.num.digit5 = 3; // MNC digit 2 - usim_data.imsi.u.num.digit6 = 0; // MNC digit 3 - usim_data.imsi.u.num.digit7 = 1; - usim_data.imsi.u.num.digit8 = 0; - usim_data.imsi.u.num.digit9 = 0; - usim_data.imsi.u.num.digit10 = 0; - usim_data.imsi.u.num.digit11 = 0; - usim_data.imsi.u.num.digit12 = 1; - usim_data.imsi.u.num.digit13 = 1; - usim_data.imsi.u.num.digit14 = 1; - usim_data.imsi.u.num.digit15 = 1; -#endif -#if (SELECTED_PLMN == TEST1) -#warning "IMSI 001.01.000001234" - usim_data.imsi.length = 8; - usim_data.imsi.u.num.parity = 0x0; // Type of identity = IMSI, even - usim_data.imsi.u.num.digit1 = 0; // MCC digit 1 - usim_data.imsi.u.num.digit2 = 0; // MCC digit 2 - usim_data.imsi.u.num.digit3 = 1; // MCC digit 3 - usim_data.imsi.u.num.digit4 = 0; // MNC digit 1 - usim_data.imsi.u.num.digit5 = 1; // MNC digit 2 - usim_data.imsi.u.num.digit6 = 0; - usim_data.imsi.u.num.digit7 = 0; - usim_data.imsi.u.num.digit8 = 0; - usim_data.imsi.u.num.digit9 = 0; - usim_data.imsi.u.num.digit10 = 0; - usim_data.imsi.u.num.digit11 = 1; - usim_data.imsi.u.num.digit12 = 2; - usim_data.imsi.u.num.digit13 = 3; - usim_data.imsi.u.num.digit14 = 4; - usim_data.imsi.u.num.digit15 = 0xF; - usim_data.usimtestmode = 1; // set usim in test mode in order to get the CMW500 K key -#endif - /* - * Ciphering and Integrity Keys - */ - usim_data.keys.ksi = KSI; - memset(&usim_data.keys.ck, 0, USIM_CK_SIZE); - memset(&usim_data.keys.ik, 0, USIM_IK_SIZE); - - /* - * Higher Priority PLMN search period - */ - usim_data.hpplmn = 0x00; /* Disable timer */ - - /* - * List of Forbidden PLMNs - */ - for (int i = 0; i < USIM_FPLMN_MAX; i++) { - memset(&usim_data.fplmn[i], 0xff, sizeof(plmn_t)); - } - - /* - * Location Information - */ - usim_data.loci.tmsi = DEFAULT_TMSI; - usim_data.loci.lai.plmn = network_records[SELECTED_PLMN].plmn; - usim_data.loci.lai.lac = DEFAULT_LAC; - usim_data.loci.status = USIM_LOCI_NOT_UPDATED; - /* - * Packet Switched Location Information - */ - usim_data.psloci.p_tmsi = DEFAULT_P_TMSI; - usim_data.psloci.signature[0] = 0x01; - usim_data.psloci.signature[1] = 0x02; - usim_data.psloci.signature[2] = 0x03; - usim_data.psloci.rai.plmn = network_records[SELECTED_PLMN].plmn; - usim_data.psloci.rai.lac = DEFAULT_LAC; - usim_data.psloci.rai.rac = DEFAULT_RAC; - usim_data.psloci.status = USIM_PSLOCI_NOT_UPDATED; - /* - * Administrative Data - */ - usim_data.ad.UE_Operation_Mode = USIM_NORMAL_MODE; - usim_data.ad.Additional_Info = 0xffff; - usim_data.ad.MNC_Length = 2; - /* - * EPS NAS security context - */ - usim_data.securityctx.length = 52; - usim_data.securityctx.KSIasme.type = USIM_KSI_ASME_TAG; - usim_data.securityctx.KSIasme.length = 1; - usim_data.securityctx.KSIasme.value[0] = KSI_ASME; - usim_data.securityctx.Kasme.type = USIM_K_ASME_TAG; - usim_data.securityctx.Kasme.length = USIM_K_ASME_SIZE; - memset(usim_data.securityctx.Kasme.value, 0, - usim_data.securityctx.Kasme.length); - usim_data.securityctx.ulNAScount.type = USIM_UL_NAS_COUNT_TAG; - usim_data.securityctx.ulNAScount.length = USIM_UL_NAS_COUNT_SIZE; - memset(usim_data.securityctx.ulNAScount.value, 0, - usim_data.securityctx.ulNAScount.length); - usim_data.securityctx.dlNAScount.type = USIM_DL_NAS_COUNT_TAG; - usim_data.securityctx.dlNAScount.length = USIM_DL_NAS_COUNT_SIZE; - memset(usim_data.securityctx.dlNAScount.value, 0, - usim_data.securityctx.dlNAScount.length); - usim_data.securityctx.algorithmID.type = USIM_INT_ENC_ALGORITHMS_TAG; - usim_data.securityctx.algorithmID.length = 1; - usim_data.securityctx.algorithmID.value[0] = SECURITY_ALGORITHMS; - /* - * Subcriber's Number - */ - usim_data.msisdn.length = 7; - usim_data.msisdn.number.ext = 1; - usim_data.msisdn.number.ton = MSISDN_TON_UNKNOWKN; - usim_data.msisdn.number.npi = MSISDN_NPI_ISDN_TELEPHONY; - usim_data.msisdn.number.digit[0].msb = 3; - usim_data.msisdn.number.digit[0].lsb = 3; - usim_data.msisdn.number.digit[1].msb = 6; - usim_data.msisdn.number.digit[1].lsb = 1; - usim_data.msisdn.number.digit[2].msb = 1; - usim_data.msisdn.number.digit[2].lsb = 1; - usim_data.msisdn.number.digit[3].msb = 2; - usim_data.msisdn.number.digit[3].lsb = 3; - usim_data.msisdn.number.digit[4].msb = 4; - usim_data.msisdn.number.digit[4].lsb = 5; - usim_data.msisdn.number.digit[5].msb = 6; - usim_data.msisdn.number.digit[5].lsb = 0xf; - usim_data.msisdn.number.digit[6].msb = 0xf; - usim_data.msisdn.number.digit[6].lsb = 0xf; - usim_data.msisdn.number.digit[7].msb = 0xf; - usim_data.msisdn.number.digit[7].lsb = 0xf; - usim_data.msisdn.number.digit[8].msb = 0xf; - usim_data.msisdn.number.digit[8].lsb = 0xf; - usim_data.msisdn.number.digit[9].msb = 0xf; - usim_data.msisdn.number.digit[9].lsb = 0xf; - usim_data.msisdn.conf1_record_id = 0xff; /* Not used */ - usim_data.msisdn.ext1_record_id = 0xff; /* Not used */ - - /* - * PLMN Network Name and Operator PLMN List - */ - for (int i = TEST1; i < VDF1; i++) { - network_record_t record = network_records[i]; - usim_data.pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; - usim_data.pnn[i].fullname.length = strlen(record.fullname); - strncpy((char*)usim_data.pnn[i].fullname.value, record.fullname, - usim_data.pnn[i].fullname.length); - usim_data.pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG; - usim_data.pnn[i].shortname.length = strlen(record.shortname); - strncpy((char*)usim_data.pnn[i].shortname.value, record.shortname, - usim_data.pnn[i].shortname.length); - usim_data.opl[i].plmn = record.plmn; - usim_data.opl[i].start = record.tac_start; - usim_data.opl[i].end = record.tac_end; - usim_data.opl[i].record_id = i; - } - - for (int i = VDF2; i < USIM_OPL_MAX; i++) { - memset(&usim_data.opl[i].plmn, 0xff, sizeof(plmn_t)); - } - - /* - * List of Equivalent HPLMNs - */ - usim_data.ehplmn[0] = network_records[SFR2].plmn; - usim_data.ehplmn[1] = network_records[SFR3].plmn; - /* - * Home PLMN Selector with Access Technology - */ - usim_data.hplmn.plmn = network_records[SELECTED_PLMN].plmn; - usim_data.hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); - - /* - * List of user controlled PLMN selector with Access Technology - */ - for (int i = 0; i < USIM_PLMN_MAX; i++) { - memset(&usim_data.plmn[i], 0xff, sizeof(plmn_t)); - } - - /* - * List of operator controlled PLMN selector with Access Technology - */ - usim_data.oplmn[0].plmn = network_records[VDF1].plmn; - usim_data.oplmn[0].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); - usim_data.oplmn[1].plmn = network_records[VDF2].plmn; - usim_data.oplmn[1].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); - usim_data.oplmn[2].plmn = network_records[VDF3].plmn; - usim_data.oplmn[2].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); - usim_data.oplmn[3].plmn = network_records[VDF4].plmn; - usim_data.oplmn[3].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); - usim_data.oplmn[4].plmn = network_records[VDF5].plmn; - usim_data.oplmn[4].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); - - for (int i = 5; i < USIM_OPLMN_MAX; i++) { - memset(&usim_data.oplmn[i], 0xff, sizeof(plmn_t)); - } - - /* - * EPS Location Information - */ - usim_data.epsloci.guti.gummei.plmn = network_records[SELECTED_PLMN].plmn; - usim_data.epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID; - usim_data.epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE; - usim_data.epsloci.guti.m_tmsi = DEFAULT_M_TMSI; - usim_data.epsloci.tai.plmn = usim_data.epsloci.guti.gummei.plmn; - usim_data.epsloci.tai.tac = DEFAULT_TAC; - usim_data.epsloci.status = USIM_EPSLOCI_UPDATED; - /* - * Non-Access Stratum configuration - */ - usim_data.nasconfig.NAS_SignallingPriority.type = USIM_NAS_SIGNALLING_PRIORITY_TAG; - usim_data.nasconfig.NAS_SignallingPriority.length = 1; - usim_data.nasconfig.NAS_SignallingPriority.value[0] = 0x00; - usim_data.nasconfig.NMO_I_Behaviour.type = USIM_NMO_I_BEHAVIOUR_TAG; - usim_data.nasconfig.NMO_I_Behaviour.length = 1; - usim_data.nasconfig.NMO_I_Behaviour.value[0] = 0x00; - usim_data.nasconfig.AttachWithImsi.type = USIM_ATTACH_WITH_IMSI_TAG; - usim_data.nasconfig.AttachWithImsi.length = 1; -#if defined(START_WITH_GUTI) - usim_data.nasconfig.AttachWithImsi.value[0] = 0x00; -#else - usim_data.nasconfig.AttachWithImsi.value[0] = 0x01; -#endif - usim_data.nasconfig.MinimumPeriodicSearchTimer.type = USIM_MINIMUM_PERIODIC_SEARCH_TIMER_TAG; - usim_data.nasconfig.MinimumPeriodicSearchTimer.length = 1; - usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0] = 0x00; - usim_data.nasconfig.ExtendedAccessBarring.type = USIM_EXTENDED_ACCESS_BARRING_TAG; - usim_data.nasconfig.ExtendedAccessBarring.length = 1; - usim_data.nasconfig.ExtendedAccessBarring.value[0] = 0x00; - usim_data.nasconfig.Timer_T3245_Behaviour.type = USIM_TIMER_T3245_BEHAVIOUR_TAG; - usim_data.nasconfig.Timer_T3245_Behaviour.length = 1; - usim_data.nasconfig.Timer_T3245_Behaviour.value[0] = 0x00; - - /* - * Write USIM application data - */ - rc = usim_api_write(path, &usim_data); - - if (rc != RETURNok) { - perror("ERROR\t: usim_api_write() failed"); - exit(EXIT_FAILURE); - } - } - - /* - * Read USIM application data - */ - memset(&usim_data, 0, sizeof(usim_data_t)); - rc = usim_api_read(path, &usim_data); - - if (rc != RETURNok) { - perror("ERROR\t: usim_api_read() failed"); - exit(EXIT_FAILURE); - } - - /* - * Display USIM application data - */ - printf("\nUSIM data:\n\n"); - _display_usim_data(&usim_data); - - /* - * Display USIM file location - */ - printf("\nUSIM data file: %s\n", path); - free(path); - - exit(EXIT_SUCCESS); -} - -/****************************************************************************/ -/********************* L O C A L F U N C T I O N S *********************/ -/****************************************************************************/ - -/* - * Displays command line usage - */ -static void _display_usage(const char* command) -{ - fprintf(stderr, "usage: %s [OPTION]\n", command); - fprintf(stderr, "\t[--gen|-g]\tGenerate the USIM data file\n"); - fprintf(stderr, "\t[--print|-p]\tDisplay the content of the USIM data file\n"); - fprintf(stderr, "\t[--help|-h]\tDisplay this usage\n"); - const char* path = getenv("USIM_DIR"); - - if (path != NULL) { - fprintf(stderr, "USIM_DIR = %s\n", path); - } else { - fprintf(stderr, "USIM_DIR environment variable is not defined\n"); - } -} - -/* - * Displays USIM application data - */ -static void _display_usim_data(const usim_data_t* data) -{ - int digits; - - printf("Administrative Data:\n"); - printf("\tUE_Operation_Mode\t= 0x%.2x\n", data->ad.UE_Operation_Mode); - printf("\tAdditional_Info\t\t= 0x%.4x\n", data->ad.Additional_Info); - printf("\tMNC_Length\t\t= %d\n\n", data->ad.MNC_Length); - - printf("IMSI:\n"); - printf("\tlength\t= %d\n", data->imsi.length); - printf("\tparity\t= %s\n", data->imsi.u.num.parity == EVEN_PARITY ? "Even" : "Odd"); - digits = (data->imsi.length * 2) - 1 - (data->imsi.u.num.parity == EVEN_PARITY ? 1 : 0); - printf("\tdigits\t= %d\n", digits); - - printf("\tdigits\t= %u%u%u%u%u%x%u%u%u%u", - data->imsi.u.num.digit1, // MCC digit 1 - data->imsi.u.num.digit2, // MCC digit 2 - data->imsi.u.num.digit3, // MCC digit 3 - data->imsi.u.num.digit4, // MNC digit 1 - data->imsi.u.num.digit5, // MNC digit 2 - data->imsi.u.num.digit6==0xf?0:data->imsi.u.num.digit6, // MNC digit 3 - data->imsi.u.num.digit7, - data->imsi.u.num.digit8, - data->imsi.u.num.digit9, - data->imsi.u.num.digit10); - - if (digits >= 11) - printf("%x", data->imsi.u.num.digit11); - - if (digits >= 12) - printf("%x", data->imsi.u.num.digit12); - - if (digits >= 13) - printf("%x", data->imsi.u.num.digit13); - - if (digits >= 14) - printf("%x", data->imsi.u.num.digit14); - - if (digits >= 15) - printf("%x", data->imsi.u.num.digit15); - - printf("\n\n"); - - printf("Ciphering and Integrity Keys:\n"); - printf("\tKSI\t: 0x%.2x\n", data->keys.ksi); - char key[USIM_CK_SIZE + 1]; - key[USIM_CK_SIZE] = '\0'; - memcpy(key, data->keys.ck, USIM_CK_SIZE); - printf("\tCK\t: \"%s\"\n", key); - memcpy(key, data->keys.ik, USIM_IK_SIZE); - printf("\tIK\t: \"%s\"\n", key); - - printf("EPS NAS security context:\n"); - printf("\tKSIasme\t: 0x%.2x\n", data->securityctx.KSIasme.value[0]); - char kasme[USIM_K_ASME_SIZE + 1]; - kasme[USIM_K_ASME_SIZE] = '\0'; - memcpy(kasme, data->securityctx.Kasme.value, USIM_K_ASME_SIZE); - printf("\tKasme\t: \"%s\"\n", kasme); - printf("\tulNAScount\t: 0x%.8x\n", - *(uint32_t*)data->securityctx.ulNAScount.value); - printf("\tdlNAScount\t: 0x%.8x\n", - *(uint32_t*)data->securityctx.dlNAScount.value); - printf("\talgorithmID\t: 0x%.2x\n\n", - data->securityctx.algorithmID.value[0]); - - printf("MSISDN\t= %u%u%u %u%u%u%u %u%u%u%u\n\n", - data->msisdn.number.digit[0].msb, - data->msisdn.number.digit[0].lsb, - data->msisdn.number.digit[1].msb, - data->msisdn.number.digit[1].lsb, - data->msisdn.number.digit[2].msb, - data->msisdn.number.digit[2].lsb, - data->msisdn.number.digit[3].msb, - data->msisdn.number.digit[3].lsb, - data->msisdn.number.digit[4].msb, - data->msisdn.number.digit[4].lsb, - data->msisdn.number.digit[5].msb); - - for (int i = 0; i < USIM_PNN_MAX; i++) { - printf("PNN[%d]\t= {%s, %s}\n", i, - data->pnn[i].fullname.value, data->pnn[i].shortname.value); - } - - printf("\n"); - - for (int i = 0; i < USIM_OPL_MAX; i++) { - printf("OPL[%d]\t= ", i); - PRINT_PLMN(data->opl[i].plmn); - printf(", TAC = [%.4x - %.4x], record_id = %d\n", - data->opl[i].start, data->opl[i].end, data->opl[i].record_id); - } - - printf("\n"); - - printf("HPLMN\t\t= "); - PRINT_PLMN(data->hplmn.plmn); - printf(", AcT = 0x%x\n\n", data->hplmn.AcT); - - for (int i = 0; i < USIM_FPLMN_MAX; i++) { - printf("FPLMN[%d]\t= ", i); - PRINT_PLMN(data->fplmn[i]); - printf("\n"); - } - - printf("\n"); - - for (int i = 0; i < USIM_EHPLMN_MAX; i++) { - printf("EHPLMN[%d]\t= ", i); - PRINT_PLMN(data->ehplmn[i]); - printf("\n"); - } - - printf("\n"); - - for (int i = 0; i < USIM_PLMN_MAX; i++) { - printf("PLMN[%d]\t\t= ", i); - PRINT_PLMN(data->plmn[i].plmn); - printf(", AcTPLMN = 0x%x", data->plmn[i].AcT); - printf("\n"); - } - - printf("\n"); - - for (int i = 0; i < USIM_OPLMN_MAX; i++) { - printf("OPLMN[%d]\t= ", i); - PRINT_PLMN(data->oplmn[i].plmn); - printf(", AcTPLMN = 0x%x", data->oplmn[i].AcT); - printf("\n"); - } - - printf("\n"); - - printf("HPPLMN\t\t= 0x%.2x (%d minutes)\n\n", data->hpplmn, data->hpplmn); - - printf("LOCI:\n"); - printf("\tTMSI = 0x%.4x\n", data->loci.tmsi); - printf("\tLAI\t: PLMN = "); - PRINT_PLMN(data->loci.lai.plmn); - printf(", LAC = 0x%.2x\n", data->loci.lai.lac); - printf("\tstatus\t= %d\n\n", data->loci.status); - - printf("PSLOCI:\n"); - printf("\tP-TMSI = 0x%.4x\n", data->psloci.p_tmsi); - printf("\tsignature = 0x%x 0x%x 0x%x\n", - data->psloci.signature[0], - data->psloci.signature[1], - data->psloci.signature[2]); - printf("\tRAI\t: PLMN = "); - PRINT_PLMN(data->psloci.rai.plmn); - printf(", LAC = 0x%.2x, RAC = 0x%.1x\n", - data->psloci.rai.lac, data->psloci.rai.rac); - printf("\tstatus\t= %d\n\n", data->psloci.status); - - printf("EPSLOCI:\n"); - printf("\tGUTI\t: GUMMEI\t: (PLMN = "); - PRINT_PLMN(data->epsloci.guti.gummei.plmn); - printf(", MMEgid = 0x%.2x, MMEcode = 0x%.1x)", - data->epsloci.guti.gummei.MMEgid, - data->epsloci.guti.gummei.MMEcode); - printf(", M-TMSI = 0x%.4x\n", data->epsloci.guti.m_tmsi); - printf("\tTAI\t: PLMN = "); - PRINT_PLMN(data->epsloci.tai.plmn); - printf(", TAC = 0x%.2x\n", - data->epsloci.tai.tac); - printf("\tstatus\t= %d\n\n", data->epsloci.status); - - printf("NASCONFIG:\n"); - printf("\tNAS_SignallingPriority\t\t: 0x%.2x\n", - data->nasconfig.NAS_SignallingPriority.value[0]); - printf("\tNMO_I_Behaviour\t\t\t: 0x%.2x\n", - data->nasconfig.NMO_I_Behaviour.value[0]); - printf("\tAttachWithImsi\t\t\t: 0x%.2x\n", - data->nasconfig.AttachWithImsi.value[0]); - printf("\tMinimumPeriodicSearchTimer\t: 0x%.2x\n", - data->nasconfig.MinimumPeriodicSearchTimer.value[0]); - printf("\tExtendedAccessBarring\t\t: 0x%.2x\n", - data->nasconfig.ExtendedAccessBarring.value[0]); - printf("\tTimer_T3245_Behaviour\t\t: 0x%.2x\n", - data->nasconfig.Timer_T3245_Behaviour.value[0]); -} - diff --git a/openair3/NAS/UE/API/USIM/aka_functions.c b/openair3/NAS/UE/API/USIM/aka_functions.c index 68efb2b24a..4d8f4cd1d3 100644 --- a/openair3/NAS/UE/API/USIM/aka_functions.c +++ b/openair3/NAS/UE/API/USIM/aka_functions.c @@ -49,16 +49,14 @@ * *-----------------------------------------------------------------*/ void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], - u8 mac_a_pP[8], const u8 op[16]) + u8 mac_a_pP[8], const u8 op_c[16]) { - u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -104,9 +102,8 @@ void f1 ( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], * *-----------------------------------------------------------------*/ void f2345 ( u8 k_pP[16], u8 rand_pP[16], - u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6],const u8 op[16]) + u8 res_pP[8], u8 ck_pP[16], u8 ik_pP[16], u8 ak_pP[6],const u8 op_c[16]) { - u8 op_c[16]; u8 temp[16]; u8 out[16]; u8 rijndaelInput[16]; @@ -122,7 +119,6 @@ void f2345 ( u8 k_pP[16], u8 rand_pP[16], rand_pP[8],rand_pP[9],rand_pP[10],rand_pP[11],rand_pP[12],rand_pP[13],rand_pP[14],rand_pP[15]); RijndaelKeySchedule( k_pP ); - ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -205,16 +201,14 @@ void f2345 ( u8 k_pP[16], u8 rand_pP[16], * *-----------------------------------------------------------------*/ void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], - u8 mac_s_pP[8],const u8 op[16]) + u8 mac_s_pP[8],const u8 op_c[16]) { - u8 op_c[16]; u8 temp[16]; u8 in1[16]; u8 out1[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; @@ -260,15 +254,13 @@ void f1star( u8 k_pP[16], u8 rand_pP[16], u8 sqn_pP[6], u8 amf_pP[2], * *-----------------------------------------------------------------*/ void f5star( u8 k_pP[16], u8 rand_pP[16], - u8 ak_pP[6], const u8 op[16]) + u8 ak_pP[6], const u8 op_c[16]) { - u8 op_c[16]; u8 temp[16]; u8 out[16]; u8 rijndaelInput[16]; u8 i; RijndaelKeySchedule( k_pP ); - ComputeOPc(op, op_c); for (i=0; i<16; i++) rijndaelInput[i] = rand_pP[i] ^ op_c[i]; diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index ef6b4f9101..e281999a09 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -88,22 +88,6 @@ int usim_api_read(const char *filename, usim_data_t* data) LOG_FUNC_RETURN (RETURNerror); } - /* initialize the subscriber authentication security key */ - hex_string_to_hex_value(data->keys.usim_api_k, USIM_API_K_VALUE, USIM_API_K_SIZE); - - // initialize OP - /* PFT OP used currently in HSS (OPENAIRHSS/auc/kdf.c) */ - #define OAI_LTEBOX - - #ifdef OAI_LTEBOX - u8 _op[16] = {0x10, 0x06, 0x02, 0x0f, 0x0a, 0x47, 0x8b, 0xf6, - 0xb6, 0x99, 0xf1, 0x5c, 0x06, 0x2e, 0x42, 0xb3 }; - #else - u8 _op[16] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; - #endif - memcpy(data->keys.op, _op, sizeof(_op)); - LOG_FUNC_RETURN (RETURNok); } @@ -367,7 +351,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co u8 ak[USIM_API_AK_SIZE]; f2345(usim_data->keys.usim_api_k, rand_pP->value, - res_pP->value, ck_pP->value, ik_pP->value, ak, usim_data->keys.op); + res_pP->value, ck_pP->value, ik_pP->value, ak, usim_data->keys.opc); LOG_TRACE(INFO, "USIM-API - res(f2) :%s",dump_octet_string(res_pP)); LOG_TRACE(INFO, "USIM-API - ck(f3) :%s",dump_octet_string(ck_pP)); LOG_TRACE(INFO, "USIM-API - ik(f4) :%s",dump_octet_string(ik_pP)); @@ -388,7 +372,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co /* Compute XMAC = f1K (SQN || RAND || AMF) */ #define USIM_API_XMAC_SIZE 8 u8 xmac[USIM_API_XMAC_SIZE]; - f1(usim_data->keys.usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac, usim_data->keys.op); + f1(usim_data->keys.usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac, usim_data->keys.opc); LOG_TRACE(DEBUG, "USIM-API - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X", xmac[0],xmac[1],xmac[2],xmac[3], @@ -416,7 +400,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co /* Concealed value of the counter SQNms in the USIM: * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ - f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.op); + f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.opc); u8 sqn_ms[USIM_API_SQNMS_SIZE]; @@ -445,7 +429,7 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co #define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE u8 macs[USIM_API_MACS_SIZE]; f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms, - &rand_pP->value[USIM_API_SQN_SIZE], macs, usim_data->keys.op); + &rand_pP->value[USIM_API_SQN_SIZE], macs, usim_data->keys.opc); LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X", macs[0],macs[1],macs[2],macs[3], macs[4],macs[5],macs[6],macs[7]); diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index 74123029dd..5915d914bf 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -124,7 +124,7 @@ typedef struct { #define USIM_IK_SIZE 16 Byte_t ik[USIM_IK_SIZE]; uint8_t usim_api_k[USIM_API_K_SIZE]; - uint8_t op[16]; + uint8_t opc[16]; } usim_keys_t; /* diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index efb17a13c2..d548d480c7 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -104,21 +104,21 @@ void *nas_ue_task(void *args_p) user->ueid=i; /* Get USIM data application filename */ - user->usim_data_store = memory_get_path(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME); + user->usim_data_store = memory_get_path_from_ueid(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME, user->ueid); if ( user->usim_data_store == NULL ) { - LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); + LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid, user->ueid); exit(EXIT_FAILURE); } /* Get UE's data pathname */ - user->user_nvdata_store = memory_get_path(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME); + user->user_nvdata_store = memory_get_path_from_ueid(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME, user->ueid); if ( user->user_nvdata_store == NULL ) { LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid); exit(EXIT_FAILURE); } /* Get EMM data pathname */ - user->emm_nvdata_store = memory_get_path(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME); + user->emm_nvdata_store = memory_get_path_from_ueid(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME, user->ueid); if ( user->emm_nvdata_store == NULL ) { LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid); exit(EXIT_FAILURE); From fe2193ba75358df406061ca9b9fc8ba16c648f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 2 Aug 2016 11:06:00 +0200 Subject: [PATCH 191/571] fix .ue* filenames in scripts and documentation TODO add option to conf2uedata and adapt script --- cmake_targets/tools/build_helper | 2 +- openair3/NAS/TEST/NETWORK/README | 12 ++++++------ .../GENERIC-LTE-EPC/start_enb_and_ue_virt.bash | 12 ++++++------ targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash | 12 ++++++------ targets/build_helper.bash | 12 ++++++------ targets/build_oai.bash | 8 ++++---- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 8a9d64b6d8..5d4a1dbeae 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -450,7 +450,7 @@ install_asn1c_from_source(){ ################################################ install_nas_tools() { - if [ ! -f $2/§.ue.nvram -o ! -f $2/.usim.nvram ]; then + if [ ! -f $2/.ue.nvram0 -o ! -f $2/.usim.nvram0 ]; then cd $OPENAIR_DIR/targets/bin ./conf2uedata -c $1 -o $2 echo_success "$1 $2" diff --git a/openair3/NAS/TEST/NETWORK/README b/openair3/NAS/TEST/NETWORK/README index 25a6de5d14..465e355e78 100644 --- a/openair3/NAS/TEST/NETWORK/README +++ b/openair3/NAS/TEST/NETWORK/README @@ -18,9 +18,9 @@ EURECOM-NAS directory should contain following files: EURECOM-NAS |-- bin -| |-- .ue.nvram -| |-- .ue_emm.nvram -| |-- .usim.nvram +| |-- .ue.nvram0 +| |-- .ue_emm.nvram0 +| |-- .usim.nvram0 | |-- NetworkProcess | |-- UEprocess | `-- UserProcess @@ -57,10 +57,10 @@ UE for testing purpose. When starting up, UEprocess reads configuration data from .nvram binary files used as UE's non-volatile memory. -.usim.nvram contains data stored into the USIM -.ue.nvram contains data related to the UE identification (IMEI, +.usim.nvram0 contains data stored into the USIM +.ue.nvram0 contains data related to the UE identification (IMEI, manufacturer, model, PIN code) -.ue_emm.nvram contains data related to EPS Mobility Management (IMSI, last +.ue_emm.nvram0 contains data related to EPS Mobility Management (IMSI, last registered PLMN) -------------------------------------------------------------------------------- diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash b/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash index 5339af13e4..6ea2d5bb0a 100755 --- a/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash +++ b/targets/PROJECTS/GENERIC-LTE-EPC/start_enb_and_ue_virt.bash @@ -125,18 +125,18 @@ if [ ! -f $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data ] || [ ! -f $OPENAIR3_DIR/NA fi echo_success "make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS -f Makefile PROCESS=UE all" make -f Makefile --debug=b --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS PROCESS=UE all - rm .ue.nvram - rm .usim.nvram + rm .ue.nvram0 + rm .usim.nvram0 touch /tmp/nas_cleaned fi -if [ ! -f .ue.nvram ]; then - echo_success "generate .ue_emm.nvram .ue.nvram" +if [ ! -f .ue.nvram0 ]; then + echo_success "generate .ue_emm.nvram0 .ue.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi -if [ ! -f .usim.nvram ]; then - echo_success "generate .usim.nvram" +if [ ! -f .usim.nvram0 ]; then + echo_success "generate .usim.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash b/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash index e6d96602e2..ff16e27982 100755 --- a/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash +++ b/targets/PROJECTS/GENERIC-LTE-EPC/start_ue.bash @@ -68,20 +68,20 @@ export NVRAM_DIR=$THIS_SCRIPT_PATH if [ ! -f $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data ]; then make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS veryveryclean make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS PROCESS=UE - rm .ue.nvram + rm .ue.nvram0 fi if [ ! -f $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data ]; then make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS veryveryclean make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS PROCESS=UE - rm .usim.nvram + rm .usim.nvram0 fi -if [ ! -f .ue.nvram ]; then - # generate .ue_emm.nvram .ue.nvram +if [ ! -f .ue.nvram0 ]; then + # generate .ue_emm.nvram0 .ue.nvram0 $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi -if [ ! -f .usim.nvram ]; then - # generate .usim.nvram +if [ ! -f .usim.nvram0 ]; then + # generate .usim.nvram0 $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print diff --git a/targets/build_helper.bash b/targets/build_helper.bash index 163be3ba53..f161275c65 100755 --- a/targets/build_helper.bash +++ b/targets/build_helper.bash @@ -852,8 +852,8 @@ compile_nas_tools() { fi echo_success "make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS/tools all" make --directory=$OPENAIR3_DIR/NAS/EURECOM-NAS/tools all - rm .ue.nvram - rm .usim.nvram + rm .ue.nvram0 + rm .usim.nvram0 touch /tmp/nas_cleaned } @@ -1027,13 +1027,13 @@ install_oaisim() { install_nas_tools() { cd $OPENAIR_TARGETS/bin - if [ ! -f .ue.nvram ]; then - echo_success "generate .ue_emm.nvram .ue.nvram" + if [ ! -f .ue.nvram0 ]; then + echo_success "generate .ue_emm.nvram0 .ue.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi - if [ ! -f .usim.nvram ]; then - echo_success "generate .usim.nvram" + if [ ! -f .usim.nvram0 ]; then + echo_success "generate .usim.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print diff --git a/targets/build_oai.bash b/targets/build_oai.bash index 1303ef9e7e..7a6a179beb 100755 --- a/targets/build_oai.bash +++ b/targets/build_oai.bash @@ -756,13 +756,13 @@ if [ $RUN -ne 0 ]; then install_nasmesh else # prepare NAS for UE - if [ ! -f .ue.nvram ]; then - echo_success "generate .ue_emm.nvram .ue.nvram" + if [ ! -f .ue.nvram0 ]; then + echo_success "generate .ue_emm.nvram0 .ue.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --gen fi - if [ ! -f .usim.nvram ]; then - echo_success "generate .usim.nvram" + if [ ! -f .usim.nvram0 ]; then + echo_success "generate .usim.nvram0" $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/usim_data --gen fi $OPENAIR3_DIR/NAS/EURECOM-NAS/bin/ue_data --print From 33b2d11fc2498077393ceacef19bf47a62493932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 10:55:05 +0200 Subject: [PATCH 192/571] fix(conf2uedata): clarify error message when config file does not exists --- openair3/NAS/TOOLS/conf2uedata.c | 43 +++++++++++++++++++++----------- openair3/NAS/TOOLS/conf2uedata.h | 1 - 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index a5aaf9ccb0..094d44f464 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -7,10 +7,12 @@ #include "utils.h" char * make_filename(const char *output_dir, const char *filename, int ueid); +int get_config_from_file(const char *filename, config_t *config); int main(int argc, char**argv) { int rc = EXIT_SUCCESS; int option; + const char* conf_file = NULL; while ((option = getopt(argc, argv, options)) != -1) { switch (option) { case 'c': @@ -42,26 +44,17 @@ int main(int argc, char**argv) { _display_usage(); return EXIT_FAILURE; } else if (parse_data) { + int ret; int ue_nb = 0; - config_t cfg; config_setting_t *root_setting = NULL; config_setting_t *ue_setting = NULL; config_setting_t *all_plmn_setting = NULL; char user[10]; - config_init(&cfg); - if (conf_file != NULL) { - /* Read the file. If there is an error, report it and exit. */ - if (!config_read_file(&cfg, conf_file)) { - fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), - config_error_line(&cfg), config_error_text(&cfg)); - config_destroy(&cfg); - return (EXIT_FAILURE); - } - } else { - config_destroy(&cfg); - perror("ERROR\t: config_read failed"); - exit(EXIT_FAILURE); - } + config_t cfg; + ret = get_config_from_file(conf_file, &cfg); + if (ret == EXIT_FAILURE) { + exit(1); + } root_setting = config_root_setting(&cfg); ue_nb = config_setting_length(root_setting) - 1; all_plmn_setting = config_setting_get_member(root_setting, PLMN); @@ -112,6 +105,26 @@ int main(int argc, char**argv) { } +int get_config_from_file(const char *filename, config_t *config) { + config_init(config); + if (filename == NULL) { + // XXX write error message ? + exit(EXIT_FAILURE); + } + + /* Read the file. If there is an error, report it and exit. */ + if (!config_read_file(config, filename)) { + fprintf(stderr, "Cant read config file '%s': %s\n", filename, + config_error_text(config)); + if ( config_error_type(config) == CONFIG_ERR_PARSE ) { + fprintf(stderr, "This is line %d\n", config_error_line(config)); + } + config_destroy(config); + return (EXIT_FAILURE); + } + return EXIT_SUCCESS; +} + void gen_usim_data(int user_id) { usim_data_t usim_data = { }; memset(&usim_data, 0, sizeof(usim_data_t)); diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 06c0027c78..44cb65c9b9 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -98,7 +98,6 @@ const char options[]="c:o:h"; unsigned char parse_data=FALSE; unsigned char print_data=FALSE; unsigned char output=FALSE; -const char* conf_file = NULL; const char* output_dir = NULL; const char* imsi=NULL; From 804595d48399991d86b068c2fb788150515e7f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 11:18:13 +0200 Subject: [PATCH 193/571] style(conf2uedata.c): rewrite main() for readability --- openair3/NAS/TOOLS/conf2uedata.c | 101 +++++++++++++++++-------------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 094d44f464..96902098f1 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -13,7 +13,8 @@ int main(int argc, char**argv) { int rc = EXIT_SUCCESS; int option; const char* conf_file = NULL; - while ((option = getopt(argc, argv, options)) != -1) { + + while ((option = getopt(argc, argv, options)) != -1) { switch (option) { case 'c': parse_data = TRUE; @@ -31,19 +32,26 @@ int main(int argc, char**argv) { break; } } + if (output == FALSE && parse_data == TRUE) { printf("No output option found\n"); _display_usage(); return EXIT_FAILURE; - } else if (output == TRUE && parse_data == FALSE) { + } + + if (output == TRUE && parse_data == FALSE) { printf("No Configuration file is given\n"); _display_usage(); return EXIT_FAILURE; - } else if (parse_data == FALSE && print_data == FALSE) { + } + + if (parse_data == FALSE && print_data == FALSE) { printf("No options found\n"); _display_usage(); return EXIT_FAILURE; - } else if (parse_data) { + } + + if (parse_data) { int ret; int ue_nb = 0; config_setting_t *root_setting = NULL; @@ -51,55 +59,60 @@ int main(int argc, char**argv) { config_setting_t *all_plmn_setting = NULL; char user[10]; config_t cfg; + ret = get_config_from_file(conf_file, &cfg); if (ret == EXIT_FAILURE) { exit(1); } + root_setting = config_root_setting(&cfg); ue_nb = config_setting_length(root_setting) - 1; - all_plmn_setting = config_setting_get_member(root_setting, PLMN); - if (all_plmn_setting != NULL) { - rc = parse_plmns(all_plmn_setting); - if (rc == EXIT_FAILURE) { - return rc; - } - fill_network_record_list(); - for (int i = 0; i < ue_nb; i++) { - sprintf(user, "%s%d", UE, i); - ue_setting = config_setting_get_member(root_setting, user); - if (ue_setting != NULL) { - rc = parse_ue_user_param(ue_setting, i); - if (rc != EXIT_SUCCESS) { - printf("Problem in USER section for UE%d. EXITING...\n", - i); - return EXIT_FAILURE; - } - _display_ue_data(i); - rc = parse_ue_sim_param(ue_setting, i); - if (rc != EXIT_SUCCESS) { - printf("Problem in SIM section for UE%d. EXITING...\n", - i); - return EXIT_FAILURE; - } - rc = parse_ue_plmn_param(ue_setting, i); - if (rc != EXIT_SUCCESS) { - return EXIT_FAILURE; - } - gen_emm_data(i); - _display_emm_data(i); - gen_usim_data(i); - _display_usim_data(i); - } else { - printf("Check UE%d settings\n", i); - return EXIT_FAILURE; - } - } - config_destroy(&cfg); - } else { + all_plmn_setting = config_setting_get_member(root_setting, PLMN); + if (all_plmn_setting == NULL) { printf("NO PLMN SECTION...EXITING...\n"); return (EXIT_FAILURE); - } + } + + rc = parse_plmns(all_plmn_setting); + if (rc == EXIT_FAILURE) { + return rc; + } + fill_network_record_list(); + + for (int i = 0; i < ue_nb; i++) { + sprintf(user, "%s%d", UE, i); + + ue_setting = config_setting_get_member(root_setting, user); + if (ue_setting == NULL) { + printf("Check UE%d settings\n", i); + return EXIT_FAILURE; + } + + rc = parse_ue_user_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + printf("Problem in USER section for UE%d. EXITING...\n", i); + return EXIT_FAILURE; + } + _display_ue_data(i); + + rc = parse_ue_sim_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + printf("Problem in SIM section for UE%d. EXITING...\n", i); + return EXIT_FAILURE; + } + + rc = parse_ue_plmn_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + return EXIT_FAILURE; + } + gen_emm_data(i); + _display_emm_data(i); + + gen_usim_data(i); + _display_usim_data(i); + } + config_destroy(&cfg); } exit(EXIT_SUCCESS); From 292535fe063d2b80df9b39fc109704f68e459ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 11:44:56 +0200 Subject: [PATCH 194/571] refactor(conf2uedata.c): rewrite main() and add parse_config_file() --- openair3/NAS/TOOLS/conf2uedata.c | 145 +++++++++++++++---------------- 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 96902098f1..32b0f7bf95 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -8,21 +8,19 @@ char * make_filename(const char *output_dir, const char *filename, int ueid); int get_config_from_file(const char *filename, config_t *config); +int parse_config_file(const char *filename); int main(int argc, char**argv) { - int rc = EXIT_SUCCESS; int option; const char* conf_file = NULL; while ((option = getopt(argc, argv, options)) != -1) { switch (option) { case 'c': - parse_data = TRUE; conf_file = optarg; break; case 'o': output_dir = optarg; - output = TRUE; break; case 'h': _display_usage(); @@ -33,91 +31,92 @@ int main(int argc, char**argv) { } } - if (output == FALSE && parse_data == TRUE) { + if (output_dir == NULL ) { printf("No output option found\n"); _display_usage(); return EXIT_FAILURE; } - if (output == TRUE && parse_data == FALSE) { + if ( conf_file == NULL ) { printf("No Configuration file is given\n"); _display_usage(); return EXIT_FAILURE; } - if (parse_data == FALSE && print_data == FALSE) { - printf("No options found\n"); - _display_usage(); - return EXIT_FAILURE; - } + if ( parse_config_file(conf_file) == EXIT_FAILURE ) { + exit(EXIT_FAILURE); + } - if (parse_data) { - int ret; - int ue_nb = 0; - config_setting_t *root_setting = NULL; - config_setting_t *ue_setting = NULL; - config_setting_t *all_plmn_setting = NULL; - char user[10]; - config_t cfg; - - ret = get_config_from_file(conf_file, &cfg); - if (ret == EXIT_FAILURE) { - exit(1); - } - - root_setting = config_root_setting(&cfg); - ue_nb = config_setting_length(root_setting) - 1; - - all_plmn_setting = config_setting_get_member(root_setting, PLMN); - if (all_plmn_setting == NULL) { - printf("NO PLMN SECTION...EXITING...\n"); - return (EXIT_FAILURE); - } - - rc = parse_plmns(all_plmn_setting); - if (rc == EXIT_FAILURE) { - return rc; - } - fill_network_record_list(); - - for (int i = 0; i < ue_nb; i++) { - sprintf(user, "%s%d", UE, i); - - ue_setting = config_setting_get_member(root_setting, user); - if (ue_setting == NULL) { - printf("Check UE%d settings\n", i); - return EXIT_FAILURE; - } - - rc = parse_ue_user_param(ue_setting, i); - if (rc != EXIT_SUCCESS) { - printf("Problem in USER section for UE%d. EXITING...\n", i); - return EXIT_FAILURE; - } - _display_ue_data(i); - - rc = parse_ue_sim_param(ue_setting, i); - if (rc != EXIT_SUCCESS) { - printf("Problem in SIM section for UE%d. EXITING...\n", i); - return EXIT_FAILURE; - } - - rc = parse_ue_plmn_param(ue_setting, i); - if (rc != EXIT_SUCCESS) { - return EXIT_FAILURE; - } - gen_emm_data(i); - _display_emm_data(i); - - gen_usim_data(i); - _display_usim_data(i); - } - config_destroy(&cfg); - } exit(EXIT_SUCCESS); } +int parse_config_file(const char *filename) { + int rc = EXIT_SUCCESS; + int ret; + int ue_nb = 0; + config_setting_t *root_setting = NULL; + config_setting_t *ue_setting = NULL; + config_setting_t *all_plmn_setting = NULL; + char user[10]; + config_t cfg; + + ret = get_config_from_file(filename, &cfg); + if (ret == EXIT_FAILURE) { + exit(1); + } + + root_setting = config_root_setting(&cfg); + ue_nb = config_setting_length(root_setting) - 1; + + all_plmn_setting = config_setting_get_member(root_setting, PLMN); + if (all_plmn_setting == NULL) { + printf("NO PLMN SECTION...EXITING...\n"); + return (EXIT_FAILURE); + } + + rc = parse_plmns(all_plmn_setting); + if (rc == EXIT_FAILURE) { + return rc; + } + fill_network_record_list(); + + for (int i = 0; i < ue_nb; i++) { + sprintf(user, "%s%d", UE, i); + + ue_setting = config_setting_get_member(root_setting, user); + if (ue_setting == NULL) { + printf("Check UE%d settings\n", i); + return EXIT_FAILURE; + } + + rc = parse_ue_user_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + printf("Problem in USER section for UE%d. EXITING...\n", i); + return EXIT_FAILURE; + } + _display_ue_data(i); + + rc = parse_ue_sim_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + printf("Problem in SIM section for UE%d. EXITING...\n", i); + return EXIT_FAILURE; + } + + rc = parse_ue_plmn_param(ue_setting, i); + if (rc != EXIT_SUCCESS) { + return EXIT_FAILURE; + } + gen_emm_data(i); + _display_emm_data(i); + + gen_usim_data(i); + _display_usim_data(i); + } + config_destroy(&cfg); + return(EXIT_SUCCESS); +} + int get_config_from_file(const char *filename, config_t *config) { config_init(config); if (filename == NULL) { From e2dc453b62047aa732cec3ccfdbb597f59891822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 11:54:29 +0200 Subject: [PATCH 195/571] fix(conf2uedata): fix missing extern in header --- openair3/NAS/TOOLS/conf2uedata.c | 29 +++++++++++++--- openair3/NAS/TOOLS/conf2uedata.h | 57 ++++++++++++++++---------------- 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 32b0f7bf95..3d4c416ecc 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -6,13 +6,35 @@ #include "user_api.h" #include "utils.h" -char * make_filename(const char *output_dir, const char *filename, int ueid); -int get_config_from_file(const char *filename, config_t *config); -int parse_config_file(const char *filename); +const char *output_dir = NULL; + +const char *msin = NULL; +const char *usim_api_k = NULL; +const char *msisdn = NULL; +const char *opc = NULL; +const char *hplmn = NULL; + +int *ucplmn = NULL; +int *oplmn = NULL; +int *ocplmn = NULL; +int *fplmn = NULL; +int *ehplmn = NULL; + +int hplmn_index = 0; +int plmn_nb = 0; +int ucplmn_nb = 0; +int oplmn_nb = 0; +int ocplmn_nb = 0; +int fplmn_nb = 0; +int ehplmn_nb = 0; + +plmn_conf_param_t* user_plmn_list=NULL; +network_record_t* user_network_record_list = NULL; int main(int argc, char**argv) { int option; const char* conf_file = NULL; + const char options[]="c:o:h"; while ((option = getopt(argc, argv, options)) != -1) { switch (option) { @@ -48,7 +70,6 @@ int main(int argc, char**argv) { } exit(EXIT_SUCCESS); - } int parse_config_file(const char *filename) { diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 44cb65c9b9..c2571860c0 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -88,41 +88,40 @@ typedef struct { } network_record_t; typedef struct { - const char* fullname; - const char* shortname; - const char* mnc; - const char* mcc; + const char *fullname; + const char *shortname; + const char *mnc; + const char *mcc; } plmn_conf_param_t; -const char options[]="c:o:h"; -unsigned char parse_data=FALSE; -unsigned char print_data=FALSE; -unsigned char output=FALSE; -const char* output_dir = NULL; +extern const char* output_dir; -const char* imsi=NULL; -const char* msin=NULL; -const char* usim_api_k = NULL; -const char* msisdn = NULL; -const char* opc=NULL; -const char* hplmn=NULL; +extern const char *msin; +extern const char *usim_api_k; +extern const char *msisdn; +extern const char *opc; +extern const char *hplmn; -int* ucplmn=NULL; -int* oplmn=NULL; -int* ocplmn=NULL; -int* fplmn=NULL; -int* ehplmn=NULL; +extern int *ucplmn; +extern int *oplmn; +extern int *ocplmn; +extern int *fplmn; +extern int *ehplmn; -int hplmn_index =0; -int plmn_nb = 0; -int ucplmn_nb=0; -int oplmn_nb=0; -int ocplmn_nb=0; -int fplmn_nb=0; -int ehplmn_nb=0; +extern int hplmn_index; +extern int plmn_nb; +extern int ucplmn_nb; +extern int oplmn_nb; +extern int ocplmn_nb; +extern int fplmn_nb; +extern int ehplmn_nb; -plmn_conf_param_t* user_plmn_list=NULL; -network_record_t* user_network_record_list = NULL; +extern plmn_conf_param_t* user_plmn_list; +extern network_record_t* user_network_record_list; + +char *make_filename(const char *output_dir, const char *filename, int ueid); +int get_config_from_file(const char *filename, config_t *config); +int parse_config_file(const char *filename); void _display_usim_data(int user_id); From 8ae72d1cf1c1c77f79e874eec75145c78af38a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 14:19:21 +0200 Subject: [PATCH 196/571] refactor(conf2uedata): put display out of build --- openair3/NAS/TOOLS/conf2uedata.c | 76 +++++++++++++++++++++++--------- openair3/NAS/TOOLS/conf2uedata.h | 14 ++++-- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 3d4c416ecc..e6d9554b0c 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -69,6 +69,8 @@ int main(int argc, char**argv) { exit(EXIT_FAILURE); } + display_data_from_directory(output_dir); + exit(EXIT_SUCCESS); } @@ -116,7 +118,6 @@ int parse_config_file(const char *filename) { printf("Problem in USER section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } - _display_ue_data(i); rc = parse_ue_sim_param(ue_setting, i); if (rc != EXIT_SUCCESS) { @@ -129,10 +130,7 @@ int parse_config_file(const char *filename) { return EXIT_FAILURE; } gen_emm_data(i); - _display_emm_data(i); - gen_usim_data(i); - _display_usim_data(i); } config_destroy(&cfg); return(EXIT_SUCCESS); @@ -854,17 +852,12 @@ int _luhn(const char* cc) { return 10 - (sum % 10); } -void _display_usim_data(int user_id) { +void display_usim_data(const char *filename) { int rc; usim_data_t data = { }; - /* - * Read USIM application data - */ - memset(&data, 0, sizeof(usim_data_t)); - char *path = make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); - rc = usim_api_read(path, &data); - free(path); + + rc = usim_api_read(filename, &data); if (rc != RETURNok) { perror("ERROR\t: usim_api_read() failed"); @@ -1046,16 +1039,14 @@ void _display_usim_data(int user_id) { } -void _display_ue_data(int user_id) { +void display_ue_data(const char *filename) { user_nvdata_t data; int rc; - char* path = make_filename(output_dir, USER_NVRAM_FILENAME, user_id); /* * Read UE's non-volatile data */ memset(&data, 0, sizeof(user_nvdata_t)); - rc = memory_read(path, &data, sizeof(user_nvdata_t)); - free(path); + rc = memory_read(filename, &data, sizeof(user_nvdata_t)); if (rc != RETURNok) { perror("ERROR\t: memory_read() failed"); @@ -1075,18 +1066,16 @@ void _display_ue_data(int user_id) { /* * Displays UE's non-volatile EMM data */ -void _display_emm_data(int user_id) { +void display_emm_data(const char *filename) { int rc; emm_nvdata_t data; - char* path = make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); /* * Read EMM non-volatile data */ memset(&data, 0, sizeof(emm_nvdata_t)); - rc = memory_read(path, &data, sizeof(emm_nvdata_t)); - free(path); + rc = memory_read(filename, &data, sizeof(emm_nvdata_t)); if (rc != RETURNok) { perror("ERROR\t: memory_read() failed "); exit(EXIT_FAILURE); @@ -1166,8 +1155,53 @@ void _display_usage(void) { fprintf(stderr, "\t[-h]\tDisplay this usage\n"); } +void display_data_from_directory(const char *directory) { + int user_id = 0; + char *filename; -char * make_filename(const char *output_dir, const char *filename, int ueid) { + filename = get_ue_filename(directory, user_id); + while ( file_exist_and_is_readable(filename) ) { + + display_ue_data(filename); + free(filename); + + filename = get_emm_filename(directory, user_id); + display_emm_data(filename); + free(filename); + + filename = get_usim_filename(directory, user_id); + display_usim_data(filename); + free(filename); + + + user_id += 1; + filename = get_ue_filename(directory, user_id); + } + free(filename); +} + +bool file_exist_and_is_readable(const char *filename) { + FILE *file ; + file = fopen(filename, "r"); + if ( file == NULL ) + return false; + fclose(file); + return true; +} + +char *get_ue_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, USER_NVRAM_FILENAME, user_id); +} + +char *get_emm_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); +} + +char *get_usim_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); +} + +char *make_filename(const char *output_dir, const char *filename, int ueid) { size_t size; char *str_ueid, *str; diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index c2571860c0..0fba9aa960 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -119,11 +119,9 @@ extern int ehplmn_nb; extern plmn_conf_param_t* user_plmn_list; extern network_record_t* user_network_record_list; -char *make_filename(const char *output_dir, const char *filename, int ueid); int get_config_from_file(const char *filename, config_t *config); int parse_config_file(const char *filename); -void _display_usim_data(int user_id); void _display_usage(void); void gen_emm_data(int user_id) ; @@ -132,9 +130,17 @@ void fill_network_record_list(void); int _luhn(const char* cc); -void _display_ue_data(int user_id); +void display_data_from_directory(const char *directory); +void display_ue_data(const char *filename); +void display_emm_data(const char *filename); +void display_usim_data(const char *filename); + +bool file_exist_and_is_readable(const char *filename); +char *get_ue_filename(const char *output_dir, int user_id); +char *get_emm_filename(const char *output_dir, int user_id); +char *get_usim_filename(const char *output_dir, int user_id); +char *make_filename(const char *output_dir, const char *filename, int ueid); -void _display_emm_data(int user_id); int parse_ue_user_param(config_setting_t *ue_setting, int user_id); int parse_ue_sim_param(config_setting_t *ue_setting, int user_id); int parse_plmn_param(config_setting_t *plmn_setting, int index); From 8461a56aa10bb9e0e584b07f89e6043541a48055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 14:58:39 +0200 Subject: [PATCH 197/571] refactor(conf2uedata): add fs.[h|c] and display.[c|h] --- cmake_targets/nas_sim_tools/CMakeLists.txt | 4 +- openair3/NAS/TOOLS/conf2uedata.c | 370 +-------------------- openair3/NAS/TOOLS/conf2uedata.h | 36 -- openair3/NAS/TOOLS/display.c | 349 +++++++++++++++++++ openair3/NAS/TOOLS/display.h | 9 + openair3/NAS/TOOLS/fs.c | 52 +++ openair3/NAS/TOOLS/fs.h | 12 + 7 files changed, 431 insertions(+), 401 deletions(-) create mode 100644 openair3/NAS/TOOLS/display.c create mode 100644 openair3/NAS/TOOLS/display.h create mode 100644 openair3/NAS/TOOLS/fs.c create mode 100644 openair3/NAS/TOOLS/fs.h diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 123b274714..8158362912 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -10,13 +10,15 @@ add_definitions(-std=gnu99) ENABLE_LANGUAGE(C) set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat") + "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat -g") set(OPENAIR_DIR $ENV{OPENAIR_DIR}) set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3) set(conf2uedata_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index e6d9554b0c..cef55dbcb7 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -1,10 +1,15 @@ #include // perror, printf, fprintf, snprintf #include // exit, free #include // memset, strncpy +#include #include "conf2uedata.h" -#include "user_api.h" +#include "memory.h" +#include "userDef.h" +#include "usim_api.h" #include "utils.h" +#include "display.h" +#include "fs.h" const char *output_dir = NULL; @@ -852,299 +857,6 @@ int _luhn(const char* cc) { return 10 - (sum % 10); } -void display_usim_data(const char *filename) { - - int rc; - usim_data_t data = { }; - - rc = usim_api_read(filename, &data); - - if (rc != RETURNok) { - perror("ERROR\t: usim_api_read() failed"); - exit(EXIT_FAILURE); - } - - /* - * Display USIM application data - */ - printf("\nUSIM data:\n\n"); - int digits; - - printf("Administrative Data:\n"); - printf("\tUE_Operation_Mode\t= 0x%.2x\n", data.ad.UE_Operation_Mode); - printf("\tAdditional_Info\t\t= 0x%.4x\n", data.ad.Additional_Info); - printf("\tMNC_Length\t\t= %d\n\n", data.ad.MNC_Length); - - printf("IMSI:\n"); - printf("\tlength\t= %d\n", data.imsi.length); - printf("\tparity\t= %s\n", - data.imsi.u.num.parity == EVEN_PARITY ? "Even" : "Odd"); - digits = (data.imsi.length * 2) - 1 - - (data.imsi.u.num.parity == EVEN_PARITY ? 1 : 0); - printf("\tdigits\t= %d\n", digits); - printf("\tdigits\t= %u%u%u%u%u%x%u%u%u%u", - data.imsi.u.num.digit1, // MCC digit 1 - data.imsi.u.num.digit2, // MCC digit 2 - data.imsi.u.num.digit3, // MCC digit 3 - data.imsi.u.num.digit4, // MNC digit 1 - data.imsi.u.num.digit5, // MNC digit 2 - data.imsi.u.num.digit6, // MNC digit 3 - data.imsi.u.num.digit7, data.imsi.u.num.digit8, - data.imsi.u.num.digit9, data.imsi.u.num.digit10); - - if (digits >= 11) - printf("%x", data.imsi.u.num.digit11); - - if (digits >= 12) - printf("%x", data.imsi.u.num.digit12); - - if (digits >= 13) - printf("%x", data.imsi.u.num.digit13); - - if (digits >= 14) - printf("%x", data.imsi.u.num.digit14); - - if (digits >= 15) - printf("%x", data.imsi.u.num.digit15); - - printf("\n\n"); - - printf("Ciphering and Integrity Keys:\n"); - printf("\tKSI\t: 0x%.2x\n", data.keys.ksi); - char key[USIM_CK_SIZE + 1]; - key[USIM_CK_SIZE] = '\0'; - memcpy(key, data.keys.ck, USIM_CK_SIZE); - printf("\tCK\t: \"%s\"\n", key); - memcpy(key, data.keys.ik, USIM_IK_SIZE); - printf("\tIK\t: \"%s\"\n", key); - - printf("EPS NAS security context:\n"); - printf("\tKSIasme\t: 0x%.2x\n", data.securityctx.KSIasme.value[0]); - char kasme[USIM_K_ASME_SIZE + 1]; - kasme[USIM_K_ASME_SIZE] = '\0'; - memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE); - printf("\tKasme\t: \"%s\"\n", kasme); - printf("\tulNAScount\t: 0x%.8x\n", - *(uint32_t*) data.securityctx.ulNAScount.value); - printf("\tdlNAScount\t: 0x%.8x\n", - *(uint32_t*) data.securityctx.dlNAScount.value); - printf("\talgorithmID\t: 0x%.2x\n\n", - data.securityctx.algorithmID.value[0]); - - printf("MSISDN\t= %u%u%u %u%u%u%u %u%u%u%u\n\n", - data.msisdn.number.digit[0].msb, data.msisdn.number.digit[0].lsb, - data.msisdn.number.digit[1].msb, data.msisdn.number.digit[1].lsb, - data.msisdn.number.digit[2].msb, data.msisdn.number.digit[2].lsb, - data.msisdn.number.digit[3].msb, data.msisdn.number.digit[3].lsb, - data.msisdn.number.digit[4].msb, data.msisdn.number.digit[4].lsb, - data.msisdn.number.digit[5].msb); - - for (int i = 0; i < USIM_PNN_MAX; i++) { - printf("PNN[%d]\t= {%s, %s}\n", i, data.pnn[i].fullname.value, - data.pnn[i].shortname.value); - } - - printf("\n"); - - for (int i = 0; i < USIM_OPL_MAX; i++) { - printf("OPL[%d]\t= ", i); - PRINT_PLMN(data.opl[i].plmn); - printf(", TAC = [%.4x - %.4x], record_id = %d\n", data.opl[i].start, - data.opl[i].end, data.opl[i].record_id); - } - - printf("\n"); - - printf("HPLMN\t\t= "); - PRINT_PLMN(data.hplmn.plmn); - printf(", AcT = 0x%x\n\n", data.hplmn.AcT); - - for (int i = 0; i < USIM_FPLMN_MAX; i++) { - printf("FPLMN[%d]\t= ", i); - PRINT_PLMN(data.fplmn[i]); - printf("\n"); - } - - printf("\n"); - - for (int i = 0; i < USIM_EHPLMN_MAX; i++) { - printf("EHPLMN[%d]\t= ", i); - PRINT_PLMN(data.ehplmn[i]); - printf("\n"); - } - - printf("\n"); - - for (int i = 0; i < USIM_PLMN_MAX; i++) { - printf("PLMN[%d]\t\t= ", i); - PRINT_PLMN(data.plmn[i].plmn); - printf(", AcTPLMN = 0x%x", data.plmn[i].AcT); - printf("\n"); - } - - printf("\n"); - - for (int i = 0; i < USIM_OPLMN_MAX; i++) { - printf("OPLMN[%d]\t= ", i); - PRINT_PLMN(data.oplmn[i].plmn); - printf(", AcTPLMN = 0x%x", data.oplmn[i].AcT); - printf("\n"); - } - - printf("\n"); - - printf("HPPLMN\t\t= 0x%.2x (%d minutes)\n\n", data.hpplmn, data.hpplmn); - - printf("LOCI:\n"); - printf("\tTMSI = 0x%.4x\n", data.loci.tmsi); - printf("\tLAI\t: PLMN = "); - PRINT_PLMN(data.loci.lai.plmn); - printf(", LAC = 0x%.2x\n", data.loci.lai.lac); - printf("\tstatus\t= %d\n\n", data.loci.status); - - printf("PSLOCI:\n"); - printf("\tP-TMSI = 0x%.4x\n", data.psloci.p_tmsi); - printf("\tsignature = 0x%x 0x%x 0x%x\n", data.psloci.signature[0], - data.psloci.signature[1], data.psloci.signature[2]); - printf("\tRAI\t: PLMN = "); - PRINT_PLMN(data.psloci.rai.plmn); - printf(", LAC = 0x%.2x, RAC = 0x%.1x\n", data.psloci.rai.lac, - data.psloci.rai.rac); - printf("\tstatus\t= %d\n\n", data.psloci.status); - - printf("EPSLOCI:\n"); - printf("\tGUTI\t: GUMMEI\t: (PLMN = "); - PRINT_PLMN(data.epsloci.guti.gummei.plmn); - printf(", MMEgid = 0x%.2x, MMEcode = 0x%.1x)", - data.epsloci.guti.gummei.MMEgid, data.epsloci.guti.gummei.MMEcode); - printf(", M-TMSI = 0x%.4x\n", data.epsloci.guti.m_tmsi); - printf("\tTAI\t: PLMN = "); - PRINT_PLMN(data.epsloci.tai.plmn); - printf(", TAC = 0x%.2x\n", data.epsloci.tai.tac); - printf("\tstatus\t= %d\n\n", data.epsloci.status); - - printf("NASCONFIG:\n"); - printf("\tNAS_SignallingPriority\t\t: 0x%.2x\n", - data.nasconfig.NAS_SignallingPriority.value[0]); - printf("\tNMO_I_Behaviour\t\t\t: 0x%.2x\n", - data.nasconfig.NMO_I_Behaviour.value[0]); - printf("\tAttachWithImsi\t\t\t: 0x%.2x\n", - data.nasconfig.AttachWithImsi.value[0]); - printf("\tMinimumPeriodicSearchTimer\t: 0x%.2x\n", - data.nasconfig.MinimumPeriodicSearchTimer.value[0]); - printf("\tExtendedAccessBarring\t\t: 0x%.2x\n", - data.nasconfig.ExtendedAccessBarring.value[0]); - printf("\tTimer_T3245_Behaviour\t\t: 0x%.2x\n", - data.nasconfig.Timer_T3245_Behaviour.value[0]); - -} - -void display_ue_data(const char *filename) { - user_nvdata_t data; - int rc; - /* - * Read UE's non-volatile data - */ - memset(&data, 0, sizeof(user_nvdata_t)); - rc = memory_read(filename, &data, sizeof(user_nvdata_t)); - - if (rc != RETURNok) { - perror("ERROR\t: memory_read() failed"); - exit(EXIT_FAILURE); - } - - /* - * Display UE's non-volatile data - */ - printf("\nUE's non-volatile data:\n\n"); - printf("IMEI\t\t= %s\n", data.IMEI); - printf("manufacturer\t= %s\n", data.manufacturer); - printf("model\t\t= %s\n", data.model); - printf("PIN\t\t= %s\n", data.PIN); -} - -/* - * Displays UE's non-volatile EMM data - */ -void display_emm_data(const char *filename) { - - int rc; - emm_nvdata_t data; - - /* - * Read EMM non-volatile data - */ - memset(&data, 0, sizeof(emm_nvdata_t)); - rc = memory_read(filename, &data, sizeof(emm_nvdata_t)); - if (rc != RETURNok) { - perror("ERROR\t: memory_read() failed "); - exit(EXIT_FAILURE); - } - - /* - * Display EMM non-volatile data - */ - printf("\nEMM non-volatile data:\n\n"); - - printf("IMSI\t\t= "); - - if (data.imsi.u.num.digit6 == 0b1111) { - if (data.imsi.u.num.digit15 == 0b1111) { - printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, - data.imsi.u.num.digit2, data.imsi.u.num.digit3, - data.imsi.u.num.digit4, data.imsi.u.num.digit5, - - data.imsi.u.num.digit7, data.imsi.u.num.digit8, - data.imsi.u.num.digit9, data.imsi.u.num.digit10, - data.imsi.u.num.digit11, data.imsi.u.num.digit12, - data.imsi.u.num.digit13, data.imsi.u.num.digit14); - } else { - printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, - data.imsi.u.num.digit2, data.imsi.u.num.digit3, - data.imsi.u.num.digit4, data.imsi.u.num.digit5, - - data.imsi.u.num.digit7, data.imsi.u.num.digit8, - data.imsi.u.num.digit9, data.imsi.u.num.digit10, - data.imsi.u.num.digit11, data.imsi.u.num.digit12, - data.imsi.u.num.digit13, data.imsi.u.num.digit14, - data.imsi.u.num.digit15); - } - } else { - if (data.imsi.u.num.digit15 == 0b1111) { - printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, - data.imsi.u.num.digit2, data.imsi.u.num.digit3, - data.imsi.u.num.digit4, data.imsi.u.num.digit5, - data.imsi.u.num.digit6, - - data.imsi.u.num.digit7, data.imsi.u.num.digit8, - data.imsi.u.num.digit9, data.imsi.u.num.digit10, - data.imsi.u.num.digit11, data.imsi.u.num.digit12, - data.imsi.u.num.digit13, data.imsi.u.num.digit14); - } else { - printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, - data.imsi.u.num.digit2, data.imsi.u.num.digit3, - data.imsi.u.num.digit4, data.imsi.u.num.digit5, - data.imsi.u.num.digit6, - - data.imsi.u.num.digit7, data.imsi.u.num.digit8, - data.imsi.u.num.digit9, data.imsi.u.num.digit10, - data.imsi.u.num.digit11, data.imsi.u.num.digit12, - data.imsi.u.num.digit13, data.imsi.u.num.digit14, - data.imsi.u.num.digit15); - } - } - - printf("RPLMN\t\t= "); - PRINT_PLMN(data.rplmn); - printf("\n"); - - for (int i = 0; i < data.eplmn.n_plmns; i++) { - printf("EPLMN[%d]\t= ", i); - PRINT_PLMN(data.eplmn.plmn[i]); - printf("\n"); - } -} - /* * Displays command line usage */ @@ -1154,73 +866,3 @@ void _display_usage(void) { fprintf(stderr, "\t[-o]\toutput file directory\n"); fprintf(stderr, "\t[-h]\tDisplay this usage\n"); } - -void display_data_from_directory(const char *directory) { - int user_id = 0; - char *filename; - - filename = get_ue_filename(directory, user_id); - while ( file_exist_and_is_readable(filename) ) { - - display_ue_data(filename); - free(filename); - - filename = get_emm_filename(directory, user_id); - display_emm_data(filename); - free(filename); - - filename = get_usim_filename(directory, user_id); - display_usim_data(filename); - free(filename); - - - user_id += 1; - filename = get_ue_filename(directory, user_id); - } - free(filename); -} - -bool file_exist_and_is_readable(const char *filename) { - FILE *file ; - file = fopen(filename, "r"); - if ( file == NULL ) - return false; - fclose(file); - return true; -} - -char *get_ue_filename(const char *output_dir, int user_id) { - return make_filename(output_dir, USER_NVRAM_FILENAME, user_id); -} - -char *get_emm_filename(const char *output_dir, int user_id) { - return make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); -} - -char *get_usim_filename(const char *output_dir, int user_id) { - return make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); -} - -char *make_filename(const char *output_dir, const char *filename, int ueid) { - size_t size; - char *str_ueid, *str; - - str_ueid = itoa(ueid); - - if (str_ueid == NULL) { - perror("ERROR\t: itoa() failed"); - exit(EXIT_FAILURE); - } - - size = strlen(output_dir)+strlen(filename) + sizeof(ueid) + 1 + 1; // for \0 and for '/' - str = malloc(size); - if (str == NULL) { - perror("ERROR\t: make_filename() failed"); - exit(EXIT_FAILURE); - } - - snprintf(str, size, "%s/%s%s",output_dir, filename, str_ueid); - free(str_ueid); - - return str; -} diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 0fba9aa960..98c4752743 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -3,10 +3,6 @@ #include #include "emmData.h" -#include "usim_api.h" -#include "userDef.h" -#include "memory.h" -#include "getopt.h" #define USER "USER" #define UE "UE" @@ -36,16 +32,6 @@ #define EHPLMN "EHPLMN_LIST" #define KSI USIM_KSI_NOT_AVAILABLE -#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) - -#define PRINT_PLMN(plmn) \ - PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit3) - #define KSI_ASME USIM_KSI_NOT_AVAILABLE #define INT_ALGO USIM_INT_EIA1 @@ -65,16 +51,6 @@ #define DEFAULT_MME_ID 0x0102 #define DEFAULT_MME_CODE 0x0F -#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) - -#define PRINT_PLMN(plmn) \ - PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ - PRINT_PLMN_DIGIT((plmn).MNCdigit3) - /* * PLMN network operator record */ @@ -122,7 +98,6 @@ extern network_record_t* user_network_record_list; int get_config_from_file(const char *filename, config_t *config); int parse_config_file(const char *filename); - void _display_usage(void); void gen_emm_data(int user_id) ; void gen_usim_data(int user_id); @@ -130,17 +105,6 @@ void fill_network_record_list(void); int _luhn(const char* cc); -void display_data_from_directory(const char *directory); -void display_ue_data(const char *filename); -void display_emm_data(const char *filename); -void display_usim_data(const char *filename); - -bool file_exist_and_is_readable(const char *filename); -char *get_ue_filename(const char *output_dir, int user_id); -char *get_emm_filename(const char *output_dir, int user_id); -char *get_usim_filename(const char *output_dir, int user_id); -char *make_filename(const char *output_dir, const char *filename, int ueid); - int parse_ue_user_param(config_setting_t *ue_setting, int user_id); int parse_ue_sim_param(config_setting_t *ue_setting, int user_id); int parse_plmn_param(config_setting_t *plmn_setting, int index); diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c new file mode 100644 index 0000000000..b130ef2c07 --- /dev/null +++ b/openair3/NAS/TOOLS/display.c @@ -0,0 +1,349 @@ +#include +#include + +#include "userDef.h" +#include "usim_api.h" +#include "emmData.h" +#include "display.h" +#include "memory.h" +#include "fs.h" + +#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) + +#define PRINT_PLMN(plmn) \ + PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit3) + +#define PRINT_PLMN_DIGIT(d) if ((d) != 0xf) printf("%u", (d)) + +#define PRINT_PLMN(plmn) \ + PRINT_PLMN_DIGIT((plmn).MCCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MCCdigit3); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit1); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ + PRINT_PLMN_DIGIT((plmn).MNCdigit3) + +void display_data_from_directory(const char *directory) { + int user_id = 0; + char *filename; + + filename = get_ue_filename(directory, user_id); + while ( file_exist_and_is_readable(filename) ) { + + display_ue_data(filename); + free(filename); + + filename = get_emm_filename(directory, user_id); + display_emm_data(filename); + free(filename); + + filename = get_usim_filename(directory, user_id); + display_usim_data(filename); + free(filename); + + + user_id += 1; + filename = get_ue_filename(directory, user_id); + } + free(filename); +} + +void display_ue_data(const char *filename) { + user_nvdata_t data; + int rc; + /* + * Read UE's non-volatile data + */ + memset(&data, 0, sizeof(user_nvdata_t)); + rc = memory_read(filename, &data, sizeof(user_nvdata_t)); + + if (rc != RETURNok) { + perror("ERROR\t: memory_read() failed"); + exit(EXIT_FAILURE); + } + + /* + * Display UE's non-volatile data + */ + printf("\nUE's non-volatile data:\n\n"); + printf("IMEI\t\t= %s\n", data.IMEI); + printf("manufacturer\t= %s\n", data.manufacturer); + printf("model\t\t= %s\n", data.model); + printf("PIN\t\t= %s\n", data.PIN); +} + +/* + * Displays UE's non-volatile EMM data + */ +void display_emm_data(const char *filename) { + + int rc; + emm_nvdata_t data; + + /* + * Read EMM non-volatile data + */ + memset(&data, 0, sizeof(emm_nvdata_t)); + rc = memory_read(filename, &data, sizeof(emm_nvdata_t)); + if (rc != RETURNok) { + perror("ERROR\t: memory_read() failed "); + exit(EXIT_FAILURE); + } + + /* + * Display EMM non-volatile data + */ + printf("\nEMM non-volatile data:\n\n"); + + printf("IMSI\t\t= "); + + if (data.imsi.u.num.digit6 == 0b1111) { + if (data.imsi.u.num.digit15 == 0b1111) { + printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14); + } else { + printf("%u%u%u.%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14, + data.imsi.u.num.digit15); + } + } else { + if (data.imsi.u.num.digit15 == 0b1111) { + printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + data.imsi.u.num.digit6, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14); + } else { + printf("%u%u%u.%u%u%u.%u%u%u%u%u%u%u%u%u\n", data.imsi.u.num.digit1, + data.imsi.u.num.digit2, data.imsi.u.num.digit3, + data.imsi.u.num.digit4, data.imsi.u.num.digit5, + data.imsi.u.num.digit6, + + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10, + data.imsi.u.num.digit11, data.imsi.u.num.digit12, + data.imsi.u.num.digit13, data.imsi.u.num.digit14, + data.imsi.u.num.digit15); + } + } + + printf("RPLMN\t\t= "); + PRINT_PLMN(data.rplmn); + printf("\n"); + + for (int i = 0; i < data.eplmn.n_plmns; i++) { + printf("EPLMN[%d]\t= ", i); + PRINT_PLMN(data.eplmn.plmn[i]); + printf("\n"); + } +} + +void display_usim_data(const char *filename) { + + int rc; + usim_data_t data = { }; + + rc = usim_api_read(filename, &data); + + if (rc != RETURNok) { + perror("ERROR\t: usim_api_read() failed"); + exit(EXIT_FAILURE); + } + + /* + * Display USIM application data + */ + printf("\nUSIM data:\n\n"); + int digits; + + printf("Administrative Data:\n"); + printf("\tUE_Operation_Mode\t= 0x%.2x\n", data.ad.UE_Operation_Mode); + printf("\tAdditional_Info\t\t= 0x%.4x\n", data.ad.Additional_Info); + printf("\tMNC_Length\t\t= %d\n\n", data.ad.MNC_Length); + + printf("IMSI:\n"); + printf("\tlength\t= %d\n", data.imsi.length); + printf("\tparity\t= %s\n", + data.imsi.u.num.parity == EVEN_PARITY ? "Even" : "Odd"); + digits = (data.imsi.length * 2) - 1 + - (data.imsi.u.num.parity == EVEN_PARITY ? 1 : 0); + printf("\tdigits\t= %d\n", digits); + printf("\tdigits\t= %u%u%u%u%u%x%u%u%u%u", + data.imsi.u.num.digit1, // MCC digit 1 + data.imsi.u.num.digit2, // MCC digit 2 + data.imsi.u.num.digit3, // MCC digit 3 + data.imsi.u.num.digit4, // MNC digit 1 + data.imsi.u.num.digit5, // MNC digit 2 + data.imsi.u.num.digit6, // MNC digit 3 + data.imsi.u.num.digit7, data.imsi.u.num.digit8, + data.imsi.u.num.digit9, data.imsi.u.num.digit10); + + if (digits >= 11) + printf("%x", data.imsi.u.num.digit11); + + if (digits >= 12) + printf("%x", data.imsi.u.num.digit12); + + if (digits >= 13) + printf("%x", data.imsi.u.num.digit13); + + if (digits >= 14) + printf("%x", data.imsi.u.num.digit14); + + if (digits >= 15) + printf("%x", data.imsi.u.num.digit15); + + printf("\n\n"); + + printf("Ciphering and Integrity Keys:\n"); + printf("\tKSI\t: 0x%.2x\n", data.keys.ksi); + char key[USIM_CK_SIZE + 1]; + key[USIM_CK_SIZE] = '\0'; + memcpy(key, data.keys.ck, USIM_CK_SIZE); + printf("\tCK\t: \"%s\"\n", key); + memcpy(key, data.keys.ik, USIM_IK_SIZE); + printf("\tIK\t: \"%s\"\n", key); + + printf("EPS NAS security context:\n"); + printf("\tKSIasme\t: 0x%.2x\n", data.securityctx.KSIasme.value[0]); + char kasme[USIM_K_ASME_SIZE + 1]; + kasme[USIM_K_ASME_SIZE] = '\0'; + memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE); + printf("\tKasme\t: \"%s\"\n", kasme); + printf("\tulNAScount\t: 0x%.8x\n", + *(uint32_t*) data.securityctx.ulNAScount.value); + printf("\tdlNAScount\t: 0x%.8x\n", + *(uint32_t*) data.securityctx.dlNAScount.value); + printf("\talgorithmID\t: 0x%.2x\n\n", + data.securityctx.algorithmID.value[0]); + + printf("MSISDN\t= %u%u%u %u%u%u%u %u%u%u%u\n\n", + data.msisdn.number.digit[0].msb, data.msisdn.number.digit[0].lsb, + data.msisdn.number.digit[1].msb, data.msisdn.number.digit[1].lsb, + data.msisdn.number.digit[2].msb, data.msisdn.number.digit[2].lsb, + data.msisdn.number.digit[3].msb, data.msisdn.number.digit[3].lsb, + data.msisdn.number.digit[4].msb, data.msisdn.number.digit[4].lsb, + data.msisdn.number.digit[5].msb); + + for (int i = 0; i < USIM_PNN_MAX; i++) { + printf("PNN[%d]\t= {%s, %s}\n", i, data.pnn[i].fullname.value, + data.pnn[i].shortname.value); + } + + printf("\n"); + + for (int i = 0; i < USIM_OPL_MAX; i++) { + printf("OPL[%d]\t= ", i); + PRINT_PLMN(data.opl[i].plmn); + printf(", TAC = [%.4x - %.4x], record_id = %d\n", data.opl[i].start, + data.opl[i].end, data.opl[i].record_id); + } + + printf("\n"); + + printf("HPLMN\t\t= "); + PRINT_PLMN(data.hplmn.plmn); + printf(", AcT = 0x%x\n\n", data.hplmn.AcT); + + for (int i = 0; i < USIM_FPLMN_MAX; i++) { + printf("FPLMN[%d]\t= ", i); + PRINT_PLMN(data.fplmn[i]); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_EHPLMN_MAX; i++) { + printf("EHPLMN[%d]\t= ", i); + PRINT_PLMN(data.ehplmn[i]); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_PLMN_MAX; i++) { + printf("PLMN[%d]\t\t= ", i); + PRINT_PLMN(data.plmn[i].plmn); + printf(", AcTPLMN = 0x%x", data.plmn[i].AcT); + printf("\n"); + } + + printf("\n"); + + for (int i = 0; i < USIM_OPLMN_MAX; i++) { + printf("OPLMN[%d]\t= ", i); + PRINT_PLMN(data.oplmn[i].plmn); + printf(", AcTPLMN = 0x%x", data.oplmn[i].AcT); + printf("\n"); + } + + printf("\n"); + + printf("HPPLMN\t\t= 0x%.2x (%d minutes)\n\n", data.hpplmn, data.hpplmn); + + printf("LOCI:\n"); + printf("\tTMSI = 0x%.4x\n", data.loci.tmsi); + printf("\tLAI\t: PLMN = "); + PRINT_PLMN(data.loci.lai.plmn); + printf(", LAC = 0x%.2x\n", data.loci.lai.lac); + printf("\tstatus\t= %d\n\n", data.loci.status); + + printf("PSLOCI:\n"); + printf("\tP-TMSI = 0x%.4x\n", data.psloci.p_tmsi); + printf("\tsignature = 0x%x 0x%x 0x%x\n", data.psloci.signature[0], + data.psloci.signature[1], data.psloci.signature[2]); + printf("\tRAI\t: PLMN = "); + PRINT_PLMN(data.psloci.rai.plmn); + printf(", LAC = 0x%.2x, RAC = 0x%.1x\n", data.psloci.rai.lac, + data.psloci.rai.rac); + printf("\tstatus\t= %d\n\n", data.psloci.status); + + printf("EPSLOCI:\n"); + printf("\tGUTI\t: GUMMEI\t: (PLMN = "); + PRINT_PLMN(data.epsloci.guti.gummei.plmn); + printf(", MMEgid = 0x%.2x, MMEcode = 0x%.1x)", + data.epsloci.guti.gummei.MMEgid, data.epsloci.guti.gummei.MMEcode); + printf(", M-TMSI = 0x%.4x\n", data.epsloci.guti.m_tmsi); + printf("\tTAI\t: PLMN = "); + PRINT_PLMN(data.epsloci.tai.plmn); + printf(", TAC = 0x%.2x\n", data.epsloci.tai.tac); + printf("\tstatus\t= %d\n\n", data.epsloci.status); + + printf("NASCONFIG:\n"); + printf("\tNAS_SignallingPriority\t\t: 0x%.2x\n", + data.nasconfig.NAS_SignallingPriority.value[0]); + printf("\tNMO_I_Behaviour\t\t\t: 0x%.2x\n", + data.nasconfig.NMO_I_Behaviour.value[0]); + printf("\tAttachWithImsi\t\t\t: 0x%.2x\n", + data.nasconfig.AttachWithImsi.value[0]); + printf("\tMinimumPeriodicSearchTimer\t: 0x%.2x\n", + data.nasconfig.MinimumPeriodicSearchTimer.value[0]); + printf("\tExtendedAccessBarring\t\t: 0x%.2x\n", + data.nasconfig.ExtendedAccessBarring.value[0]); + printf("\tTimer_T3245_Behaviour\t\t: 0x%.2x\n", + data.nasconfig.Timer_T3245_Behaviour.value[0]); + +} + + diff --git a/openair3/NAS/TOOLS/display.h b/openair3/NAS/TOOLS/display.h new file mode 100644 index 0000000000..fd4f4ff1e3 --- /dev/null +++ b/openair3/NAS/TOOLS/display.h @@ -0,0 +1,9 @@ +#ifndef _DISPLAY_H +#define _DISPLAY_H + +void display_data_from_directory(const char *directory); +void display_ue_data(const char *filename); +void display_emm_data(const char *filename); +void display_usim_data(const char *filename); + +#endif diff --git a/openair3/NAS/TOOLS/fs.c b/openair3/NAS/TOOLS/fs.c new file mode 100644 index 0000000000..c25f10a1e7 --- /dev/null +++ b/openair3/NAS/TOOLS/fs.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "fs.h" +#include "user_api.h" +#include "utils.h" + +bool file_exist_and_is_readable(const char *filename) { + FILE *file ; + file = fopen(filename, "r"); + if ( file == NULL ) + return false; + fclose(file); + return true; +} + +char *get_ue_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, USER_NVRAM_FILENAME, user_id); +} + +char *get_emm_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); +} + +char *get_usim_filename(const char *output_dir, int user_id) { + return make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); +} + +char *make_filename(const char *output_dir, const char *filename, int ueid) { + size_t size; + char *str_ueid, *str; + + str_ueid = itoa(ueid); + + if (str_ueid == NULL) { + perror("ERROR\t: itoa() failed"); + exit(EXIT_FAILURE); + } + + size = strlen(output_dir)+strlen(filename) + sizeof(ueid) + 1 + 1; // for \0 and for '/' + str = malloc(size); + if (str == NULL) { + perror("ERROR\t: make_filename() failed"); + exit(EXIT_FAILURE); + } + + snprintf(str, size, "%s/%s%s",output_dir, filename, str_ueid); + free(str_ueid); + + return str; +} diff --git a/openair3/NAS/TOOLS/fs.h b/openair3/NAS/TOOLS/fs.h new file mode 100644 index 0000000000..ecfca55955 --- /dev/null +++ b/openair3/NAS/TOOLS/fs.h @@ -0,0 +1,12 @@ +#ifndef _FS_H +#define _FS_H + +#include + +bool file_exist_and_is_readable(const char *filename); +char *get_ue_filename(const char *output_dir, int user_id); +char *get_emm_filename(const char *output_dir, int user_id); +char *get_usim_filename(const char *output_dir, int user_id); +char *make_filename(const char *output_dir, const char *filename, int ueid); + +#endif From ef2dee59d41ca1af93c2d7ba8578261fd5bbbb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 15:41:47 +0200 Subject: [PATCH 198/571] refactor(conf2uedata): separate processing and writing of data --- openair3/NAS/TOOLS/conf2uedata.c | 421 ++++++++++++++++--------------- openair3/NAS/TOOLS/conf2uedata.h | 18 +- 2 files changed, 231 insertions(+), 208 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index cef55dbcb7..486b7e2bff 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -11,8 +11,6 @@ #include "display.h" #include "fs.h" -const char *output_dir = NULL; - const char *msin = NULL; const char *usim_api_k = NULL; const char *msisdn = NULL; @@ -39,6 +37,7 @@ network_record_t* user_network_record_list = NULL; int main(int argc, char**argv) { int option; const char* conf_file = NULL; + const char* output_dir = NULL; const char options[]="c:o:h"; while ((option = getopt(argc, argv, options)) != -1) { @@ -70,7 +69,7 @@ int main(int argc, char**argv) { return EXIT_FAILURE; } - if ( parse_config_file(conf_file) == EXIT_FAILURE ) { + if ( parse_config_file(output_dir, conf_file) == EXIT_FAILURE ) { exit(EXIT_FAILURE); } @@ -79,7 +78,7 @@ int main(int argc, char**argv) { exit(EXIT_SUCCESS); } -int parse_config_file(const char *filename) { +int parse_config_file(const char *output_dir, const char *conf_filename) { int rc = EXIT_SUCCESS; int ret; int ue_nb = 0; @@ -89,7 +88,7 @@ int parse_config_file(const char *filename) { char user[10]; config_t cfg; - ret = get_config_from_file(filename, &cfg); + ret = get_config_from_file(conf_filename, &cfg); if (ret == EXIT_FAILURE) { exit(1); } @@ -110,6 +109,10 @@ int parse_config_file(const char *filename) { fill_network_record_list(); for (int i = 0; i < ue_nb; i++) { + emm_nvdata_t emm_data; + user_nvdata_t user_data; + usim_data_t usim_data; + sprintf(user, "%s%d", UE, i); ue_setting = config_setting_get_member(root_setting, user); @@ -118,11 +121,12 @@ int parse_config_file(const char *filename) { return EXIT_FAILURE; } - rc = parse_ue_user_param(ue_setting, i); + rc = parse_ue_user_param(ue_setting, i, &user_data); if (rc != EXIT_SUCCESS) { printf("Problem in USER section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } + write_user_data(output_dir, i, &user_data); rc = parse_ue_sim_param(ue_setting, i); if (rc != EXIT_SUCCESS) { @@ -134,9 +138,12 @@ int parse_config_file(const char *filename) { if (rc != EXIT_SUCCESS) { return EXIT_FAILURE; } - gen_emm_data(i); - gen_usim_data(i); - } + gen_emm_data(i, &emm_data); + write_emm_data(output_dir, i, &emm_data); + + gen_usim_data(&usim_data); + write_usim_data(output_dir, i, &usim_data); + } config_destroy(&cfg); return(EXIT_SUCCESS); } @@ -161,142 +168,141 @@ int get_config_from_file(const char *filename, config_t *config) { return EXIT_SUCCESS; } -void gen_usim_data(int user_id) { - usim_data_t usim_data = { }; - memset(&usim_data, 0, sizeof(usim_data_t)); - usim_data.imsi.length = 8; - usim_data.imsi.u.num.parity = get_msin_parity(msin); +void gen_usim_data(usim_data_t *usim_data) { + memset(usim_data, 0, sizeof(usim_data_t)); + usim_data->imsi.length = 8; + usim_data->imsi.u.num.parity = get_msin_parity(msin); - usim_data.imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; - usim_data.imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; - usim_data.imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + usim_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; + usim_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; + usim_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; - usim_data.imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; - usim_data.imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; + usim_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; + usim_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; if (strlen(user_plmn_list[hplmn_index].mnc) == 2) { - usim_data.imsi.u.num.digit6 = msin[0]; - usim_data.imsi.u.num.digit7 = msin[1]; - usim_data.imsi.u.num.digit8 = msin[2]; - usim_data.imsi.u.num.digit9 = msin[3]; - usim_data.imsi.u.num.digit10 = msin[4]; - usim_data.imsi.u.num.digit11 = msin[5]; - usim_data.imsi.u.num.digit12 = msin[6]; - usim_data.imsi.u.num.digit13 = msin[7]; - usim_data.imsi.u.num.digit14 = msin[8]; - usim_data.imsi.u.num.digit15 = msin[9]; + usim_data->imsi.u.num.digit6 = msin[0]; + usim_data->imsi.u.num.digit7 = msin[1]; + usim_data->imsi.u.num.digit8 = msin[2]; + usim_data->imsi.u.num.digit9 = msin[3]; + usim_data->imsi.u.num.digit10 = msin[4]; + usim_data->imsi.u.num.digit11 = msin[5]; + usim_data->imsi.u.num.digit12 = msin[6]; + usim_data->imsi.u.num.digit13 = msin[7]; + usim_data->imsi.u.num.digit14 = msin[8]; + usim_data->imsi.u.num.digit15 = msin[9]; } else { - usim_data.imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; - usim_data.imsi.u.num.digit7 = msin[0]; - usim_data.imsi.u.num.digit8 = msin[1]; - usim_data.imsi.u.num.digit9 = msin[2]; - usim_data.imsi.u.num.digit10 = msin[3]; - usim_data.imsi.u.num.digit11 = msin[4]; - usim_data.imsi.u.num.digit12 = msin[5]; - usim_data.imsi.u.num.digit13 = msin[6]; - usim_data.imsi.u.num.digit14 = msin[7]; - usim_data.imsi.u.num.digit15 = msin[8]; + usim_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + usim_data->imsi.u.num.digit7 = msin[0]; + usim_data->imsi.u.num.digit8 = msin[1]; + usim_data->imsi.u.num.digit9 = msin[2]; + usim_data->imsi.u.num.digit10 = msin[3]; + usim_data->imsi.u.num.digit11 = msin[4]; + usim_data->imsi.u.num.digit12 = msin[5]; + usim_data->imsi.u.num.digit13 = msin[6]; + usim_data->imsi.u.num.digit14 = msin[7]; + usim_data->imsi.u.num.digit15 = msin[8]; } /* * Ciphering and Integrity Keys */ - usim_data.keys.ksi = KSI; - memset(&usim_data.keys.ck, 0, USIM_CK_SIZE); - memset(&usim_data.keys.ik, 0, USIM_IK_SIZE); + usim_data->keys.ksi = KSI; + memset(&usim_data->keys.ck, 0, USIM_CK_SIZE); + memset(&usim_data->keys.ik, 0, USIM_IK_SIZE); /* * Higher Priority PLMN search period */ - usim_data.hpplmn = 0x00; /* Disable timer */ + usim_data->hpplmn = 0x00; /* Disable timer */ /* * List of Forbidden PLMNs */ for (int i = 0; i < USIM_FPLMN_MAX; i++) { - memset(&usim_data.fplmn[i], 0xff, sizeof(plmn_t)); + memset(&usim_data->fplmn[i], 0xff, sizeof(plmn_t)); } if (fplmn_nb > 0) { for (int i = 0; i < fplmn_nb; i++) { - usim_data.fplmn[i] = user_network_record_list[fplmn[i]].plmn; + usim_data->fplmn[i] = user_network_record_list[fplmn[i]].plmn; } } /* * Location Information */ - usim_data.loci.tmsi = DEFAULT_TMSI; - usim_data.loci.lai.plmn = user_network_record_list[hplmn_index].plmn; - usim_data.loci.lai.lac = DEFAULT_LAC; - usim_data.loci.status = USIM_LOCI_NOT_UPDATED; + usim_data->loci.tmsi = DEFAULT_TMSI; + usim_data->loci.lai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->loci.lai.lac = DEFAULT_LAC; + usim_data->loci.status = USIM_LOCI_NOT_UPDATED; /* * Packet Switched Location Information */ - usim_data.psloci.p_tmsi = DEFAULT_P_TMSI; - usim_data.psloci.signature[0] = 0x01; - usim_data.psloci.signature[1] = 0x02; - usim_data.psloci.signature[2] = 0x03; - usim_data.psloci.rai.plmn = user_network_record_list[hplmn_index].plmn; - usim_data.psloci.rai.lac = DEFAULT_LAC; - usim_data.psloci.rai.rac = DEFAULT_RAC; - usim_data.psloci.status = USIM_PSLOCI_NOT_UPDATED; + usim_data->psloci.p_tmsi = DEFAULT_P_TMSI; + usim_data->psloci.signature[0] = 0x01; + usim_data->psloci.signature[1] = 0x02; + usim_data->psloci.signature[2] = 0x03; + usim_data->psloci.rai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->psloci.rai.lac = DEFAULT_LAC; + usim_data->psloci.rai.rac = DEFAULT_RAC; + usim_data->psloci.status = USIM_PSLOCI_NOT_UPDATED; /* * Administrative Data */ - usim_data.ad.UE_Operation_Mode = USIM_NORMAL_MODE; - usim_data.ad.Additional_Info = 0xffff; - usim_data.ad.MNC_Length = strlen(user_plmn_list[hplmn_index].mnc); + usim_data->ad.UE_Operation_Mode = USIM_NORMAL_MODE; + usim_data->ad.Additional_Info = 0xffff; + usim_data->ad.MNC_Length = strlen(user_plmn_list[hplmn_index].mnc); /* * EPS NAS security context */ - usim_data.securityctx.length = 52; - usim_data.securityctx.KSIasme.type = USIM_KSI_ASME_TAG; - usim_data.securityctx.KSIasme.length = 1; - usim_data.securityctx.KSIasme.value[0] = KSI_ASME; - usim_data.securityctx.Kasme.type = USIM_K_ASME_TAG; - usim_data.securityctx.Kasme.length = USIM_K_ASME_SIZE; - memset(usim_data.securityctx.Kasme.value, 0, - usim_data.securityctx.Kasme.length); - usim_data.securityctx.ulNAScount.type = USIM_UL_NAS_COUNT_TAG; - usim_data.securityctx.ulNAScount.length = USIM_UL_NAS_COUNT_SIZE; - memset(usim_data.securityctx.ulNAScount.value, 0, - usim_data.securityctx.ulNAScount.length); - usim_data.securityctx.dlNAScount.type = USIM_DL_NAS_COUNT_TAG; - usim_data.securityctx.dlNAScount.length = USIM_DL_NAS_COUNT_SIZE; - memset(usim_data.securityctx.dlNAScount.value, 0, - usim_data.securityctx.dlNAScount.length); - usim_data.securityctx.algorithmID.type = USIM_INT_ENC_ALGORITHMS_TAG; - usim_data.securityctx.algorithmID.length = 1; - usim_data.securityctx.algorithmID.value[0] = SECURITY_ALGORITHMS; + usim_data->securityctx.length = 52; + usim_data->securityctx.KSIasme.type = USIM_KSI_ASME_TAG; + usim_data->securityctx.KSIasme.length = 1; + usim_data->securityctx.KSIasme.value[0] = KSI_ASME; + usim_data->securityctx.Kasme.type = USIM_K_ASME_TAG; + usim_data->securityctx.Kasme.length = USIM_K_ASME_SIZE; + memset(usim_data->securityctx.Kasme.value, 0, + usim_data->securityctx.Kasme.length); + usim_data->securityctx.ulNAScount.type = USIM_UL_NAS_COUNT_TAG; + usim_data->securityctx.ulNAScount.length = USIM_UL_NAS_COUNT_SIZE; + memset(usim_data->securityctx.ulNAScount.value, 0, + usim_data->securityctx.ulNAScount.length); + usim_data->securityctx.dlNAScount.type = USIM_DL_NAS_COUNT_TAG; + usim_data->securityctx.dlNAScount.length = USIM_DL_NAS_COUNT_SIZE; + memset(usim_data->securityctx.dlNAScount.value, 0, + usim_data->securityctx.dlNAScount.length); + usim_data->securityctx.algorithmID.type = USIM_INT_ENC_ALGORITHMS_TAG; + usim_data->securityctx.algorithmID.length = 1; + usim_data->securityctx.algorithmID.value[0] = SECURITY_ALGORITHMS; /* * Subcriber's Number */ - usim_data.msisdn.length = 7; - usim_data.msisdn.number.ext = 1; - usim_data.msisdn.number.ton = MSISDN_TON_UNKNOWKN; - usim_data.msisdn.number.npi = MSISDN_NPI_ISDN_TELEPHONY; - usim_data.msisdn.conf1_record_id = 0xff; /* Not used */ - usim_data.msisdn.ext1_record_id = 0xff; /* Not used */ + usim_data->msisdn.length = 7; + usim_data->msisdn.number.ext = 1; + usim_data->msisdn.number.ton = MSISDN_TON_UNKNOWKN; + usim_data->msisdn.number.npi = MSISDN_NPI_ISDN_TELEPHONY; + usim_data->msisdn.conf1_record_id = 0xff; /* Not used */ + usim_data->msisdn.ext1_record_id = 0xff; /* Not used */ int j = 0; for (int i = 0; i < strlen(msisdn); i += 2) { - usim_data.msisdn.number.digit[j].msb = msisdn[i]; + usim_data->msisdn.number.digit[j].msb = msisdn[i]; j++; } j = 0; for (int i = 1; i < strlen(msisdn); i += 2) { - usim_data.msisdn.number.digit[j].lsb = msisdn[i]; + usim_data->msisdn.number.digit[j].lsb = msisdn[i]; j++; } if (strlen(msisdn) % 2 == 0) { for (int i = strlen(msisdn) / 2; i < 10; i++) { - usim_data.msisdn.number.digit[i].msb = 0xf; - usim_data.msisdn.number.digit[i].lsb = 0xf; + usim_data->msisdn.number.digit[i].msb = 0xf; + usim_data->msisdn.number.digit[i].lsb = 0xf; } } else { - usim_data.msisdn.number.digit[strlen(msisdn) / 2].lsb = 0xf; + usim_data->msisdn.number.digit[strlen(msisdn) / 2].lsb = 0xf; for (int i = (strlen(msisdn) / 2) + 1; i < 10; i++) { - usim_data.msisdn.number.digit[i].msb = 0xf; - usim_data.msisdn.number.digit[i].lsb = 0xf; + usim_data->msisdn.number.digit[i].msb = 0xf; + usim_data->msisdn.number.digit[i].lsb = 0xf; } } /* @@ -304,22 +310,22 @@ void gen_usim_data(int user_id) { */ for (int i = 0; i < oplmn_nb; i++) { network_record_t record = user_network_record_list[oplmn[i]]; - usim_data.pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; - usim_data.pnn[i].fullname.length = strlen(record.fullname); - strncpy((char*) usim_data.pnn[i].fullname.value, record.fullname, - usim_data.pnn[i].fullname.length); - usim_data.pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG; - usim_data.pnn[i].shortname.length = strlen(record.shortname); - strncpy((char*) usim_data.pnn[i].shortname.value, record.shortname, - usim_data.pnn[i].shortname.length); - usim_data.opl[i].plmn = record.plmn; - usim_data.opl[i].start = record.tac_start; - usim_data.opl[i].end = record.tac_end; - usim_data.opl[i].record_id = i; + usim_data->pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; + usim_data->pnn[i].fullname.length = strlen(record.fullname); + strncpy((char*) usim_data->pnn[i].fullname.value, record.fullname, + usim_data->pnn[i].fullname.length); + usim_data->pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG; + usim_data->pnn[i].shortname.length = strlen(record.shortname); + strncpy((char*) usim_data->pnn[i].shortname.value, record.shortname, + usim_data->pnn[i].shortname.length); + usim_data->opl[i].plmn = record.plmn; + usim_data->opl[i].start = record.tac_start; + usim_data->opl[i].end = record.tac_end; + usim_data->opl[i].record_id = i; } if (oplmn_nb < USIM_OPL_MAX) { for (int i = oplmn_nb; i < USIM_OPL_MAX; i++) { - memset(&usim_data.opl[i].plmn, 0xff, sizeof(plmn_t)); + memset(&usim_data->opl[i].plmn, 0xff, sizeof(plmn_t)); } } @@ -327,155 +333,162 @@ void gen_usim_data(int user_id) { * List of Equivalent HPLMNs */ for (int i = 0; i < ehplmn_nb; i++) { - usim_data.ehplmn[i] = user_network_record_list[ehplmn[i]].plmn; + usim_data->ehplmn[i] = user_network_record_list[ehplmn[i]].plmn; } if (ehplmn_nb < USIM_EHPLMN_MAX) { for (int i = ehplmn_nb; i < USIM_EHPLMN_MAX; i++) { - memset(&usim_data.ehplmn[i], 0xff, sizeof(plmn_t)); + memset(&usim_data->ehplmn[i], 0xff, sizeof(plmn_t)); } } /* * Home PLMN Selector with Access Technology */ - usim_data.hplmn.plmn = user_network_record_list[hplmn_index].plmn; - usim_data.hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); + usim_data->hplmn.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); /* * List of user controlled PLMN selector with Access Technology */ for (int i = 0; i < USIM_PLMN_MAX; i++) { - memset(&usim_data.plmn[i], 0xff, sizeof(plmn_t)); + memset(&usim_data->plmn[i], 0xff, sizeof(plmn_t)); } if (ucplmn_nb > 0) { for (int i = 0; i < ucplmn_nb; i++) { - usim_data.plmn[i].plmn = user_network_record_list[ucplmn[i]].plmn; + usim_data->plmn[i].plmn = user_network_record_list[ucplmn[i]].plmn; } } // List of operator controlled PLMN selector with Access Technology for (int i = 0; i < USIM_OPLMN_MAX; i++) { - memset(&usim_data.oplmn[i], 0xff, sizeof(plmn_t)); + memset(&usim_data->oplmn[i], 0xff, sizeof(plmn_t)); } if (ocplmn_nb > 0) { for (int i = 0; i < ocplmn_nb; i++) { - usim_data.oplmn[i].plmn = user_network_record_list[ocplmn[i]].plmn; - usim_data.oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN + usim_data->oplmn[i].plmn = user_network_record_list[ocplmn[i]].plmn; + usim_data->oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); } } /* * EPS Location Information */ - usim_data.epsloci.guti.gummei.plmn = + usim_data->epsloci.guti.gummei.plmn = user_network_record_list[hplmn_index].plmn; - usim_data.epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID; - usim_data.epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE; - usim_data.epsloci.guti.m_tmsi = DEFAULT_M_TMSI; - usim_data.epsloci.tai.plmn = usim_data.epsloci.guti.gummei.plmn; - usim_data.epsloci.tai.tac = DEFAULT_TAC; - usim_data.epsloci.status = USIM_EPSLOCI_UPDATED; + usim_data->epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID; + usim_data->epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE; + usim_data->epsloci.guti.m_tmsi = DEFAULT_M_TMSI; + usim_data->epsloci.tai.plmn = usim_data->epsloci.guti.gummei.plmn; + usim_data->epsloci.tai.tac = DEFAULT_TAC; + usim_data->epsloci.status = USIM_EPSLOCI_UPDATED; /* * Non-Access Stratum configuration */ - usim_data.nasconfig.NAS_SignallingPriority.type = + usim_data->nasconfig.NAS_SignallingPriority.type = USIM_NAS_SIGNALLING_PRIORITY_TAG; - usim_data.nasconfig.NAS_SignallingPriority.length = 1; - usim_data.nasconfig.NAS_SignallingPriority.value[0] = 0x00; - usim_data.nasconfig.NMO_I_Behaviour.type = USIM_NMO_I_BEHAVIOUR_TAG; - usim_data.nasconfig.NMO_I_Behaviour.length = 1; - usim_data.nasconfig.NMO_I_Behaviour.value[0] = 0x00; - usim_data.nasconfig.AttachWithImsi.type = USIM_ATTACH_WITH_IMSI_TAG; - usim_data.nasconfig.AttachWithImsi.length = 1; + usim_data->nasconfig.NAS_SignallingPriority.length = 1; + usim_data->nasconfig.NAS_SignallingPriority.value[0] = 0x00; + usim_data->nasconfig.NMO_I_Behaviour.type = USIM_NMO_I_BEHAVIOUR_TAG; + usim_data->nasconfig.NMO_I_Behaviour.length = 1; + usim_data->nasconfig.NMO_I_Behaviour.value[0] = 0x00; + usim_data->nasconfig.AttachWithImsi.type = USIM_ATTACH_WITH_IMSI_TAG; + usim_data->nasconfig.AttachWithImsi.length = 1; #if defined(START_WITH_GUTI) - usim_data.nasconfig.AttachWithImsi.value[0] = 0x00; + usim_data->nasconfig.AttachWithImsi.value[0] = 0x00; #else - usim_data.nasconfig.AttachWithImsi.value[0] = 0x01; + usim_data->nasconfig.AttachWithImsi.value[0] = 0x01; #endif - usim_data.nasconfig.MinimumPeriodicSearchTimer.type = + usim_data->nasconfig.MinimumPeriodicSearchTimer.type = USIM_MINIMUM_PERIODIC_SEARCH_TIMER_TAG; - usim_data.nasconfig.MinimumPeriodicSearchTimer.length = 1; - usim_data.nasconfig.MinimumPeriodicSearchTimer.value[0] = 0x00; - usim_data.nasconfig.ExtendedAccessBarring.type = + usim_data->nasconfig.MinimumPeriodicSearchTimer.length = 1; + usim_data->nasconfig.MinimumPeriodicSearchTimer.value[0] = 0x00; + usim_data->nasconfig.ExtendedAccessBarring.type = USIM_EXTENDED_ACCESS_BARRING_TAG; - usim_data.nasconfig.ExtendedAccessBarring.length = 1; - usim_data.nasconfig.ExtendedAccessBarring.value[0] = 0x00; - usim_data.nasconfig.Timer_T3245_Behaviour.type = + usim_data->nasconfig.ExtendedAccessBarring.length = 1; + usim_data->nasconfig.ExtendedAccessBarring.value[0] = 0x00; + usim_data->nasconfig.Timer_T3245_Behaviour.type = USIM_TIMER_T3245_BEHAVIOUR_TAG; - usim_data.nasconfig.Timer_T3245_Behaviour.length = 1; - usim_data.nasconfig.Timer_T3245_Behaviour.value[0] = 0x00; + usim_data->nasconfig.Timer_T3245_Behaviour.length = 1; + usim_data->nasconfig.Timer_T3245_Behaviour.value[0] = 0x00; /* initialize the subscriber authentication security key */ - hex_string_to_hex_value(usim_data.keys.usim_api_k, + hex_string_to_hex_value(usim_data->keys.usim_api_k, usim_api_k, USIM_API_K_SIZE); - hex_string_to_hex_value(usim_data.keys.opc, opc, + hex_string_to_hex_value(usim_data->keys.opc, opc, OPC_SIZE); - - char *path = make_filename(output_dir, USIM_API_NVRAM_FILENAME, user_id); - usim_api_write(path, &usim_data); - free(path); } -void gen_emm_data(int user_id) { - hplmn_index = get_plmn_index(hplmn); - emm_nvdata_t emm_data; - int rc; - memset(&emm_data, 0, sizeof(emm_nvdata_t)); - int hplmn_index = get_plmn_index(hplmn); - emm_data.imsi.length = 8; - emm_data.imsi.u.num.parity = get_msin_parity(msin); - emm_data.imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; - emm_data.imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; - emm_data.imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; - emm_data.imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; - emm_data.imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; +int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ + int rc; + char *filename = make_filename(directory, USIM_API_NVRAM_FILENAME, user_id); + rc = usim_api_write(filename, usim_data); + free(filename); + return rc; +} + + +void gen_emm_data(int user_id, emm_nvdata_t *emm_data) { + hplmn_index = get_plmn_index(hplmn); + memset(emm_data, 0, sizeof(emm_nvdata_t)); + int hplmn_index = get_plmn_index(hplmn); + emm_data->imsi.length = 8; + emm_data->imsi.u.num.parity = get_msin_parity(msin); + emm_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; + emm_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; + emm_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + + emm_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; + emm_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; if (strlen(user_plmn_list[hplmn_index].mnc) == 3) { - emm_data.rplmn.MNCdigit3 = user_plmn_list[hplmn_index].mnc[2]; + emm_data->rplmn.MNCdigit3 = user_plmn_list[hplmn_index].mnc[2]; - emm_data.imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; - emm_data.imsi.u.num.digit7 = msin[0]; - emm_data.imsi.u.num.digit8 = msin[1]; - emm_data.imsi.u.num.digit9 = msin[2]; - emm_data.imsi.u.num.digit10 = msin[3]; - emm_data.imsi.u.num.digit11 = msin[4]; - emm_data.imsi.u.num.digit12 = msin[5]; - emm_data.imsi.u.num.digit13 = msin[6]; - emm_data.imsi.u.num.digit14 = msin[7]; - emm_data.imsi.u.num.digit15 = msin[8]; + emm_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + emm_data->imsi.u.num.digit7 = msin[0]; + emm_data->imsi.u.num.digit8 = msin[1]; + emm_data->imsi.u.num.digit9 = msin[2]; + emm_data->imsi.u.num.digit10 = msin[3]; + emm_data->imsi.u.num.digit11 = msin[4]; + emm_data->imsi.u.num.digit12 = msin[5]; + emm_data->imsi.u.num.digit13 = msin[6]; + emm_data->imsi.u.num.digit14 = msin[7]; + emm_data->imsi.u.num.digit15 = msin[8]; } else { - emm_data.rplmn.MNCdigit3 = 0xf; + emm_data->rplmn.MNCdigit3 = 0xf; - emm_data.imsi.u.num.digit6 = msin[0]; - emm_data.imsi.u.num.digit7 = msin[1]; - emm_data.imsi.u.num.digit8 = msin[2]; - emm_data.imsi.u.num.digit9 = msin[3]; - emm_data.imsi.u.num.digit10 = msin[4]; - emm_data.imsi.u.num.digit11 = msin[5]; - emm_data.imsi.u.num.digit12 = msin[6]; - emm_data.imsi.u.num.digit13 = msin[7]; - emm_data.imsi.u.num.digit14 = msin[8]; - emm_data.imsi.u.num.digit15 = msin[9]; + emm_data->imsi.u.num.digit6 = msin[0]; + emm_data->imsi.u.num.digit7 = msin[1]; + emm_data->imsi.u.num.digit8 = msin[2]; + emm_data->imsi.u.num.digit9 = msin[3]; + emm_data->imsi.u.num.digit10 = msin[4]; + emm_data->imsi.u.num.digit11 = msin[5]; + emm_data->imsi.u.num.digit12 = msin[6]; + emm_data->imsi.u.num.digit13 = msin[7]; + emm_data->imsi.u.num.digit14 = msin[8]; + emm_data->imsi.u.num.digit15 = msin[9]; } - emm_data.rplmn.MCCdigit1 = user_plmn_list[hplmn_index].mcc[0]; - emm_data.rplmn.MCCdigit2 = user_plmn_list[hplmn_index].mcc[1]; - emm_data.rplmn.MCCdigit3 = user_plmn_list[hplmn_index].mcc[2]; - emm_data.rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; - emm_data.rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; + emm_data->rplmn.MCCdigit1 = user_plmn_list[hplmn_index].mcc[0]; + emm_data->rplmn.MCCdigit2 = user_plmn_list[hplmn_index].mcc[1]; + emm_data->rplmn.MCCdigit3 = user_plmn_list[hplmn_index].mcc[2]; + emm_data->rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; + emm_data->rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; - emm_data.eplmn.n_plmns = ehplmn_nb; + emm_data->eplmn.n_plmns = ehplmn_nb; +} - char* path = make_filename(output_dir, EMM_NVRAM_FILENAME, user_id); - rc = memory_write(path, &emm_data, sizeof(emm_nvdata_t)); - free(path); +int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { + int rc; + char* filename = make_filename(directory, EMM_NVRAM_FILENAME, user_id); + rc = memory_write(filename, emm_data, sizeof(emm_nvdata_t)); + free(filename); if (rc != RETURNok) { perror("ERROR\t: memory_write() failed"); exit(EXIT_FAILURE); } - + return(EXIT_SUCCESS); } int parse_plmn_param(config_setting_t *plmn_setting, int index) { @@ -632,9 +645,8 @@ int parse_ue_sim_param(config_setting_t *ue_setting, int user_id) { return EXIT_SUCCESS; } -int parse_ue_user_param(config_setting_t *ue_setting, int user_id) { +int parse_ue_user_param(config_setting_t *ue_setting, int user_id, user_nvdata_t *user_data) { config_setting_t *ue_param_setting = NULL; - user_nvdata_t user_data; const char* imei = NULL; const char* manufacturer = NULL; const char* model = NULL; @@ -667,29 +679,34 @@ int parse_ue_user_param(config_setting_t *ue_setting, int user_id) { printf("Check USER PIN for UE%d FULLNAME. Exiting\n", user_id); return EXIT_FAILURE; } - memset(&user_data, 0, sizeof(user_nvdata_t)); - snprintf(user_data.IMEI, USER_IMEI_SIZE + 1, "%s%d", imei, _luhn(imei)); + + memset(user_data, 0, sizeof(user_nvdata_t)); + snprintf(user_data->IMEI, USER_IMEI_SIZE + 1, "%s%d", imei, _luhn(imei)); /* * Manufacturer identifier */ - strncpy(user_data.manufacturer, manufacturer, USER_MANUFACTURER_SIZE); + strncpy(user_data->manufacturer, manufacturer, USER_MANUFACTURER_SIZE); /* * Model identifier */ - strncpy(user_data.model, model, USER_MODEL_SIZE); + strncpy(user_data->model, model, USER_MODEL_SIZE); /* * SIM Personal Identification Number */ - strncpy(user_data.PIN, pin, USER_PIN_SIZE); + strncpy(user_data->PIN, pin, USER_PIN_SIZE); - char* path = make_filename(output_dir, USER_NVRAM_FILENAME, user_id); - rc = memory_write(path, &user_data, sizeof(user_nvdata_t)); - free(path); + return EXIT_SUCCESS; +} + +void write_user_data(const char *directory, int user_id, user_nvdata_t *data) { + int rc; + char* filename = make_filename(directory, USER_NVRAM_FILENAME, user_id); + rc = memory_write(filename, data, sizeof(user_nvdata_t)); + free(filename); if (rc != RETURNok) { perror("ERROR\t: memory_write() failed"); exit(EXIT_FAILURE); } - return EXIT_SUCCESS; } int fill_ucplmn(config_setting_t* setting, int user_id) { diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 98c4752743..1aee521e79 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -2,7 +2,10 @@ #define _CONF2UEDATA_H #include + #include "emmData.h" +#include "usim_api.h" +#include "userDef.h" #define USER "USER" #define UE "UE" @@ -70,8 +73,6 @@ typedef struct { const char *mcc; } plmn_conf_param_t; -extern const char* output_dir; - extern const char *msin; extern const char *usim_api_k; extern const char *msisdn; @@ -96,16 +97,21 @@ extern plmn_conf_param_t* user_plmn_list; extern network_record_t* user_network_record_list; int get_config_from_file(const char *filename, config_t *config); -int parse_config_file(const char *filename); +int parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); -void gen_emm_data(int user_id) ; -void gen_usim_data(int user_id); +void gen_emm_data(int user_id, emm_nvdata_t *emm_data); void fill_network_record_list(void); +int parse_ue_user_param(config_setting_t *ue_setting, int user_id, user_nvdata_t *user_data); +void write_user_data(const char *directory, int user_id, user_nvdata_t *data); +int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); +int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); +void gen_usim_data(usim_data_t *usim_data); + + int _luhn(const char* cc); -int parse_ue_user_param(config_setting_t *ue_setting, int user_id); int parse_ue_sim_param(config_setting_t *ue_setting, int user_id); int parse_plmn_param(config_setting_t *plmn_setting, int index); int parse_plmns(config_setting_t *all_plmn_setting); From eeb44860e9cef26b850b3fcefa3706af1c5c7764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 16 Aug 2016 15:58:35 +0200 Subject: [PATCH 199/571] refactor(conf2uedata): move emm_data funcions in conf_emm.[c|h] --- cmake_targets/nas_sim_tools/CMakeLists.txt | 2 + openair3/NAS/TOOLS/conf2uedata.c | 75 +------------------- openair3/NAS/TOOLS/conf2uedata.h | 4 -- openair3/NAS/TOOLS/conf_emm.c | 80 ++++++++++++++++++++++ openair3/NAS/TOOLS/conf_emm.h | 10 +++ 5 files changed, 94 insertions(+), 77 deletions(-) create mode 100644 openair3/NAS/TOOLS/conf_emm.c create mode 100644 openair3/NAS/TOOLS/conf_emm.h diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 8158362912..9e48fd5eb3 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -17,6 +17,7 @@ set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3) set(conf2uedata_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c @@ -30,6 +31,7 @@ set(conf2uedata_SRC set(conf2uedata_HDR ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.h + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.h ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.h ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.h ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 486b7e2bff..c14232d00d 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -10,6 +10,7 @@ #include "utils.h" #include "display.h" #include "fs.h" +#include "conf_emm.h" const char *msin = NULL; const char *usim_api_k = NULL; @@ -138,7 +139,7 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { if (rc != EXIT_SUCCESS) { return EXIT_FAILURE; } - gen_emm_data(i, &emm_data); + gen_emm_data(&emm_data); write_emm_data(output_dir, i, &emm_data); gen_usim_data(&usim_data); @@ -427,70 +428,6 @@ int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ } -void gen_emm_data(int user_id, emm_nvdata_t *emm_data) { - hplmn_index = get_plmn_index(hplmn); - memset(emm_data, 0, sizeof(emm_nvdata_t)); - int hplmn_index = get_plmn_index(hplmn); - emm_data->imsi.length = 8; - emm_data->imsi.u.num.parity = get_msin_parity(msin); - emm_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; - emm_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; - emm_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; - - emm_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; - emm_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; - - if (strlen(user_plmn_list[hplmn_index].mnc) == 3) { - emm_data->rplmn.MNCdigit3 = user_plmn_list[hplmn_index].mnc[2]; - - emm_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; - emm_data->imsi.u.num.digit7 = msin[0]; - emm_data->imsi.u.num.digit8 = msin[1]; - emm_data->imsi.u.num.digit9 = msin[2]; - emm_data->imsi.u.num.digit10 = msin[3]; - emm_data->imsi.u.num.digit11 = msin[4]; - emm_data->imsi.u.num.digit12 = msin[5]; - emm_data->imsi.u.num.digit13 = msin[6]; - emm_data->imsi.u.num.digit14 = msin[7]; - emm_data->imsi.u.num.digit15 = msin[8]; - - } else { - emm_data->rplmn.MNCdigit3 = 0xf; - - emm_data->imsi.u.num.digit6 = msin[0]; - emm_data->imsi.u.num.digit7 = msin[1]; - emm_data->imsi.u.num.digit8 = msin[2]; - emm_data->imsi.u.num.digit9 = msin[3]; - emm_data->imsi.u.num.digit10 = msin[4]; - emm_data->imsi.u.num.digit11 = msin[5]; - emm_data->imsi.u.num.digit12 = msin[6]; - emm_data->imsi.u.num.digit13 = msin[7]; - emm_data->imsi.u.num.digit14 = msin[8]; - emm_data->imsi.u.num.digit15 = msin[9]; - - } - - emm_data->rplmn.MCCdigit1 = user_plmn_list[hplmn_index].mcc[0]; - emm_data->rplmn.MCCdigit2 = user_plmn_list[hplmn_index].mcc[1]; - emm_data->rplmn.MCCdigit3 = user_plmn_list[hplmn_index].mcc[2]; - emm_data->rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; - emm_data->rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; - - emm_data->eplmn.n_plmns = ehplmn_nb; -} - -int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { - int rc; - char* filename = make_filename(directory, EMM_NVRAM_FILENAME, user_id); - rc = memory_write(filename, emm_data, sizeof(emm_nvdata_t)); - free(filename); - if (rc != RETURNok) { - perror("ERROR\t: memory_write() failed"); - exit(EXIT_FAILURE); - } - return(EXIT_SUCCESS); -} - int parse_plmn_param(config_setting_t *plmn_setting, int index) { int rc = 0; rc = config_setting_lookup_string(plmn_setting, @@ -827,14 +764,6 @@ int get_plmn_index(const char * mccmnc) { return -1; } -int get_msin_parity(const char * msin) { - int imsi_size = strlen(msin) + strlen(user_plmn_list[hplmn_index].mcc) - + strlen(user_plmn_list[hplmn_index].mnc); - int result = (imsi_size % 2 == 0) ? 0 : 1; - return result; - -} - void fill_network_record_list() { for (int i = 0; i < plmn_nb; i++) { strcpy(user_network_record_list[i].fullname, diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 1aee521e79..e58f5877e3 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -3,7 +3,6 @@ #include -#include "emmData.h" #include "usim_api.h" #include "userDef.h" @@ -100,12 +99,10 @@ int get_config_from_file(const char *filename, config_t *config); int parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); -void gen_emm_data(int user_id, emm_nvdata_t *emm_data); void fill_network_record_list(void); int parse_ue_user_param(config_setting_t *ue_setting, int user_id, user_nvdata_t *user_data); void write_user_data(const char *directory, int user_id, user_nvdata_t *data); -int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); void gen_usim_data(usim_data_t *usim_data); @@ -115,7 +112,6 @@ int _luhn(const char* cc); int parse_ue_sim_param(config_setting_t *ue_setting, int user_id); int parse_plmn_param(config_setting_t *plmn_setting, int index); int parse_plmns(config_setting_t *all_plmn_setting); -int get_msin_parity(const char * msin); int get_plmn_index(const char * mccmnc); int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id); int fill_ucplmn(config_setting_t* setting, int use_id); diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c new file mode 100644 index 0000000000..a46fc5d59b --- /dev/null +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -0,0 +1,80 @@ +#include + +#include "conf2uedata.h" +#include "memory.h" +#include "conf_emm.h" +#include "fs.h" + +void gen_emm_data(emm_nvdata_t *emm_data) { + hplmn_index = get_plmn_index(hplmn); + memset(emm_data, 0, sizeof(emm_nvdata_t)); + int hplmn_index = get_plmn_index(hplmn); + emm_data->imsi.length = 8; + emm_data->imsi.u.num.parity = get_msin_parity(msin); + emm_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; + emm_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; + emm_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + + emm_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; + emm_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; + + if (strlen(user_plmn_list[hplmn_index].mnc) == 3) { + emm_data->rplmn.MNCdigit3 = user_plmn_list[hplmn_index].mnc[2]; + + emm_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + emm_data->imsi.u.num.digit7 = msin[0]; + emm_data->imsi.u.num.digit8 = msin[1]; + emm_data->imsi.u.num.digit9 = msin[2]; + emm_data->imsi.u.num.digit10 = msin[3]; + emm_data->imsi.u.num.digit11 = msin[4]; + emm_data->imsi.u.num.digit12 = msin[5]; + emm_data->imsi.u.num.digit13 = msin[6]; + emm_data->imsi.u.num.digit14 = msin[7]; + emm_data->imsi.u.num.digit15 = msin[8]; + + } else { + emm_data->rplmn.MNCdigit3 = 0xf; + + emm_data->imsi.u.num.digit6 = msin[0]; + emm_data->imsi.u.num.digit7 = msin[1]; + emm_data->imsi.u.num.digit8 = msin[2]; + emm_data->imsi.u.num.digit9 = msin[3]; + emm_data->imsi.u.num.digit10 = msin[4]; + emm_data->imsi.u.num.digit11 = msin[5]; + emm_data->imsi.u.num.digit12 = msin[6]; + emm_data->imsi.u.num.digit13 = msin[7]; + emm_data->imsi.u.num.digit14 = msin[8]; + emm_data->imsi.u.num.digit15 = msin[9]; + + } + + emm_data->rplmn.MCCdigit1 = user_plmn_list[hplmn_index].mcc[0]; + emm_data->rplmn.MCCdigit2 = user_plmn_list[hplmn_index].mcc[1]; + emm_data->rplmn.MCCdigit3 = user_plmn_list[hplmn_index].mcc[2]; + emm_data->rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; + emm_data->rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; + + emm_data->eplmn.n_plmns = ehplmn_nb; +} + +int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { + int rc; + char* filename = make_filename(directory, EMM_NVRAM_FILENAME, user_id); + rc = memory_write(filename, emm_data, sizeof(emm_nvdata_t)); + free(filename); + if (rc != RETURNok) { + perror("ERROR\t: memory_write() failed"); + exit(EXIT_FAILURE); + } + return(EXIT_SUCCESS); +} + +int get_msin_parity(const char * msin) { + int imsi_size = strlen(msin) + strlen(user_plmn_list[hplmn_index].mcc) + + strlen(user_plmn_list[hplmn_index].mnc); + int result = (imsi_size % 2 == 0) ? 0 : 1; + return result; + +} + + diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h new file mode 100644 index 0000000000..ddb920f5b5 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -0,0 +1,10 @@ +#ifndef _CONF_EMM_H +#define _CONF_EMM_H + +#include "emmData.h" + +void gen_emm_data(emm_nvdata_t *emm_data); +int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); +int get_msin_parity(const char * msin); + +#endif From f03e2dbc0e4256ce2c98e97359ab1880245442f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 17 Aug 2016 09:01:11 +0200 Subject: [PATCH 200/571] refactor(conf2uedata): move user_data function in conf_user_data[c|h] --- cmake_targets/nas_sim_tools/CMakeLists.txt | 1 + openair3/NAS/TOOLS/conf2uedata.c | 83 ++------------------- openair3/NAS/TOOLS/conf2uedata.h | 7 -- openair3/NAS/TOOLS/conf_user_data.c | 84 ++++++++++++++++++++++ openair3/NAS/TOOLS/conf_user_data.h | 26 +++++++ 5 files changed, 115 insertions(+), 86 deletions(-) create mode 100644 openair3/NAS/TOOLS/conf_user_data.c create mode 100644 openair3/NAS/TOOLS/conf_user_data.h diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 9e48fd5eb3..f450715a29 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -18,6 +18,7 @@ set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3) set(conf2uedata_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index c14232d00d..3b31776a02 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -11,6 +11,7 @@ #include "display.h" #include "fs.h" #include "conf_emm.h" +#include "conf_user_data.h" const char *msin = NULL; const char *usim_api_k = NULL; @@ -113,6 +114,7 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { emm_nvdata_t emm_data; user_nvdata_t user_data; usim_data_t usim_data; + user_data_conf_t user_data_conf; sprintf(user, "%s%d", UE, i); @@ -122,11 +124,12 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { return EXIT_FAILURE; } - rc = parse_ue_user_param(ue_setting, i, &user_data); + rc = parse_ue_user_data(ue_setting, i, &user_data_conf); if (rc != EXIT_SUCCESS) { printf("Problem in USER section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } + gen_user_data(&user_data_conf, &user_data); write_user_data(output_dir, i, &user_data); rc = parse_ue_sim_param(ue_setting, i); @@ -582,69 +585,6 @@ int parse_ue_sim_param(config_setting_t *ue_setting, int user_id) { return EXIT_SUCCESS; } -int parse_ue_user_param(config_setting_t *ue_setting, int user_id, user_nvdata_t *user_data) { - config_setting_t *ue_param_setting = NULL; - const char* imei = NULL; - const char* manufacturer = NULL; - const char* model = NULL; - const char* pin = NULL; - - int rc = EXIT_SUCCESS; - ue_param_setting = config_setting_get_member(ue_setting, USER); - if (ue_param_setting == NULL) { - printf("Check USER section of UE%d. EXITING...\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, UE_IMEI, &imei); - if (rc != 1) { - printf("Check USER IMEI section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, MANUFACTURER, - &manufacturer); - if (rc != 1) { - printf("Check USER MANUFACTURER for UE%d FULLNAME. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, MODEL, &model); - if (rc != 1) { - printf("Check USER MODEL for UE%d FULLNAME. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, PINCODE, &pin); - if (rc != 1) { - printf("Check USER PIN for UE%d FULLNAME. Exiting\n", user_id); - return EXIT_FAILURE; - } - - memset(user_data, 0, sizeof(user_nvdata_t)); - snprintf(user_data->IMEI, USER_IMEI_SIZE + 1, "%s%d", imei, _luhn(imei)); - /* - * Manufacturer identifier - */ - strncpy(user_data->manufacturer, manufacturer, USER_MANUFACTURER_SIZE); - /* - * Model identifier - */ - strncpy(user_data->model, model, USER_MODEL_SIZE); - /* - * SIM Personal Identification Number - */ - strncpy(user_data->PIN, pin, USER_PIN_SIZE); - - return EXIT_SUCCESS; -} - -void write_user_data(const char *directory, int user_id, user_nvdata_t *data) { - int rc; - char* filename = make_filename(directory, USER_NVRAM_FILENAME, user_id); - rc = memory_write(filename, data, sizeof(user_nvdata_t)); - free(filename); - if (rc != RETURNok) { - perror("ERROR\t: memory_write() failed"); - exit(EXIT_FAILURE); - } -} int fill_ucplmn(config_setting_t* setting, int user_id) { int rc; @@ -788,21 +728,6 @@ void fill_network_record_list() { } } -/* - * Computes the check digit using Luhn algorithm - */ -int _luhn(const char* cc) { - const int m[] = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }; - int odd = 1, sum = 0; - - for (int i = strlen(cc); i--; odd = !odd) { - int digit = cc[i] - '0'; - sum += odd ? m[digit] : digit; - } - - return 10 - (sum % 10); -} - /* * Displays command line usage */ diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index e58f5877e3..cb2b31a4ff 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -4,9 +4,7 @@ #include #include "usim_api.h" -#include "userDef.h" -#define USER "USER" #define UE "UE" #define SIM "SIM" #define PLMN "PLMN" @@ -101,14 +99,9 @@ int parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); void fill_network_record_list(void); -int parse_ue_user_param(config_setting_t *ue_setting, int user_id, user_nvdata_t *user_data); -void write_user_data(const char *directory, int user_id, user_nvdata_t *data); int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); void gen_usim_data(usim_data_t *usim_data); - -int _luhn(const char* cc); - int parse_ue_sim_param(config_setting_t *ue_setting, int user_id); int parse_plmn_param(config_setting_t *plmn_setting, int index); int parse_plmns(config_setting_t *all_plmn_setting); diff --git a/openair3/NAS/TOOLS/conf_user_data.c b/openair3/NAS/TOOLS/conf_user_data.c new file mode 100644 index 0000000000..4dcfc3cf78 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_data.c @@ -0,0 +1,84 @@ +#include +#include + +#include "memory.h" +#include "fs.h" +#include "conf_user_data.h" + +int parse_ue_user_data(config_setting_t *ue_setting, int user_id, user_data_conf_t *u) { + config_setting_t *ue_param_setting = NULL; + + int rc = EXIT_SUCCESS; + ue_param_setting = config_setting_get_member(ue_setting, USER); + if (ue_param_setting == NULL) { + printf("Check USER section of UE%d. EXITING...\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, UE_IMEI, &u->imei); + if (rc != 1) { + printf("Check USER IMEI section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MANUFACTURER, + &u->manufacturer); + if (rc != 1) { + printf("Check USER MANUFACTURER for UE%d FULLNAME. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MODEL, &u->model); + if (rc != 1) { + printf("Check USER MODEL for UE%d FULLNAME. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, PINCODE, &u->pin); + if (rc != 1) { + printf("Check USER PIN for UE%d FULLNAME. Exiting\n", user_id); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +void gen_user_data(user_data_conf_t *u, user_nvdata_t *user_data) { + memset(user_data, 0, sizeof(user_nvdata_t)); + snprintf(user_data->IMEI, USER_IMEI_SIZE + 1, "%s%d", u->imei, _luhn(u->imei)); + /* + * Manufacturer identifier + */ + strncpy(user_data->manufacturer, u->manufacturer, USER_MANUFACTURER_SIZE); + /* + * Model identifier + */ + strncpy(user_data->model, u->model, USER_MODEL_SIZE); + /* + * SIM Personal Identification Number + */ + strncpy(user_data->PIN, u->pin, USER_PIN_SIZE); +} + +void write_user_data(const char *directory, int user_id, user_nvdata_t *data) { + int rc; + char* filename = make_filename(directory, USER_NVRAM_FILENAME, user_id); + rc = memory_write(filename, data, sizeof(user_nvdata_t)); + free(filename); + if (rc != EXIT_SUCCESS) { + perror("ERROR\t: memory_write() failed"); + exit(EXIT_FAILURE); + } +} + +/* + * Computes the check digit using Luhn algorithm + */ +int _luhn(const char* cc) { + const int m[] = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 }; + int odd = 1, sum = 0; + + for (int i = strlen(cc); i--; odd = !odd) { + int digit = cc[i] - '0'; + sum += odd ? m[digit] : digit; + } + + return 10 - (sum % 10); +} + + diff --git a/openair3/NAS/TOOLS/conf_user_data.h b/openair3/NAS/TOOLS/conf_user_data.h new file mode 100644 index 0000000000..ac168e3c72 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_data.h @@ -0,0 +1,26 @@ +#ifndef _CONF_USER_DATA_H +#define _CONF_USER_DATA_H + +#include +#include "userDef.h" + +#define USER "USER" +#define MANUFACTURER "MANUFACTURER" +#define MODEL "MODEL" +#define UE_IMEI "IMEI" +#define PINCODE "PIN" + +typedef struct { + const char* imei; + const char* manufacturer; + const char* model; + const char* pin; +} user_data_conf_t; + +void gen_user_data(user_data_conf_t *u, user_nvdata_t *user_data); +void write_user_data(const char *directory, int user_id, user_nvdata_t *data); +int parse_ue_user_data(config_setting_t *ue_setting, int user_id, user_data_conf_t *u); + +int _luhn(const char* cc); + +#endif From 7fe8d45d6a6a5702076fea08f66ac0aba6ad408c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 17 Aug 2016 08:42:37 +0200 Subject: [PATCH 201/571] refactor(conf2uedata): move usim_data funcions in conf_usim.[c|h] --- cmake_targets/nas_sim_tools/CMakeLists.txt | 1 + openair3/NAS/TOOLS/conf2uedata.c | 331 ++------------------- openair3/NAS/TOOLS/conf2uedata.h | 41 +-- openair3/NAS/TOOLS/conf_emm.c | 2 +- openair3/NAS/TOOLS/conf_emm.h | 2 +- openair3/NAS/TOOLS/conf_usim.c | 301 +++++++++++++++++++ openair3/NAS/TOOLS/conf_usim.h | 45 +++ 7 files changed, 371 insertions(+), 352 deletions(-) create mode 100644 openair3/NAS/TOOLS/conf_usim.c create mode 100644 openair3/NAS/TOOLS/conf_usim.h diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index f450715a29..39e7102357 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -19,6 +19,7 @@ set(conf2uedata_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 3b31776a02..a3beb27b2d 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -5,19 +5,12 @@ #include "conf2uedata.h" #include "memory.h" -#include "userDef.h" -#include "usim_api.h" #include "utils.h" #include "display.h" #include "fs.h" #include "conf_emm.h" #include "conf_user_data.h" - -const char *msin = NULL; -const char *usim_api_k = NULL; -const char *msisdn = NULL; -const char *opc = NULL; -const char *hplmn = NULL; +#include "conf_usim.h" int *ucplmn = NULL; int *oplmn = NULL; @@ -112,10 +105,13 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { for (int i = 0; i < ue_nb; i++) { emm_nvdata_t emm_data; + user_nvdata_t user_data; - usim_data_t usim_data; user_data_conf_t user_data_conf; + usim_data_t usim_data; + usim_data_conf_t usim_data_conf; + sprintf(user, "%s%d", UE, i); ue_setting = config_setting_get_member(root_setting, user); @@ -124,6 +120,11 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { return EXIT_FAILURE; } + rc = parse_ue_plmn_param(ue_setting, i, &usim_data_conf.hplmn); + if (rc != EXIT_SUCCESS) { + return EXIT_FAILURE; + } + rc = parse_ue_user_data(ue_setting, i, &user_data_conf); if (rc != EXIT_SUCCESS) { printf("Problem in USER section for UE%d. EXITING...\n", i); @@ -132,21 +133,17 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { gen_user_data(&user_data_conf, &user_data); write_user_data(output_dir, i, &user_data); - rc = parse_ue_sim_param(ue_setting, i); + rc = parse_ue_sim_param(ue_setting, i, &usim_data_conf); if (rc != EXIT_SUCCESS) { printf("Problem in SIM section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } + gen_usim_data(&usim_data_conf, &usim_data); + write_usim_data(output_dir, i, &usim_data); - rc = parse_ue_plmn_param(ue_setting, i); - if (rc != EXIT_SUCCESS) { - return EXIT_FAILURE; - } - gen_emm_data(&emm_data); + gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin); write_emm_data(output_dir, i, &emm_data); - gen_usim_data(&usim_data); - write_usim_data(output_dir, i, &usim_data); } config_destroy(&cfg); return(EXIT_SUCCESS); @@ -172,264 +169,6 @@ int get_config_from_file(const char *filename, config_t *config) { return EXIT_SUCCESS; } -void gen_usim_data(usim_data_t *usim_data) { - memset(usim_data, 0, sizeof(usim_data_t)); - usim_data->imsi.length = 8; - usim_data->imsi.u.num.parity = get_msin_parity(msin); - - usim_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; - usim_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; - usim_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; - - usim_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; - usim_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; - - if (strlen(user_plmn_list[hplmn_index].mnc) == 2) { - usim_data->imsi.u.num.digit6 = msin[0]; - usim_data->imsi.u.num.digit7 = msin[1]; - usim_data->imsi.u.num.digit8 = msin[2]; - usim_data->imsi.u.num.digit9 = msin[3]; - usim_data->imsi.u.num.digit10 = msin[4]; - usim_data->imsi.u.num.digit11 = msin[5]; - usim_data->imsi.u.num.digit12 = msin[6]; - usim_data->imsi.u.num.digit13 = msin[7]; - usim_data->imsi.u.num.digit14 = msin[8]; - usim_data->imsi.u.num.digit15 = msin[9]; - } else { - usim_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; - usim_data->imsi.u.num.digit7 = msin[0]; - usim_data->imsi.u.num.digit8 = msin[1]; - usim_data->imsi.u.num.digit9 = msin[2]; - usim_data->imsi.u.num.digit10 = msin[3]; - usim_data->imsi.u.num.digit11 = msin[4]; - usim_data->imsi.u.num.digit12 = msin[5]; - usim_data->imsi.u.num.digit13 = msin[6]; - usim_data->imsi.u.num.digit14 = msin[7]; - usim_data->imsi.u.num.digit15 = msin[8]; - } - - /* - * Ciphering and Integrity Keys - */ - usim_data->keys.ksi = KSI; - memset(&usim_data->keys.ck, 0, USIM_CK_SIZE); - memset(&usim_data->keys.ik, 0, USIM_IK_SIZE); - /* - * Higher Priority PLMN search period - */ - usim_data->hpplmn = 0x00; /* Disable timer */ - - /* - * List of Forbidden PLMNs - */ - for (int i = 0; i < USIM_FPLMN_MAX; i++) { - memset(&usim_data->fplmn[i], 0xff, sizeof(plmn_t)); - } - if (fplmn_nb > 0) { - for (int i = 0; i < fplmn_nb; i++) { - usim_data->fplmn[i] = user_network_record_list[fplmn[i]].plmn; - } - } - - /* - * Location Information - */ - usim_data->loci.tmsi = DEFAULT_TMSI; - usim_data->loci.lai.plmn = user_network_record_list[hplmn_index].plmn; - usim_data->loci.lai.lac = DEFAULT_LAC; - usim_data->loci.status = USIM_LOCI_NOT_UPDATED; - /* - * Packet Switched Location Information - */ - usim_data->psloci.p_tmsi = DEFAULT_P_TMSI; - usim_data->psloci.signature[0] = 0x01; - usim_data->psloci.signature[1] = 0x02; - usim_data->psloci.signature[2] = 0x03; - usim_data->psloci.rai.plmn = user_network_record_list[hplmn_index].plmn; - usim_data->psloci.rai.lac = DEFAULT_LAC; - usim_data->psloci.rai.rac = DEFAULT_RAC; - usim_data->psloci.status = USIM_PSLOCI_NOT_UPDATED; - /* - * Administrative Data - */ - usim_data->ad.UE_Operation_Mode = USIM_NORMAL_MODE; - usim_data->ad.Additional_Info = 0xffff; - usim_data->ad.MNC_Length = strlen(user_plmn_list[hplmn_index].mnc); - /* - * EPS NAS security context - */ - usim_data->securityctx.length = 52; - usim_data->securityctx.KSIasme.type = USIM_KSI_ASME_TAG; - usim_data->securityctx.KSIasme.length = 1; - usim_data->securityctx.KSIasme.value[0] = KSI_ASME; - usim_data->securityctx.Kasme.type = USIM_K_ASME_TAG; - usim_data->securityctx.Kasme.length = USIM_K_ASME_SIZE; - memset(usim_data->securityctx.Kasme.value, 0, - usim_data->securityctx.Kasme.length); - usim_data->securityctx.ulNAScount.type = USIM_UL_NAS_COUNT_TAG; - usim_data->securityctx.ulNAScount.length = USIM_UL_NAS_COUNT_SIZE; - memset(usim_data->securityctx.ulNAScount.value, 0, - usim_data->securityctx.ulNAScount.length); - usim_data->securityctx.dlNAScount.type = USIM_DL_NAS_COUNT_TAG; - usim_data->securityctx.dlNAScount.length = USIM_DL_NAS_COUNT_SIZE; - memset(usim_data->securityctx.dlNAScount.value, 0, - usim_data->securityctx.dlNAScount.length); - usim_data->securityctx.algorithmID.type = USIM_INT_ENC_ALGORITHMS_TAG; - usim_data->securityctx.algorithmID.length = 1; - usim_data->securityctx.algorithmID.value[0] = SECURITY_ALGORITHMS; - /* - * Subcriber's Number - */ - usim_data->msisdn.length = 7; - usim_data->msisdn.number.ext = 1; - usim_data->msisdn.number.ton = MSISDN_TON_UNKNOWKN; - usim_data->msisdn.number.npi = MSISDN_NPI_ISDN_TELEPHONY; - usim_data->msisdn.conf1_record_id = 0xff; /* Not used */ - usim_data->msisdn.ext1_record_id = 0xff; /* Not used */ - int j = 0; - for (int i = 0; i < strlen(msisdn); i += 2) { - usim_data->msisdn.number.digit[j].msb = msisdn[i]; - j++; - } - j = 0; - for (int i = 1; i < strlen(msisdn); i += 2) { - usim_data->msisdn.number.digit[j].lsb = msisdn[i]; - j++; - - } - if (strlen(msisdn) % 2 == 0) { - for (int i = strlen(msisdn) / 2; i < 10; i++) { - usim_data->msisdn.number.digit[i].msb = 0xf; - usim_data->msisdn.number.digit[i].lsb = 0xf; - } - } else { - usim_data->msisdn.number.digit[strlen(msisdn) / 2].lsb = 0xf; - for (int i = (strlen(msisdn) / 2) + 1; i < 10; i++) { - usim_data->msisdn.number.digit[i].msb = 0xf; - usim_data->msisdn.number.digit[i].lsb = 0xf; - } - } - /* - * PLMN Network Name and Operator PLMN List - */ - for (int i = 0; i < oplmn_nb; i++) { - network_record_t record = user_network_record_list[oplmn[i]]; - usim_data->pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; - usim_data->pnn[i].fullname.length = strlen(record.fullname); - strncpy((char*) usim_data->pnn[i].fullname.value, record.fullname, - usim_data->pnn[i].fullname.length); - usim_data->pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG; - usim_data->pnn[i].shortname.length = strlen(record.shortname); - strncpy((char*) usim_data->pnn[i].shortname.value, record.shortname, - usim_data->pnn[i].shortname.length); - usim_data->opl[i].plmn = record.plmn; - usim_data->opl[i].start = record.tac_start; - usim_data->opl[i].end = record.tac_end; - usim_data->opl[i].record_id = i; - } - if (oplmn_nb < USIM_OPL_MAX) { - for (int i = oplmn_nb; i < USIM_OPL_MAX; i++) { - memset(&usim_data->opl[i].plmn, 0xff, sizeof(plmn_t)); - } - } - - /* - * List of Equivalent HPLMNs - */ - for (int i = 0; i < ehplmn_nb; i++) { - usim_data->ehplmn[i] = user_network_record_list[ehplmn[i]].plmn; - } - if (ehplmn_nb < USIM_EHPLMN_MAX) { - for (int i = ehplmn_nb; i < USIM_EHPLMN_MAX; i++) { - memset(&usim_data->ehplmn[i], 0xff, sizeof(plmn_t)); - } - } - /* - * Home PLMN Selector with Access Technology - */ - usim_data->hplmn.plmn = user_network_record_list[hplmn_index].plmn; - usim_data->hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); - - /* - * List of user controlled PLMN selector with Access Technology - */ - for (int i = 0; i < USIM_PLMN_MAX; i++) { - memset(&usim_data->plmn[i], 0xff, sizeof(plmn_t)); - } - if (ucplmn_nb > 0) { - for (int i = 0; i < ucplmn_nb; i++) { - usim_data->plmn[i].plmn = user_network_record_list[ucplmn[i]].plmn; - } - } - - // List of operator controlled PLMN selector with Access Technology - - for (int i = 0; i < USIM_OPLMN_MAX; i++) { - memset(&usim_data->oplmn[i], 0xff, sizeof(plmn_t)); - } - if (ocplmn_nb > 0) { - for (int i = 0; i < ocplmn_nb; i++) { - usim_data->oplmn[i].plmn = user_network_record_list[ocplmn[i]].plmn; - usim_data->oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN - | USIM_ACT_EUTRAN); - } - } - /* - * EPS Location Information - */ - usim_data->epsloci.guti.gummei.plmn = - user_network_record_list[hplmn_index].plmn; - usim_data->epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID; - usim_data->epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE; - usim_data->epsloci.guti.m_tmsi = DEFAULT_M_TMSI; - usim_data->epsloci.tai.plmn = usim_data->epsloci.guti.gummei.plmn; - usim_data->epsloci.tai.tac = DEFAULT_TAC; - usim_data->epsloci.status = USIM_EPSLOCI_UPDATED; - /* - * Non-Access Stratum configuration - */ - usim_data->nasconfig.NAS_SignallingPriority.type = - USIM_NAS_SIGNALLING_PRIORITY_TAG; - usim_data->nasconfig.NAS_SignallingPriority.length = 1; - usim_data->nasconfig.NAS_SignallingPriority.value[0] = 0x00; - usim_data->nasconfig.NMO_I_Behaviour.type = USIM_NMO_I_BEHAVIOUR_TAG; - usim_data->nasconfig.NMO_I_Behaviour.length = 1; - usim_data->nasconfig.NMO_I_Behaviour.value[0] = 0x00; - usim_data->nasconfig.AttachWithImsi.type = USIM_ATTACH_WITH_IMSI_TAG; - usim_data->nasconfig.AttachWithImsi.length = 1; -#if defined(START_WITH_GUTI) - usim_data->nasconfig.AttachWithImsi.value[0] = 0x00; -#else - usim_data->nasconfig.AttachWithImsi.value[0] = 0x01; -#endif - usim_data->nasconfig.MinimumPeriodicSearchTimer.type = - USIM_MINIMUM_PERIODIC_SEARCH_TIMER_TAG; - usim_data->nasconfig.MinimumPeriodicSearchTimer.length = 1; - usim_data->nasconfig.MinimumPeriodicSearchTimer.value[0] = 0x00; - usim_data->nasconfig.ExtendedAccessBarring.type = - USIM_EXTENDED_ACCESS_BARRING_TAG; - usim_data->nasconfig.ExtendedAccessBarring.length = 1; - usim_data->nasconfig.ExtendedAccessBarring.value[0] = 0x00; - usim_data->nasconfig.Timer_T3245_Behaviour.type = - USIM_TIMER_T3245_BEHAVIOUR_TAG; - usim_data->nasconfig.Timer_T3245_Behaviour.length = 1; - usim_data->nasconfig.Timer_T3245_Behaviour.value[0] = 0x00; - - /* initialize the subscriber authentication security key */ - hex_string_to_hex_value(usim_data->keys.usim_api_k, - usim_api_k, USIM_API_K_SIZE); - hex_string_to_hex_value(usim_data->keys.opc, opc, - OPC_SIZE); -} - -int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ - int rc; - char *filename = make_filename(directory, USIM_API_NVRAM_FILENAME, user_id); - rc = usim_api_write(filename, usim_data); - free(filename); - return rc; -} - int parse_plmn_param(config_setting_t *plmn_setting, int index) { int rc = 0; @@ -488,14 +227,17 @@ int parse_plmns(config_setting_t *all_plmn_setting) { return rc; } -int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id) { +int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char **h) { int rc = EXIT_SUCCESS; + const char *hplmn; config_setting_t *setting = NULL; - rc = config_setting_lookup_string(ue_setting, HPLMN, &hplmn); + rc = config_setting_lookup_string(ue_setting, HPLMN, h); if (rc != 1) { printf("Check HPLMN section for UE%d. Exiting\n", user_id); return EXIT_FAILURE; - } else if (get_plmn_index(hplmn) == -1) { + } + hplmn = *h; + if (get_plmn_index(hplmn) == -1) { printf("HPLMN for UE%d is not defined in PLMN section. Exiting\n", user_id); return EXIT_FAILURE; @@ -553,39 +295,6 @@ int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id) { return EXIT_SUCCESS; } -int parse_ue_sim_param(config_setting_t *ue_setting, int user_id) { - int rc = EXIT_SUCCESS; - config_setting_t *ue_param_setting = NULL; - ue_param_setting = config_setting_get_member(ue_setting, SIM); - if (ue_param_setting == NULL) { - printf("Check SIM section for UE%d. EXITING...\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, MSIN, &msin); - if (rc != 1 || strlen(msin) > 10 || strlen(msin) < 9) { - printf("Check SIM MSIN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, USIM_API_K, - &usim_api_k); - if (rc != 1) { - printf("Check SIM USIM_API_K section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, OPC, &opc); - if (rc != 1) { - printf("Check SIM OPC section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(ue_param_setting, MSISDN, &msisdn); - if (rc != 1) { - printf("Check SIM MSISDN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} - - int fill_ucplmn(config_setting_t* setting, int user_id) { int rc; ucplmn_nb = config_setting_length(setting); diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index cb2b31a4ff..7ae326bf1c 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -6,7 +6,7 @@ #include "usim_api.h" #define UE "UE" -#define SIM "SIM" + #define PLMN "PLMN" #define FULLNAME "FULLNAME" @@ -14,16 +14,6 @@ #define MNC "MNC" #define MCC "MCC" -#define MSIN "MSIN" -#define USIM_API_K "USIM_API_K" -#define OPC "OPC" -#define MSISDN "MSISDN" - -#define UE_IMEI "IMEI" -#define MANUFACTURER "MANUFACTURER" -#define MODEL "MODEL" -#define PINCODE "PIN" - #define HPLMN "HPLMN" #define UCPLMN "UCPLMN_LIST" #define OPLMN "OPLMN_LIST" @@ -31,26 +21,9 @@ #define FPLMN "FPLMN_LIST" #define EHPLMN "EHPLMN_LIST" -#define KSI USIM_KSI_NOT_AVAILABLE - -#define KSI_ASME USIM_KSI_NOT_AVAILABLE -#define INT_ALGO USIM_INT_EIA1 -#define ENC_ALGO USIM_ENC_EEA0 -#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO) -#define OPC_SIZE 16 #define MIN_TAC 0x0000 #define MAX_TAC 0xFFFE -#define DEFAULT_TMSI 0x0000000D -#define DEFAULT_P_TMSI 0x0000000D -#define DEFAULT_M_TMSI 0x0000000D -#define DEFAULT_LAC 0xFFFE -#define DEFAULT_RAC 0x01 -#define DEFAULT_TAC 0x0001 - -#define DEFAULT_MME_ID 0x0102 -#define DEFAULT_MME_CODE 0x0F - /* * PLMN network operator record */ @@ -70,12 +43,6 @@ typedef struct { const char *mcc; } plmn_conf_param_t; -extern const char *msin; -extern const char *usim_api_k; -extern const char *msisdn; -extern const char *opc; -extern const char *hplmn; - extern int *ucplmn; extern int *oplmn; extern int *ocplmn; @@ -99,14 +66,10 @@ int parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); void fill_network_record_list(void); -int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); -void gen_usim_data(usim_data_t *usim_data); - -int parse_ue_sim_param(config_setting_t *ue_setting, int user_id); int parse_plmn_param(config_setting_t *plmn_setting, int index); int parse_plmns(config_setting_t *all_plmn_setting); int get_plmn_index(const char * mccmnc); -int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id); +int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char **hplmn); int fill_ucplmn(config_setting_t* setting, int use_id); int fill_oplmn(config_setting_t* setting, int use_id); int fill_ocplmn(config_setting_t* setting, int use_id); diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c index a46fc5d59b..ad877e32ef 100644 --- a/openair3/NAS/TOOLS/conf_emm.c +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -5,7 +5,7 @@ #include "conf_emm.h" #include "fs.h" -void gen_emm_data(emm_nvdata_t *emm_data) { +void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin) { hplmn_index = get_plmn_index(hplmn); memset(emm_data, 0, sizeof(emm_nvdata_t)); int hplmn_index = get_plmn_index(hplmn); diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h index ddb920f5b5..80562aba55 100644 --- a/openair3/NAS/TOOLS/conf_emm.h +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -3,7 +3,7 @@ #include "emmData.h" -void gen_emm_data(emm_nvdata_t *emm_data); +void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin); int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); int get_msin_parity(const char * msin); diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c new file mode 100644 index 0000000000..ee8ed8e0d0 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -0,0 +1,301 @@ +#include +#include + +#include "userDef.h" +#include "utils.h" +#include "conf_emm.h" +#include "fs.h" +#include "conf_usim.h" +#include "conf2uedata.h" + +int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u) { + int rc = EXIT_SUCCESS; + config_setting_t *ue_param_setting = NULL; + ue_param_setting = config_setting_get_member(ue_setting, SIM); + if (ue_param_setting == NULL) { + printf("Check SIM section for UE%d. EXITING...\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MSIN, &u->msin); + if (rc != 1 || strlen(u->msin) > 10 || strlen(u->msin) < 9) { + printf("Check SIM MSIN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, USIM_API_K, + &u->usim_api_k); + if (rc != 1) { + printf("Check SIM USIM_API_K section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, OPC, &u->opc); + if (rc != 1) { + printf("Check SIM OPC section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + rc = config_setting_lookup_string(ue_param_setting, MSISDN, &u->msisdn); + if (rc != 1) { + printf("Check SIM MSISDN section for UE%d. Exiting\n", user_id); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { + memset(usim_data, 0, sizeof(usim_data_t)); + usim_data->imsi.length = 8; + usim_data->imsi.u.num.parity = get_msin_parity(u->msin); + + usim_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; + usim_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; + usim_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + + usim_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; + usim_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; + + if (strlen(user_plmn_list[hplmn_index].mnc) == 2) { + usim_data->imsi.u.num.digit6 = u->msin[0]; + usim_data->imsi.u.num.digit7 = u->msin[1]; + usim_data->imsi.u.num.digit8 = u->msin[2]; + usim_data->imsi.u.num.digit9 = u->msin[3]; + usim_data->imsi.u.num.digit10 = u->msin[4]; + usim_data->imsi.u.num.digit11 = u->msin[5]; + usim_data->imsi.u.num.digit12 = u->msin[6]; + usim_data->imsi.u.num.digit13 = u->msin[7]; + usim_data->imsi.u.num.digit14 = u->msin[8]; + usim_data->imsi.u.num.digit15 = u->msin[9]; + } else { + usim_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + usim_data->imsi.u.num.digit7 = u->msin[0]; + usim_data->imsi.u.num.digit8 = u->msin[1]; + usim_data->imsi.u.num.digit9 = u->msin[2]; + usim_data->imsi.u.num.digit10 = u->msin[3]; + usim_data->imsi.u.num.digit11 = u->msin[4]; + usim_data->imsi.u.num.digit12 = u->msin[5]; + usim_data->imsi.u.num.digit13 = u->msin[6]; + usim_data->imsi.u.num.digit14 = u->msin[7]; + usim_data->imsi.u.num.digit15 = u->msin[8]; + } + + /* + * Ciphering and Integrity Keys + */ + usim_data->keys.ksi = KSI; + memset(&usim_data->keys.ck, 0, USIM_CK_SIZE); + memset(&usim_data->keys.ik, 0, USIM_IK_SIZE); + /* + * Higher Priority PLMN search period + */ + usim_data->hpplmn = 0x00; /* Disable timer */ + + /* + * List of Forbidden PLMNs + */ + for (int i = 0; i < USIM_FPLMN_MAX; i++) { + memset(&usim_data->fplmn[i], 0xff, sizeof(plmn_t)); + } + if (fplmn_nb > 0) { + for (int i = 0; i < fplmn_nb; i++) { + usim_data->fplmn[i] = user_network_record_list[fplmn[i]].plmn; + } + } + + /* + * Location Information + */ + usim_data->loci.tmsi = DEFAULT_TMSI; + usim_data->loci.lai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->loci.lai.lac = DEFAULT_LAC; + usim_data->loci.status = USIM_LOCI_NOT_UPDATED; + /* + * Packet Switched Location Information + */ + usim_data->psloci.p_tmsi = DEFAULT_P_TMSI; + usim_data->psloci.signature[0] = 0x01; + usim_data->psloci.signature[1] = 0x02; + usim_data->psloci.signature[2] = 0x03; + usim_data->psloci.rai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->psloci.rai.lac = DEFAULT_LAC; + usim_data->psloci.rai.rac = DEFAULT_RAC; + usim_data->psloci.status = USIM_PSLOCI_NOT_UPDATED; + /* + * Administrative Data + */ + usim_data->ad.UE_Operation_Mode = USIM_NORMAL_MODE; + usim_data->ad.Additional_Info = 0xffff; + usim_data->ad.MNC_Length = strlen(user_plmn_list[hplmn_index].mnc); + /* + * EPS NAS security context + */ + usim_data->securityctx.length = 52; + usim_data->securityctx.KSIasme.type = USIM_KSI_ASME_TAG; + usim_data->securityctx.KSIasme.length = 1; + usim_data->securityctx.KSIasme.value[0] = KSI_ASME; + usim_data->securityctx.Kasme.type = USIM_K_ASME_TAG; + usim_data->securityctx.Kasme.length = USIM_K_ASME_SIZE; + memset(usim_data->securityctx.Kasme.value, 0, + usim_data->securityctx.Kasme.length); + usim_data->securityctx.ulNAScount.type = USIM_UL_NAS_COUNT_TAG; + usim_data->securityctx.ulNAScount.length = USIM_UL_NAS_COUNT_SIZE; + memset(usim_data->securityctx.ulNAScount.value, 0, + usim_data->securityctx.ulNAScount.length); + usim_data->securityctx.dlNAScount.type = USIM_DL_NAS_COUNT_TAG; + usim_data->securityctx.dlNAScount.length = USIM_DL_NAS_COUNT_SIZE; + memset(usim_data->securityctx.dlNAScount.value, 0, + usim_data->securityctx.dlNAScount.length); + usim_data->securityctx.algorithmID.type = USIM_INT_ENC_ALGORITHMS_TAG; + usim_data->securityctx.algorithmID.length = 1; + usim_data->securityctx.algorithmID.value[0] = SECURITY_ALGORITHMS; + /* + * Subcriber's Number + */ + usim_data->msisdn.length = 7; + usim_data->msisdn.number.ext = 1; + usim_data->msisdn.number.ton = MSISDN_TON_UNKNOWKN; + usim_data->msisdn.number.npi = MSISDN_NPI_ISDN_TELEPHONY; + usim_data->msisdn.conf1_record_id = 0xff; /* Not used */ + usim_data->msisdn.ext1_record_id = 0xff; /* Not used */ + int j = 0; + for (int i = 0; i < strlen(u->msisdn); i += 2) { + usim_data->msisdn.number.digit[j].msb = u->msisdn[i]; + j++; + } + j = 0; + for (int i = 1; i < strlen(u->msisdn); i += 2) { + usim_data->msisdn.number.digit[j].lsb = u->msisdn[i]; + j++; + + } + if (strlen(u->msisdn) % 2 == 0) { + for (int i = strlen(u->msisdn) / 2; i < 10; i++) { + usim_data->msisdn.number.digit[i].msb = 0xf; + usim_data->msisdn.number.digit[i].lsb = 0xf; + } + } else { + usim_data->msisdn.number.digit[strlen(u->msisdn) / 2].lsb = 0xf; + for (int i = (strlen(u->msisdn) / 2) + 1; i < 10; i++) { + usim_data->msisdn.number.digit[i].msb = 0xf; + usim_data->msisdn.number.digit[i].lsb = 0xf; + } + } + /* + * PLMN Network Name and Operator PLMN List + */ + for (int i = 0; i < oplmn_nb; i++) { + network_record_t record = user_network_record_list[oplmn[i]]; + usim_data->pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; + usim_data->pnn[i].fullname.length = strlen(record.fullname); + strncpy((char*) usim_data->pnn[i].fullname.value, record.fullname, + usim_data->pnn[i].fullname.length); + usim_data->pnn[i].shortname.type = USIM_PNN_SHORTNAME_TAG; + usim_data->pnn[i].shortname.length = strlen(record.shortname); + strncpy((char*) usim_data->pnn[i].shortname.value, record.shortname, + usim_data->pnn[i].shortname.length); + usim_data->opl[i].plmn = record.plmn; + usim_data->opl[i].start = record.tac_start; + usim_data->opl[i].end = record.tac_end; + usim_data->opl[i].record_id = i; + } + if (oplmn_nb < USIM_OPL_MAX) { + for (int i = oplmn_nb; i < USIM_OPL_MAX; i++) { + memset(&usim_data->opl[i].plmn, 0xff, sizeof(plmn_t)); + } + } + + /* + * List of Equivalent HPLMNs + */ + for (int i = 0; i < ehplmn_nb; i++) { + usim_data->ehplmn[i] = user_network_record_list[ehplmn[i]].plmn; + } + if (ehplmn_nb < USIM_EHPLMN_MAX) { + for (int i = ehplmn_nb; i < USIM_EHPLMN_MAX; i++) { + memset(&usim_data->ehplmn[i], 0xff, sizeof(plmn_t)); + } + } + /* + * Home PLMN Selector with Access Technology + */ + usim_data->hplmn.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); + + /* + * List of user controlled PLMN selector with Access Technology + */ + for (int i = 0; i < USIM_PLMN_MAX; i++) { + memset(&usim_data->plmn[i], 0xff, sizeof(plmn_t)); + } + if (ucplmn_nb > 0) { + for (int i = 0; i < ucplmn_nb; i++) { + usim_data->plmn[i].plmn = user_network_record_list[ucplmn[i]].plmn; + } + } + + // List of operator controlled PLMN selector with Access Technology + + for (int i = 0; i < USIM_OPLMN_MAX; i++) { + memset(&usim_data->oplmn[i], 0xff, sizeof(plmn_t)); + } + if (ocplmn_nb > 0) { + for (int i = 0; i < ocplmn_nb; i++) { + usim_data->oplmn[i].plmn = user_network_record_list[ocplmn[i]].plmn; + usim_data->oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN + | USIM_ACT_EUTRAN); + } + } + /* + * EPS Location Information + */ + usim_data->epsloci.guti.gummei.plmn = + user_network_record_list[hplmn_index].plmn; + usim_data->epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID; + usim_data->epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE; + usim_data->epsloci.guti.m_tmsi = DEFAULT_M_TMSI; + usim_data->epsloci.tai.plmn = usim_data->epsloci.guti.gummei.plmn; + usim_data->epsloci.tai.tac = DEFAULT_TAC; + usim_data->epsloci.status = USIM_EPSLOCI_UPDATED; + /* + * Non-Access Stratum configuration + */ + usim_data->nasconfig.NAS_SignallingPriority.type = + USIM_NAS_SIGNALLING_PRIORITY_TAG; + usim_data->nasconfig.NAS_SignallingPriority.length = 1; + usim_data->nasconfig.NAS_SignallingPriority.value[0] = 0x00; + usim_data->nasconfig.NMO_I_Behaviour.type = USIM_NMO_I_BEHAVIOUR_TAG; + usim_data->nasconfig.NMO_I_Behaviour.length = 1; + usim_data->nasconfig.NMO_I_Behaviour.value[0] = 0x00; + usim_data->nasconfig.AttachWithImsi.type = USIM_ATTACH_WITH_IMSI_TAG; + usim_data->nasconfig.AttachWithImsi.length = 1; +#if defined(START_WITH_GUTI) + usim_data->nasconfig.AttachWithImsi.value[0] = 0x00; +#else + usim_data->nasconfig.AttachWithImsi.value[0] = 0x01; +#endif + usim_data->nasconfig.MinimumPeriodicSearchTimer.type = + USIM_MINIMUM_PERIODIC_SEARCH_TIMER_TAG; + usim_data->nasconfig.MinimumPeriodicSearchTimer.length = 1; + usim_data->nasconfig.MinimumPeriodicSearchTimer.value[0] = 0x00; + usim_data->nasconfig.ExtendedAccessBarring.type = + USIM_EXTENDED_ACCESS_BARRING_TAG; + usim_data->nasconfig.ExtendedAccessBarring.length = 1; + usim_data->nasconfig.ExtendedAccessBarring.value[0] = 0x00; + usim_data->nasconfig.Timer_T3245_Behaviour.type = + USIM_TIMER_T3245_BEHAVIOUR_TAG; + usim_data->nasconfig.Timer_T3245_Behaviour.length = 1; + usim_data->nasconfig.Timer_T3245_Behaviour.value[0] = 0x00; + + /* initialize the subscriber authentication security key */ + hex_string_to_hex_value(usim_data->keys.usim_api_k, + u->usim_api_k, USIM_API_K_SIZE); + hex_string_to_hex_value(usim_data->keys.opc, u->opc, + OPC_SIZE); +} + +int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ + int rc; + char *filename = make_filename(directory, USIM_API_NVRAM_FILENAME, user_id); + rc = usim_api_write(filename, usim_data); + free(filename); + return rc; +} + + diff --git a/openair3/NAS/TOOLS/conf_usim.h b/openair3/NAS/TOOLS/conf_usim.h new file mode 100644 index 0000000000..3375bf9d5d --- /dev/null +++ b/openair3/NAS/TOOLS/conf_usim.h @@ -0,0 +1,45 @@ +#ifndef _CONF_USIM_H +#define _CONF_USIM_H + +#include +#include "usim_api.h" + +#define SIM "SIM" +#define MSIN "MSIN" +#define USIM_API_K "USIM_API_K" +#define OPC "OPC" +#define MSISDN "MSISDN" + +#define KSI USIM_KSI_NOT_AVAILABLE +#define KSI_ASME USIM_KSI_NOT_AVAILABLE + +#define OPC_SIZE 16 + +#define DEFAULT_TMSI 0x0000000D +#define DEFAULT_P_TMSI 0x0000000D +#define DEFAULT_M_TMSI 0x0000000D + +#define DEFAULT_RAC 0x01 +#define DEFAULT_TAC 0x0001 +#define DEFAULT_LAC 0xFFFE + +#define DEFAULT_MME_ID 0x0102 +#define DEFAULT_MME_CODE 0x0F + +#define INT_ALGO USIM_INT_EIA1 +#define ENC_ALGO USIM_ENC_EEA0 +#define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO) + +typedef struct { + const char *msin; + const char *usim_api_k; + const char *msisdn; + const char *opc; + const char *hplmn; +} usim_data_conf_t; + +int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u); +int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); +void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data); + +#endif From 5c8410c56f42a62b6c3981f4c8a8e3bddc75b451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Mon, 22 Aug 2016 15:43:42 +0200 Subject: [PATCH 202/571] fix(conf2uedata): make hplmn_index a local variable There was a side effect corrupting data because hplmn_index was not computed. --- openair3/NAS/TOOLS/conf2uedata.c | 1 - openair3/NAS/TOOLS/conf2uedata.h | 1 - openair3/NAS/TOOLS/conf_emm.c | 9 ++++----- openair3/NAS/TOOLS/conf_emm.h | 2 +- openair3/NAS/TOOLS/conf_usim.c | 5 ++++- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index a3beb27b2d..804c8aecdb 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -18,7 +18,6 @@ int *ocplmn = NULL; int *fplmn = NULL; int *ehplmn = NULL; -int hplmn_index = 0; int plmn_nb = 0; int ucplmn_nb = 0; int oplmn_nb = 0; diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 7ae326bf1c..ed74ccf288 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -49,7 +49,6 @@ extern int *ocplmn; extern int *fplmn; extern int *ehplmn; -extern int hplmn_index; extern int plmn_nb; extern int ucplmn_nb; extern int oplmn_nb; diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c index ad877e32ef..de696592de 100644 --- a/openair3/NAS/TOOLS/conf_emm.c +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -6,11 +6,10 @@ #include "fs.h" void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin) { - hplmn_index = get_plmn_index(hplmn); memset(emm_data, 0, sizeof(emm_nvdata_t)); int hplmn_index = get_plmn_index(hplmn); emm_data->imsi.length = 8; - emm_data->imsi.u.num.parity = get_msin_parity(msin); + emm_data->imsi.u.num.parity = get_msin_parity(msin, user_plmn_list[hplmn_index].mcc, user_plmn_list[hplmn_index].mnc); emm_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; emm_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; emm_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; @@ -69,9 +68,9 @@ int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { return(EXIT_SUCCESS); } -int get_msin_parity(const char * msin) { - int imsi_size = strlen(msin) + strlen(user_plmn_list[hplmn_index].mcc) - + strlen(user_plmn_list[hplmn_index].mnc); +int get_msin_parity(const char * msin, const char *mcc, const char *mnc) { + int imsi_size = strlen(msin) + strlen(mcc) + + strlen(mnc); int result = (imsi_size % 2 == 0) ? 0 : 1; return result; diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h index 80562aba55..996e63ca05 100644 --- a/openair3/NAS/TOOLS/conf_emm.h +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -5,6 +5,6 @@ void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin); int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); -int get_msin_parity(const char * msin); +int get_msin_parity(const char * msin, const char *mcc, const char *mnc); #endif diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c index ee8ed8e0d0..345309996f 100644 --- a/openair3/NAS/TOOLS/conf_usim.c +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -41,9 +41,12 @@ int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf } void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { + int hplmn_index = get_plmn_index(u->hplmn); memset(usim_data, 0, sizeof(usim_data_t)); usim_data->imsi.length = 8; - usim_data->imsi.u.num.parity = get_msin_parity(u->msin); + usim_data->imsi.u.num.parity = get_msin_parity(u->msin, + user_plmn_list[hplmn_index].mcc, + user_plmn_list[hplmn_index].mnc); usim_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; usim_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; From fcb857e50830a0860655a2f86807e2b8dc2b2bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 23 Aug 2016 11:58:29 +0200 Subject: [PATCH 203/571] refactor(conf2uedata): add parse_Xplmn() to read *plmns --- openair3/NAS/TOOLS/conf2uedata.c | 174 +++++++------------------------ openair3/NAS/TOOLS/conf2uedata.h | 8 +- 2 files changed, 38 insertions(+), 144 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 804c8aecdb..a9eb8ef797 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -227,11 +227,10 @@ int parse_plmns(config_setting_t *all_plmn_setting) { } int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char **h) { - int rc = EXIT_SUCCESS; + int nb_errors = 0; const char *hplmn; - config_setting_t *setting = NULL; - rc = config_setting_lookup_string(ue_setting, HPLMN, h); - if (rc != 1) { + + if ( config_setting_lookup_string(ue_setting, HPLMN, h) != 1 ) { printf("Check HPLMN section for UE%d. Exiting\n", user_id); return EXIT_FAILURE; } @@ -241,67 +240,41 @@ int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char ** user_id); return EXIT_FAILURE; } - setting = config_setting_get_member(ue_setting, UCPLMN); - if (setting == NULL) { - printf("Check UCPLMN section for UE%d. Exiting\n", user_id); + + if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &ucplmn_nb, &ucplmn) == EXIT_FAILURE ) + nb_errors++; + if ( parse_Xplmn(ue_setting, OPLMN, user_id, &oplmn_nb, &oplmn) == EXIT_FAILURE ) + nb_errors++; + if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &ocplmn_nb, &ocplmn) == EXIT_FAILURE ) + nb_errors++; + if ( parse_Xplmn(ue_setting, FPLMN, user_id, &fplmn_nb, &fplmn) == EXIT_FAILURE ) + nb_errors++; + if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &ehplmn_nb, &ehplmn) == EXIT_FAILURE ) + nb_errors++; + + if ( nb_errors > 0 ) return EXIT_FAILURE; - } - rc = fill_ucplmn(setting, user_id); - if (rc != EXIT_SUCCESS) { - printf("Check UCPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - setting = config_setting_get_member(ue_setting, OPLMN); - if (setting == NULL) { - printf("Check OPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = fill_oplmn(setting, user_id); - if (rc != EXIT_SUCCESS) { - printf("Check OPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - setting = config_setting_get_member(ue_setting, OCPLMN); - if (setting == NULL) { - printf("Check OCPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = fill_ocplmn(setting, user_id); - if (rc != EXIT_SUCCESS) { - printf("Check OCPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - setting = config_setting_get_member(ue_setting, FPLMN); - if (setting == NULL) { - printf("Check FPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = fill_fplmn(setting, user_id); - if (rc != EXIT_SUCCESS) { - printf("Check FPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - setting = config_setting_get_member(ue_setting, EHPLMN); - if (setting == NULL) { - printf("Check EHPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = fill_ehplmn(setting, user_id); - if (rc != EXIT_SUCCESS) { - printf("Check EHPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } return EXIT_SUCCESS; } -int fill_ucplmn(config_setting_t* setting, int user_id) { +int parse_Xplmn(config_setting_t *ue_setting, const char *section, + int user_id, int *plmns_count, int **plmns ) { int rc; - ucplmn_nb = config_setting_length(setting); - ucplmn = malloc(ucplmn_nb * sizeof(int)); - for (int i = 0; i < ucplmn_nb; i++) { + int item_count; + config_setting_t *setting; + + setting = config_setting_get_member(ue_setting, section); + if (setting == NULL) { + printf("Check %s section for UE%d. Exiting\n", section, user_id); + return EXIT_FAILURE; + } + + item_count = config_setting_length(setting); + int *datas = malloc(item_count * sizeof(int)); + for (int i = 0; i < item_count; i++) { const char *mccmnc = config_setting_get_string_elem(setting, i); if (mccmnc == NULL) { - printf("Check UCPLMN section for UE%d. Exiting\n", user_id); + printf("Check %s section for UE%d. Exiting\n", section, user_id); return EXIT_FAILURE; } rc = get_plmn_index(mccmnc); @@ -310,88 +283,11 @@ int fill_ucplmn(config_setting_t* setting, int user_id) { mccmnc); return EXIT_FAILURE; } - ucplmn[i] = rc; - } - return EXIT_SUCCESS; -} -int fill_oplmn(config_setting_t* setting, int user_id) { - int rc; - oplmn_nb = config_setting_length(setting); - oplmn = malloc(oplmn_nb * sizeof(int)); - for (int i = 0; i < oplmn_nb; i++) { - const char *mccmnc = config_setting_get_string_elem(setting, i); - if (mccmnc == NULL) { - printf("Check OPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = get_plmn_index(mccmnc); - if (rc == -1) { - printf("The PLMN %s is not defined in PLMN section. Exiting...\n", - mccmnc); - return EXIT_FAILURE; - } - oplmn[i] = rc; - } - return EXIT_SUCCESS; -} -int fill_ocplmn(config_setting_t* setting, int user_id) { - int rc; - ocplmn_nb = config_setting_length(setting); - ocplmn = malloc(ocplmn_nb * sizeof(int)); - for (int i = 0; i < ocplmn_nb; i++) { - const char *mccmnc = config_setting_get_string_elem(setting, i); - if (mccmnc == NULL) { - printf("Check OCPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = get_plmn_index(mccmnc); - if (rc == -1) { - printf("The PLMN %s is not defined in PLMN section. Exiting...\n", - mccmnc); - return EXIT_FAILURE; - } - ocplmn[i] = rc; - } - return EXIT_SUCCESS; -} -int fill_fplmn(config_setting_t* setting, int user_id) { - int rc; - fplmn_nb = config_setting_length(setting); - fplmn = malloc(fplmn_nb * sizeof(int)); - for (int i = 0; i < fplmn_nb; i++) { - const char *mccmnc = config_setting_get_string_elem(setting, i); - if (mccmnc == NULL) { - printf("Check FPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = get_plmn_index(mccmnc); - if (rc == -1) { - printf("The PLMN %s is not defined in PLMN section. Exiting...\n", - mccmnc); - return EXIT_FAILURE; - } - fplmn[i] = rc; - } - return EXIT_SUCCESS; -} -int fill_ehplmn(config_setting_t* setting, int user_id) { - int rc; - ehplmn_nb = config_setting_length(setting); - ehplmn = malloc(ehplmn_nb * sizeof(int)); - for (int i = 0; i < ehplmn_nb; i++) { - const char *mccmnc = config_setting_get_string_elem(setting, i); - if (mccmnc == NULL) { - printf("Check EHPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - rc = get_plmn_index(mccmnc); - if (rc == -1) { - printf("The PLMN %s is not defined in PLMN section. Exiting...\n", - mccmnc); - return EXIT_FAILURE; - } - ehplmn[i] = rc; + datas[i] = rc; } + + *plmns_count = item_count; + *plmns = datas; return EXIT_SUCCESS; } diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index ed74ccf288..9fd1cb53a9 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -69,10 +69,8 @@ int parse_plmn_param(config_setting_t *plmn_setting, int index); int parse_plmns(config_setting_t *all_plmn_setting); int get_plmn_index(const char * mccmnc); int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char **hplmn); -int fill_ucplmn(config_setting_t* setting, int use_id); -int fill_oplmn(config_setting_t* setting, int use_id); -int fill_ocplmn(config_setting_t* setting, int use_id); -int fill_fplmn(config_setting_t* setting, int use_id); -int fill_ehplmn(config_setting_t* setting, int use_id); +int parse_Xplmn(config_setting_t *ue_setting, const char *section, + int user_id, int *plmns_count, int **plmns ); + #endif // _CONF2UEDATA_H From c86b437eb31af9594ea5646a4eb5927e5111e189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 23 Aug 2016 13:39:07 +0200 Subject: [PATCH 204/571] refactor(conf2uedata): make plmns_list struct for managing plmns --- openair3/NAS/TOOLS/conf2uedata.c | 31 ++++++++++++----------------- openair3/NAS/TOOLS/conf2uedata.h | 22 ++++++++++----------- openair3/NAS/TOOLS/conf_emm.c | 2 +- openair3/NAS/TOOLS/conf_usim.c | 34 ++++++++++++++++---------------- 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index a9eb8ef797..3a783c2fe3 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -12,18 +12,13 @@ #include "conf_user_data.h" #include "conf_usim.h" -int *ucplmn = NULL; -int *oplmn = NULL; -int *ocplmn = NULL; -int *fplmn = NULL; -int *ehplmn = NULL; +plmns_list ucplmns; +plmns_list oplmns; +plmns_list ocplmns; +plmns_list fplmns; +plmns_list ehplmns; int plmn_nb = 0; -int ucplmn_nb = 0; -int oplmn_nb = 0; -int ocplmn_nb = 0; -int fplmn_nb = 0; -int ehplmn_nb = 0; plmn_conf_param_t* user_plmn_list=NULL; network_record_t* user_network_record_list = NULL; @@ -241,15 +236,15 @@ int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char ** return EXIT_FAILURE; } - if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &ucplmn_nb, &ucplmn) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &ucplmns) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, OPLMN, user_id, &oplmn_nb, &oplmn) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, OPLMN, user_id, &oplmns) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &ocplmn_nb, &ocplmn) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &ocplmns) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, FPLMN, user_id, &fplmn_nb, &fplmn) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, FPLMN, user_id, &fplmns) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &ehplmn_nb, &ehplmn) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &ehplmns) == EXIT_FAILURE ) nb_errors++; if ( nb_errors > 0 ) @@ -258,7 +253,7 @@ int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char ** } int parse_Xplmn(config_setting_t *ue_setting, const char *section, - int user_id, int *plmns_count, int **plmns ) { + int user_id, plmns_list *plmns) { int rc; int item_count; config_setting_t *setting; @@ -286,8 +281,8 @@ int parse_Xplmn(config_setting_t *ue_setting, const char *section, datas[i] = rc; } - *plmns_count = item_count; - *plmns = datas; + plmns->size = item_count; + plmns->items = datas; return EXIT_SUCCESS; } diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 9fd1cb53a9..64a182af75 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -43,18 +43,18 @@ typedef struct { const char *mcc; } plmn_conf_param_t; -extern int *ucplmn; -extern int *oplmn; -extern int *ocplmn; -extern int *fplmn; -extern int *ehplmn; +typedef struct { + int size; + int *items; +} plmns_list; + +extern plmns_list ucplmns; +extern plmns_list oplmns; +extern plmns_list ocplmns; +extern plmns_list fplmns; +extern plmns_list ehplmns; extern int plmn_nb; -extern int ucplmn_nb; -extern int oplmn_nb; -extern int ocplmn_nb; -extern int fplmn_nb; -extern int ehplmn_nb; extern plmn_conf_param_t* user_plmn_list; extern network_record_t* user_network_record_list; @@ -70,7 +70,7 @@ int parse_plmns(config_setting_t *all_plmn_setting); int get_plmn_index(const char * mccmnc); int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char **hplmn); int parse_Xplmn(config_setting_t *ue_setting, const char *section, - int user_id, int *plmns_count, int **plmns ); + int user_id, plmns_list *plmns); #endif // _CONF2UEDATA_H diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c index de696592de..ca9665e6d6 100644 --- a/openair3/NAS/TOOLS/conf_emm.c +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -53,7 +53,7 @@ void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin) { emm_data->rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; emm_data->rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; - emm_data->eplmn.n_plmns = ehplmn_nb; + emm_data->eplmn.n_plmns = ehplmns.size; } int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c index 345309996f..9161041862 100644 --- a/openair3/NAS/TOOLS/conf_usim.c +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -96,9 +96,9 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { for (int i = 0; i < USIM_FPLMN_MAX; i++) { memset(&usim_data->fplmn[i], 0xff, sizeof(plmn_t)); } - if (fplmn_nb > 0) { - for (int i = 0; i < fplmn_nb; i++) { - usim_data->fplmn[i] = user_network_record_list[fplmn[i]].plmn; + if (fplmns.size > 0) { + for (int i = 0; i < fplmns.size; i++) { + usim_data->fplmn[i] = user_network_record_list[fplmns.items[i]].plmn; } } @@ -183,8 +183,8 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { /* * PLMN Network Name and Operator PLMN List */ - for (int i = 0; i < oplmn_nb; i++) { - network_record_t record = user_network_record_list[oplmn[i]]; + for (int i = 0; i < oplmns.size; i++) { + network_record_t record = user_network_record_list[oplmns.items[i]]; usim_data->pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; usim_data->pnn[i].fullname.length = strlen(record.fullname); strncpy((char*) usim_data->pnn[i].fullname.value, record.fullname, @@ -198,8 +198,8 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { usim_data->opl[i].end = record.tac_end; usim_data->opl[i].record_id = i; } - if (oplmn_nb < USIM_OPL_MAX) { - for (int i = oplmn_nb; i < USIM_OPL_MAX; i++) { + if (oplmns.size < USIM_OPL_MAX) { + for (int i = oplmns.size; i < USIM_OPL_MAX; i++) { memset(&usim_data->opl[i].plmn, 0xff, sizeof(plmn_t)); } } @@ -207,11 +207,11 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { /* * List of Equivalent HPLMNs */ - for (int i = 0; i < ehplmn_nb; i++) { - usim_data->ehplmn[i] = user_network_record_list[ehplmn[i]].plmn; + for (int i = 0; i < ehplmns.size; i++) { + usim_data->ehplmn[i] = user_network_record_list[ehplmns.items[i]].plmn; } - if (ehplmn_nb < USIM_EHPLMN_MAX) { - for (int i = ehplmn_nb; i < USIM_EHPLMN_MAX; i++) { + if (ehplmns.size < USIM_EHPLMN_MAX) { + for (int i = ehplmns.size; i < USIM_EHPLMN_MAX; i++) { memset(&usim_data->ehplmn[i], 0xff, sizeof(plmn_t)); } } @@ -227,9 +227,9 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { for (int i = 0; i < USIM_PLMN_MAX; i++) { memset(&usim_data->plmn[i], 0xff, sizeof(plmn_t)); } - if (ucplmn_nb > 0) { - for (int i = 0; i < ucplmn_nb; i++) { - usim_data->plmn[i].plmn = user_network_record_list[ucplmn[i]].plmn; + if (ucplmns.size > 0) { + for (int i = 0; i < ucplmns.size; i++) { + usim_data->plmn[i].plmn = user_network_record_list[ucplmns.items[i]].plmn; } } @@ -238,9 +238,9 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { for (int i = 0; i < USIM_OPLMN_MAX; i++) { memset(&usim_data->oplmn[i], 0xff, sizeof(plmn_t)); } - if (ocplmn_nb > 0) { - for (int i = 0; i < ocplmn_nb; i++) { - usim_data->oplmn[i].plmn = user_network_record_list[ocplmn[i]].plmn; + if (ocplmns.size > 0) { + for (int i = 0; i < ocplmns.size; i++) { + usim_data->oplmn[i].plmn = user_network_record_list[ocplmns.items[i]].plmn; usim_data->oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); } From 459a6ec37233cd9ff24d689739b81f4b8d5ccbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 23 Aug 2016 14:46:25 +0200 Subject: [PATCH 205/571] refactor(conf2uedata): use user_plmns struct to store plmns lists This remove the old static lists --- openair3/NAS/TOOLS/conf2uedata.c | 27 ++++++++++------------ openair3/NAS/TOOLS/conf2uedata.h | 15 +++++++----- openair3/NAS/TOOLS/conf_emm.c | 4 ++-- openair3/NAS/TOOLS/conf_emm.h | 3 ++- openair3/NAS/TOOLS/conf_usim.c | 39 ++++++++++++++++---------------- openair3/NAS/TOOLS/conf_usim.h | 3 ++- 6 files changed, 47 insertions(+), 44 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 3a783c2fe3..2e9317dc1c 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -12,12 +12,6 @@ #include "conf_user_data.h" #include "conf_usim.h" -plmns_list ucplmns; -plmns_list oplmns; -plmns_list ocplmns; -plmns_list fplmns; -plmns_list ehplmns; - int plmn_nb = 0; plmn_conf_param_t* user_plmn_list=NULL; @@ -106,6 +100,8 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { usim_data_t usim_data; usim_data_conf_t usim_data_conf; + user_plmns_t user_plmns; + sprintf(user, "%s%d", UE, i); ue_setting = config_setting_get_member(root_setting, user); @@ -114,7 +110,7 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { return EXIT_FAILURE; } - rc = parse_ue_plmn_param(ue_setting, i, &usim_data_conf.hplmn); + rc = parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn); if (rc != EXIT_SUCCESS) { return EXIT_FAILURE; } @@ -132,10 +128,10 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { printf("Problem in SIM section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } - gen_usim_data(&usim_data_conf, &usim_data); + gen_usim_data(&usim_data_conf, &usim_data, &user_plmns); write_usim_data(output_dir, i, &usim_data); - gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin); + gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, user_plmns.equivalents_home.size); write_emm_data(output_dir, i, &emm_data); } @@ -221,7 +217,8 @@ int parse_plmns(config_setting_t *all_plmn_setting) { return rc; } -int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char **h) { +int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, + user_plmns_t *user_plmns, const char **h) { int nb_errors = 0; const char *hplmn; @@ -236,15 +233,15 @@ int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char ** return EXIT_FAILURE; } - if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &ucplmns) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &user_plmns->users_controlled) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, OPLMN, user_id, &oplmns) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, OPLMN, user_id, &user_plmns->operators) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &ocplmns) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &user_plmns->operators_controlled) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, FPLMN, user_id, &fplmns) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, FPLMN, user_id, &user_plmns->forbiddens) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &ehplmns) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &user_plmns->equivalents_home) == EXIT_FAILURE ) nb_errors++; if ( nb_errors > 0 ) diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 64a182af75..21cc2c3fbd 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -48,11 +48,13 @@ typedef struct { int *items; } plmns_list; -extern plmns_list ucplmns; -extern plmns_list oplmns; -extern plmns_list ocplmns; -extern plmns_list fplmns; -extern plmns_list ehplmns; +typedef struct { + plmns_list users_controlled; + plmns_list operators; + plmns_list operators_controlled; + plmns_list forbiddens; + plmns_list equivalents_home; +} user_plmns_t; extern int plmn_nb; @@ -68,7 +70,8 @@ void fill_network_record_list(void); int parse_plmn_param(config_setting_t *plmn_setting, int index); int parse_plmns(config_setting_t *all_plmn_setting); int get_plmn_index(const char * mccmnc); -int parse_ue_plmn_param(config_setting_t *ue_setting, int user_id, const char **hplmn); +int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, + user_plmns_t *user_plmns, const char **h); int parse_Xplmn(config_setting_t *ue_setting, const char *section, int user_id, plmns_list *plmns); diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c index ca9665e6d6..bc9f3441ae 100644 --- a/openair3/NAS/TOOLS/conf_emm.c +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -5,7 +5,7 @@ #include "conf_emm.h" #include "fs.h" -void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin) { +void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count) { memset(emm_data, 0, sizeof(emm_nvdata_t)); int hplmn_index = get_plmn_index(hplmn); emm_data->imsi.length = 8; @@ -53,7 +53,7 @@ void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin) { emm_data->rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; emm_data->rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; - emm_data->eplmn.n_plmns = ehplmns.size; + emm_data->eplmn.n_plmns = ehplmn_count; } int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h index 996e63ca05..c405e02612 100644 --- a/openair3/NAS/TOOLS/conf_emm.h +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -3,7 +3,8 @@ #include "emmData.h" -void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin); +void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, + int ehplmn_count); int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); int get_msin_parity(const char * msin, const char *mcc, const char *mnc); diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c index 9161041862..8b1a80ad52 100644 --- a/openair3/NAS/TOOLS/conf_usim.c +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -5,8 +5,8 @@ #include "utils.h" #include "conf_emm.h" #include "fs.h" -#include "conf_usim.h" #include "conf2uedata.h" +#include "conf_usim.h" int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u) { int rc = EXIT_SUCCESS; @@ -40,7 +40,8 @@ int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf return EXIT_SUCCESS; } -void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { +void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, + const user_plmns_t *user_plmns) { int hplmn_index = get_plmn_index(u->hplmn); memset(usim_data, 0, sizeof(usim_data_t)); usim_data->imsi.length = 8; @@ -96,9 +97,9 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { for (int i = 0; i < USIM_FPLMN_MAX; i++) { memset(&usim_data->fplmn[i], 0xff, sizeof(plmn_t)); } - if (fplmns.size > 0) { - for (int i = 0; i < fplmns.size; i++) { - usim_data->fplmn[i] = user_network_record_list[fplmns.items[i]].plmn; + if (user_plmns->forbiddens.size > 0) { + for (int i = 0; i < user_plmns->forbiddens.size; i++) { + usim_data->fplmn[i] = user_network_record_list[user_plmns->forbiddens.items[i]].plmn; } } @@ -183,8 +184,8 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { /* * PLMN Network Name and Operator PLMN List */ - for (int i = 0; i < oplmns.size; i++) { - network_record_t record = user_network_record_list[oplmns.items[i]]; + for (int i = 0; i < user_plmns->operators.size; i++) { + network_record_t record = user_network_record_list[user_plmns->operators.items[i]]; usim_data->pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; usim_data->pnn[i].fullname.length = strlen(record.fullname); strncpy((char*) usim_data->pnn[i].fullname.value, record.fullname, @@ -198,8 +199,8 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { usim_data->opl[i].end = record.tac_end; usim_data->opl[i].record_id = i; } - if (oplmns.size < USIM_OPL_MAX) { - for (int i = oplmns.size; i < USIM_OPL_MAX; i++) { + if (user_plmns->operators.size < USIM_OPL_MAX) { + for (int i = user_plmns->operators.size; i < USIM_OPL_MAX; i++) { memset(&usim_data->opl[i].plmn, 0xff, sizeof(plmn_t)); } } @@ -207,11 +208,11 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { /* * List of Equivalent HPLMNs */ - for (int i = 0; i < ehplmns.size; i++) { - usim_data->ehplmn[i] = user_network_record_list[ehplmns.items[i]].plmn; + for (int i = 0; i < user_plmns->equivalents_home.size; i++) { + usim_data->ehplmn[i] = user_network_record_list[user_plmns->equivalents_home.items[i]].plmn; } - if (ehplmns.size < USIM_EHPLMN_MAX) { - for (int i = ehplmns.size; i < USIM_EHPLMN_MAX; i++) { + if (user_plmns->equivalents_home.size < USIM_EHPLMN_MAX) { + for (int i = user_plmns->equivalents_home.size; i < USIM_EHPLMN_MAX; i++) { memset(&usim_data->ehplmn[i], 0xff, sizeof(plmn_t)); } } @@ -227,9 +228,9 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { for (int i = 0; i < USIM_PLMN_MAX; i++) { memset(&usim_data->plmn[i], 0xff, sizeof(plmn_t)); } - if (ucplmns.size > 0) { - for (int i = 0; i < ucplmns.size; i++) { - usim_data->plmn[i].plmn = user_network_record_list[ucplmns.items[i]].plmn; + if (user_plmns->users_controlled.size > 0) { + for (int i = 0; i < user_plmns->users_controlled.size; i++) { + usim_data->plmn[i].plmn = user_network_record_list[user_plmns->users_controlled.items[i]].plmn; } } @@ -238,9 +239,9 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data) { for (int i = 0; i < USIM_OPLMN_MAX; i++) { memset(&usim_data->oplmn[i], 0xff, sizeof(plmn_t)); } - if (ocplmns.size > 0) { - for (int i = 0; i < ocplmns.size; i++) { - usim_data->oplmn[i].plmn = user_network_record_list[ocplmns.items[i]].plmn; + if (user_plmns->operators_controlled.size > 0) { + for (int i = 0; i < user_plmns->operators_controlled.size; i++) { + usim_data->oplmn[i].plmn = user_network_record_list[user_plmns->operators_controlled.items[i]].plmn; usim_data->oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); } diff --git a/openair3/NAS/TOOLS/conf_usim.h b/openair3/NAS/TOOLS/conf_usim.h index 3375bf9d5d..5018be8148 100644 --- a/openair3/NAS/TOOLS/conf_usim.h +++ b/openair3/NAS/TOOLS/conf_usim.h @@ -40,6 +40,7 @@ typedef struct { int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u); int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); -void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data); +void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, + const user_plmns_t *user_plmns); #endif From 8d36213f6ff1cedf6814948f898c62e15b448640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 23 Aug 2016 15:55:35 +0200 Subject: [PATCH 206/571] refactor(conf2uedata): add make_plmn_from_conf() --- openair3/NAS/TOOLS/conf2uedata.c | 33 ++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 2e9317dc1c..197c639454 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -300,27 +300,40 @@ int get_plmn_index(const char * mccmnc) { return -1; } + +plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) { + plmn_t plmn; + char num[6]; + + memset(&plmn, 0xff, sizeof(plmn)); + + snprintf(num, 6, "%s%s", plmn_conf->mcc, plmn_conf->mnc); + + plmn.MCCdigit2 = plmn_conf->mcc[1]; + plmn.MCCdigit1 = plmn_conf->mcc[0]; + plmn.MCCdigit3 = plmn_conf->mcc[2]; + plmn.MNCdigit2 = plmn_conf->mnc[1]; + plmn.MNCdigit1 = plmn_conf->mnc[0]; + if (strlen(plmn_conf->mnc) > 2) { + plmn.MNCdigit3 = plmn_conf->mnc[2]; + } + return plmn; +} + void fill_network_record_list() { for (int i = 0; i < plmn_nb; i++) { strcpy(user_network_record_list[i].fullname, user_plmn_list[i].fullname); strcpy(user_network_record_list[i].shortname, user_plmn_list[i].shortname); + char num[6]; sprintf(num, "%s%s", user_plmn_list[i].mcc, user_plmn_list[i].mnc); user_network_record_list[i].num = atoi(num); - user_network_record_list[i].plmn.MCCdigit2 = user_plmn_list[i].mcc[1]; - user_network_record_list[i].plmn.MCCdigit1 = user_plmn_list[i].mcc[0]; - user_network_record_list[i].plmn.MCCdigit3 = user_plmn_list[i].mcc[2]; - user_network_record_list[i].plmn.MNCdigit2 = user_plmn_list[i].mnc[1]; - user_network_record_list[i].plmn.MNCdigit1 = user_plmn_list[i].mnc[0]; + + user_network_record_list[i].plmn = make_plmn_from_conf(&user_plmn_list[i]); user_network_record_list[i].tac_end = 0xfffd; user_network_record_list[i].tac_start = 0x0001; - if (strlen(user_plmn_list[i].mnc) > 2) { - user_network_record_list[i].plmn.MNCdigit3 = - user_plmn_list[i].mnc[2]; - } - } } From 1b54e18a47524e09b04f482c72eb878e0a80c943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 23 Aug 2016 16:57:26 +0200 Subject: [PATCH 207/571] refactor(conf2uedata): add networks_t for managing known_networks --- openair3/NAS/TOOLS/conf2uedata.c | 119 +++++++++++++++---------------- openair3/NAS/TOOLS/conf2uedata.h | 25 ++++--- openair3/NAS/TOOLS/conf_emm.c | 34 ++++----- openair3/NAS/TOOLS/conf_emm.h | 4 +- openair3/NAS/TOOLS/conf_usim.c | 43 +++++------ openair3/NAS/TOOLS/conf_usim.h | 2 +- 6 files changed, 116 insertions(+), 111 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 197c639454..44005b9dd1 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -12,11 +12,6 @@ #include "conf_user_data.h" #include "conf_usim.h" -int plmn_nb = 0; - -plmn_conf_param_t* user_plmn_list=NULL; -network_record_t* user_network_record_list = NULL; - int main(int argc, char**argv) { int option; const char* conf_file = NULL; @@ -71,6 +66,8 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { char user[10]; config_t cfg; + networks_t networks;; + ret = get_config_from_file(conf_filename, &cfg); if (ret == EXIT_FAILURE) { exit(1); @@ -85,11 +82,10 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { return (EXIT_FAILURE); } - rc = parse_plmns(all_plmn_setting); + rc = parse_plmns(all_plmn_setting, &networks); if (rc == EXIT_FAILURE) { return rc; } - fill_network_record_list(); for (int i = 0; i < ue_nb; i++) { emm_nvdata_t emm_data; @@ -110,7 +106,7 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { return EXIT_FAILURE; } - rc = parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn); + rc = parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn, networks); if (rc != EXIT_SUCCESS) { return EXIT_FAILURE; } @@ -128,13 +124,16 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { printf("Problem in SIM section for UE%d. EXITING...\n", i); return EXIT_FAILURE; } - gen_usim_data(&usim_data_conf, &usim_data, &user_plmns); + gen_usim_data(&usim_data_conf, &usim_data, &user_plmns, networks); write_usim_data(output_dir, i, &usim_data); - gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, user_plmns.equivalents_home.size); + gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, + user_plmns.equivalents_home.size, networks); write_emm_data(output_dir, i, &emm_data); } + free(networks.items); + networks.size=0; config_destroy(&cfg); return(EXIT_SUCCESS); } @@ -160,52 +159,52 @@ int get_config_from_file(const char *filename, config_t *config) { } -int parse_plmn_param(config_setting_t *plmn_setting, int index) { +int parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf) { int rc = 0; - rc = config_setting_lookup_string(plmn_setting, - FULLNAME, &user_plmn_list[index].fullname); + rc = config_setting_lookup_string(plmn_setting, FULLNAME, &conf->fullname); if (rc != 1) { - printf("Check PLMN%d FULLNAME. Exiting\n", index); + printf("Error on FULLNAME\n"); return EXIT_FAILURE; } - rc = config_setting_lookup_string(plmn_setting, - SHORTNAME, &user_plmn_list[index].shortname); + rc = config_setting_lookup_string(plmn_setting, SHORTNAME, &conf->shortname); if (rc != 1) { - printf("Check PLMN%d SHORTNAME. Exiting\n", index); + printf("Error on SHORTNAME\n"); return EXIT_FAILURE; } - rc = config_setting_lookup_string(plmn_setting, - MNC, &user_plmn_list[index].mnc); - if (rc != 1 || strlen(user_plmn_list[index].mnc) > 3 - || strlen(user_plmn_list[index].mnc) < 2) { - printf("Check PLMN%d MNC. Exiting\n", index); + rc = config_setting_lookup_string(plmn_setting, MNC, &conf->mnc); + if (rc != 1 || strlen(conf->mnc) > 3 + || strlen(conf->mnc) < 2) { + printf("Error ond MNC. Exiting\n"); return EXIT_FAILURE; } - rc = config_setting_lookup_string(plmn_setting, - MCC, &user_plmn_list[index].mcc); - if (rc != 1 || strlen(user_plmn_list[index].mcc) != 3) { - printf("Check PLMN%d MCC. Exiting\n", index); + rc = config_setting_lookup_string(plmn_setting, MCC, &conf->mcc); + if (rc != 1 || strlen(conf->mcc) != 3) { + printf("Error on MCC\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } -int parse_plmns(config_setting_t *all_plmn_setting) { +int parse_plmns(config_setting_t *all_plmn_setting, networks_t *networks) { config_setting_t *plmn_setting = NULL; char plmn[10]; int rc = EXIT_SUCCESS; - plmn_nb = config_setting_length(all_plmn_setting); - user_plmn_list = malloc(sizeof(plmn_conf_param_t) * plmn_nb); - user_network_record_list = malloc(sizeof(network_record_t) * plmn_nb); - for (int i = 0; i < plmn_nb; i++) { - memset(&user_network_record_list[i], 0xff, sizeof(network_record_t)); - memset(&user_plmn_list[i], 0xff, sizeof(plmn_conf_param_t)); + int size = 0; + + size = config_setting_length(all_plmn_setting); + + networks->size = size; + networks->items = malloc(sizeof(network_t) * size); + for (int i = 0; i < size; i++) { + memset(&networks->items[i].record, 0xff, sizeof(network_record_t)); } - for (int i = 0; i < plmn_nb; i++) { + + for (int i = 0; i < networks->size; i++) { + network_t *network = &networks->items[i]; sprintf(plmn, "%s%d", PLMN, i); plmn_setting = config_setting_get_member(all_plmn_setting, plmn); if (plmn_setting != NULL) { - rc = parse_plmn_param(plmn_setting, i); + rc = parse_plmn_param(plmn_setting, &network->conf); if (rc == EXIT_FAILURE) { return rc; } @@ -213,12 +212,15 @@ int parse_plmns(config_setting_t *all_plmn_setting) { printf("Problem in PLMN%d. Exiting...\n", i); return EXIT_FAILURE; } + gen_network_record_from_conf(&network->conf, &network->record); + network->plmn = network->record.plmn; } return rc; } int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, - user_plmns_t *user_plmns, const char **h) { + user_plmns_t *user_plmns, const char **h, + const networks_t networks) { int nb_errors = 0; const char *hplmn; @@ -227,21 +229,21 @@ int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, return EXIT_FAILURE; } hplmn = *h; - if (get_plmn_index(hplmn) == -1) { + if (get_plmn_index(hplmn, networks) == -1) { printf("HPLMN for UE%d is not defined in PLMN section. Exiting\n", user_id); return EXIT_FAILURE; } - if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &user_plmns->users_controlled) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &user_plmns->users_controlled, networks) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, OPLMN, user_id, &user_plmns->operators) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, OPLMN, user_id, &user_plmns->operators, networks) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &user_plmns->operators_controlled) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &user_plmns->operators_controlled, networks) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, FPLMN, user_id, &user_plmns->forbiddens) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, FPLMN, user_id, &user_plmns->forbiddens, networks) == EXIT_FAILURE ) nb_errors++; - if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &user_plmns->equivalents_home) == EXIT_FAILURE ) + if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &user_plmns->equivalents_home, networks) == EXIT_FAILURE ) nb_errors++; if ( nb_errors > 0 ) @@ -250,7 +252,7 @@ int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, } int parse_Xplmn(config_setting_t *ue_setting, const char *section, - int user_id, plmns_list *plmns) { + int user_id, plmns_list *plmns, const networks_t networks) { int rc; int item_count; config_setting_t *setting; @@ -269,7 +271,7 @@ int parse_Xplmn(config_setting_t *ue_setting, const char *section, printf("Check %s section for UE%d. Exiting\n", section, user_id); return EXIT_FAILURE; } - rc = get_plmn_index(mccmnc); + rc = get_plmn_index(mccmnc, networks); if (rc == -1) { printf("The PLMN %s is not defined in PLMN section. Exiting...\n", mccmnc); @@ -283,16 +285,16 @@ int parse_Xplmn(config_setting_t *ue_setting, const char *section, return EXIT_SUCCESS; } -int get_plmn_index(const char * mccmnc) { +int get_plmn_index(const char * mccmnc, const networks_t networks) { char mcc[4]; char mnc[strlen(mccmnc) - 2]; strncpy(mcc, mccmnc, 3); mcc[3] = '\0'; strncpy(mnc, mccmnc + 3, 3); mnc[strlen(mccmnc) - 3] = '\0'; - for (int i = 0; i < plmn_nb; i++) { - if (strcmp(user_plmn_list[i].mcc, mcc) == 0) { - if (strcmp(user_plmn_list[i].mnc, mnc) == 0) { + for (int i = 0; i < networks.size; i++) { + if (strcmp(networks.items[i].conf.mcc, mcc) == 0) { + if (strcmp(networks.items[i].conf.mnc, mnc) == 0) { return i; } } @@ -300,7 +302,6 @@ int get_plmn_index(const char * mccmnc) { return -1; } - plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) { plmn_t plmn; char num[6]; @@ -320,21 +321,17 @@ plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) { return plmn; } -void fill_network_record_list() { - for (int i = 0; i < plmn_nb; i++) { - strcpy(user_network_record_list[i].fullname, - user_plmn_list[i].fullname); - strcpy(user_network_record_list[i].shortname, - user_plmn_list[i].shortname); +void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record) { + strcpy(record->fullname, conf->fullname); + strcpy(record->shortname, conf->shortname); char num[6]; - sprintf(num, "%s%s", user_plmn_list[i].mcc, user_plmn_list[i].mnc); - user_network_record_list[i].num = atoi(num); + sprintf(num, "%s%s", conf->mcc, conf->mnc); + record->num = atoi(num); - user_network_record_list[i].plmn = make_plmn_from_conf(&user_plmn_list[i]); - user_network_record_list[i].tac_end = 0xfffd; - user_network_record_list[i].tac_start = 0x0001; - } + record->plmn = make_plmn_from_conf(conf); + record->tac_end = 0xfffd; + record->tac_start = 0x0001; } /* diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 21cc2c3fbd..3693aafffb 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -56,24 +56,31 @@ typedef struct { plmns_list equivalents_home; } user_plmns_t; -extern int plmn_nb; +typedef struct { + plmn_conf_param_t conf; + network_record_t record; + plmn_t plmn; +} network_t; -extern plmn_conf_param_t* user_plmn_list; -extern network_record_t* user_network_record_list; +typedef struct { + int size; + network_t *items; +} networks_t; int get_config_from_file(const char *filename, config_t *config); int parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); -void fill_network_record_list(void); +void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record); -int parse_plmn_param(config_setting_t *plmn_setting, int index); -int parse_plmns(config_setting_t *all_plmn_setting); -int get_plmn_index(const char * mccmnc); +int parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf); +int parse_plmns(config_setting_t *all_plmn_setting, networks_t *plmns); +int get_plmn_index(const char * mccmnc, const networks_t networks); int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, - user_plmns_t *user_plmns, const char **h); + user_plmns_t *user_plmns, const char **h, + const networks_t networks); int parse_Xplmn(config_setting_t *ue_setting, const char *section, - int user_id, plmns_list *plmns); + int user_id, plmns_list *plmns, const networks_t networks); #endif // _CONF2UEDATA_H diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c index bc9f3441ae..04debda412 100644 --- a/openair3/NAS/TOOLS/conf_emm.c +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -1,26 +1,26 @@ #include -#include "conf2uedata.h" #include "memory.h" #include "conf_emm.h" #include "fs.h" -void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count) { +void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count, const networks_t networks) { memset(emm_data, 0, sizeof(emm_nvdata_t)); - int hplmn_index = get_plmn_index(hplmn); + int hplmn_index = get_plmn_index(hplmn, networks); + plmn_conf_param_t *conf = &networks.items[hplmn_index].conf; emm_data->imsi.length = 8; - emm_data->imsi.u.num.parity = get_msin_parity(msin, user_plmn_list[hplmn_index].mcc, user_plmn_list[hplmn_index].mnc); - emm_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; - emm_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; - emm_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + emm_data->imsi.u.num.parity = get_msin_parity(msin, conf->mcc, conf->mnc); + emm_data->imsi.u.num.digit1 = conf->mcc[0]; + emm_data->imsi.u.num.digit2 = conf->mcc[1]; + emm_data->imsi.u.num.digit3 = conf->mcc[2]; - emm_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; - emm_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; + emm_data->imsi.u.num.digit4 = conf->mnc[0]; + emm_data->imsi.u.num.digit5 = conf->mnc[1]; - if (strlen(user_plmn_list[hplmn_index].mnc) == 3) { - emm_data->rplmn.MNCdigit3 = user_plmn_list[hplmn_index].mnc[2]; + if (strlen(conf->mnc) == 3) { + emm_data->rplmn.MNCdigit3 = conf->mnc[2]; - emm_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + emm_data->imsi.u.num.digit6 = conf->mnc[2]; emm_data->imsi.u.num.digit7 = msin[0]; emm_data->imsi.u.num.digit8 = msin[1]; emm_data->imsi.u.num.digit9 = msin[2]; @@ -47,11 +47,11 @@ void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, i } - emm_data->rplmn.MCCdigit1 = user_plmn_list[hplmn_index].mcc[0]; - emm_data->rplmn.MCCdigit2 = user_plmn_list[hplmn_index].mcc[1]; - emm_data->rplmn.MCCdigit3 = user_plmn_list[hplmn_index].mcc[2]; - emm_data->rplmn.MNCdigit1 = user_plmn_list[hplmn_index].mnc[0]; - emm_data->rplmn.MNCdigit2 = user_plmn_list[hplmn_index].mnc[1]; + emm_data->rplmn.MCCdigit1 = conf->mcc[0]; + emm_data->rplmn.MCCdigit2 = conf->mcc[1]; + emm_data->rplmn.MCCdigit3 = conf->mcc[2]; + emm_data->rplmn.MNCdigit1 = conf->mnc[0]; + emm_data->rplmn.MNCdigit2 = conf->mnc[1]; emm_data->eplmn.n_plmns = ehplmn_count; } diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h index c405e02612..0b5f737091 100644 --- a/openair3/NAS/TOOLS/conf_emm.h +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -1,10 +1,10 @@ #ifndef _CONF_EMM_H #define _CONF_EMM_H +#include "conf2uedata.h" #include "emmData.h" -void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, - int ehplmn_count); +void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count, const networks_t networks); int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); int get_msin_parity(const char * msin, const char *mcc, const char *mnc); diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c index 8b1a80ad52..da2c44dc23 100644 --- a/openair3/NAS/TOOLS/conf_usim.c +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -41,22 +41,23 @@ int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf } void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, - const user_plmns_t *user_plmns) { - int hplmn_index = get_plmn_index(u->hplmn); + const user_plmns_t *user_plmns, const networks_t networks) { + int hplmn_index = get_plmn_index(u->hplmn, networks); + const plmn_conf_param_t *conf = &networks.items[hplmn_index].conf; memset(usim_data, 0, sizeof(usim_data_t)); usim_data->imsi.length = 8; usim_data->imsi.u.num.parity = get_msin_parity(u->msin, - user_plmn_list[hplmn_index].mcc, - user_plmn_list[hplmn_index].mnc); + conf->mcc, + conf->mnc); - usim_data->imsi.u.num.digit1 = user_plmn_list[hplmn_index].mcc[0]; - usim_data->imsi.u.num.digit2 = user_plmn_list[hplmn_index].mcc[1]; - usim_data->imsi.u.num.digit3 = user_plmn_list[hplmn_index].mcc[2]; + usim_data->imsi.u.num.digit1 = conf->mcc[0]; + usim_data->imsi.u.num.digit2 = conf->mcc[1]; + usim_data->imsi.u.num.digit3 = conf->mcc[2]; - usim_data->imsi.u.num.digit4 = user_plmn_list[hplmn_index].mnc[0]; - usim_data->imsi.u.num.digit5 = user_plmn_list[hplmn_index].mnc[1]; + usim_data->imsi.u.num.digit4 = conf->mnc[0]; + usim_data->imsi.u.num.digit5 = conf->mnc[1]; - if (strlen(user_plmn_list[hplmn_index].mnc) == 2) { + if (strlen(conf->mnc) == 2) { usim_data->imsi.u.num.digit6 = u->msin[0]; usim_data->imsi.u.num.digit7 = u->msin[1]; usim_data->imsi.u.num.digit8 = u->msin[2]; @@ -68,7 +69,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, usim_data->imsi.u.num.digit14 = u->msin[8]; usim_data->imsi.u.num.digit15 = u->msin[9]; } else { - usim_data->imsi.u.num.digit6 = user_plmn_list[hplmn_index].mnc[2]; + usim_data->imsi.u.num.digit6 = conf->mnc[2]; usim_data->imsi.u.num.digit7 = u->msin[0]; usim_data->imsi.u.num.digit8 = u->msin[1]; usim_data->imsi.u.num.digit9 = u->msin[2]; @@ -99,7 +100,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, } if (user_plmns->forbiddens.size > 0) { for (int i = 0; i < user_plmns->forbiddens.size; i++) { - usim_data->fplmn[i] = user_network_record_list[user_plmns->forbiddens.items[i]].plmn; + usim_data->fplmn[i] = networks.items[user_plmns->forbiddens.items[i]].plmn; } } @@ -107,7 +108,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, * Location Information */ usim_data->loci.tmsi = DEFAULT_TMSI; - usim_data->loci.lai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->loci.lai.plmn = networks.items[hplmn_index].plmn; usim_data->loci.lai.lac = DEFAULT_LAC; usim_data->loci.status = USIM_LOCI_NOT_UPDATED; /* @@ -117,7 +118,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, usim_data->psloci.signature[0] = 0x01; usim_data->psloci.signature[1] = 0x02; usim_data->psloci.signature[2] = 0x03; - usim_data->psloci.rai.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->psloci.rai.plmn = networks.items[hplmn_index].plmn; usim_data->psloci.rai.lac = DEFAULT_LAC; usim_data->psloci.rai.rac = DEFAULT_RAC; usim_data->psloci.status = USIM_PSLOCI_NOT_UPDATED; @@ -126,7 +127,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, */ usim_data->ad.UE_Operation_Mode = USIM_NORMAL_MODE; usim_data->ad.Additional_Info = 0xffff; - usim_data->ad.MNC_Length = strlen(user_plmn_list[hplmn_index].mnc); + usim_data->ad.MNC_Length = strlen(conf->mnc); /* * EPS NAS security context */ @@ -185,7 +186,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, * PLMN Network Name and Operator PLMN List */ for (int i = 0; i < user_plmns->operators.size; i++) { - network_record_t record = user_network_record_list[user_plmns->operators.items[i]]; + network_record_t record = networks.items[user_plmns->operators.items[i]].record; usim_data->pnn[i].fullname.type = USIM_PNN_FULLNAME_TAG; usim_data->pnn[i].fullname.length = strlen(record.fullname); strncpy((char*) usim_data->pnn[i].fullname.value, record.fullname, @@ -209,7 +210,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, * List of Equivalent HPLMNs */ for (int i = 0; i < user_plmns->equivalents_home.size; i++) { - usim_data->ehplmn[i] = user_network_record_list[user_plmns->equivalents_home.items[i]].plmn; + usim_data->ehplmn[i] = networks.items[user_plmns->equivalents_home.items[i]].plmn; } if (user_plmns->equivalents_home.size < USIM_EHPLMN_MAX) { for (int i = user_plmns->equivalents_home.size; i < USIM_EHPLMN_MAX; i++) { @@ -219,7 +220,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, /* * Home PLMN Selector with Access Technology */ - usim_data->hplmn.plmn = user_network_record_list[hplmn_index].plmn; + usim_data->hplmn.plmn = networks.items[hplmn_index].plmn; usim_data->hplmn.AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); /* @@ -230,7 +231,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, } if (user_plmns->users_controlled.size > 0) { for (int i = 0; i < user_plmns->users_controlled.size; i++) { - usim_data->plmn[i].plmn = user_network_record_list[user_plmns->users_controlled.items[i]].plmn; + usim_data->plmn[i].plmn = networks.items[user_plmns->users_controlled.items[i]].plmn; } } @@ -241,7 +242,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, } if (user_plmns->operators_controlled.size > 0) { for (int i = 0; i < user_plmns->operators_controlled.size; i++) { - usim_data->oplmn[i].plmn = user_network_record_list[user_plmns->operators_controlled.items[i]].plmn; + usim_data->oplmn[i].plmn = networks.items[user_plmns->operators_controlled.items[i]].plmn; usim_data->oplmn[i].AcT = (USIM_ACT_GSM | USIM_ACT_UTRAN | USIM_ACT_EUTRAN); } @@ -250,7 +251,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, * EPS Location Information */ usim_data->epsloci.guti.gummei.plmn = - user_network_record_list[hplmn_index].plmn; + networks.items[hplmn_index].plmn; usim_data->epsloci.guti.gummei.MMEgid = DEFAULT_MME_ID; usim_data->epsloci.guti.gummei.MMEcode = DEFAULT_MME_CODE; usim_data->epsloci.guti.m_tmsi = DEFAULT_M_TMSI; diff --git a/openair3/NAS/TOOLS/conf_usim.h b/openair3/NAS/TOOLS/conf_usim.h index 5018be8148..90b3a9e418 100644 --- a/openair3/NAS/TOOLS/conf_usim.h +++ b/openair3/NAS/TOOLS/conf_usim.h @@ -41,6 +41,6 @@ typedef struct { int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u); int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, - const user_plmns_t *user_plmns); + const user_plmns_t *user_plmns, const networks_t networks); #endif From 51c775352650c4a2ed9f248c75d30dc6bc7391c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 23 Aug 2016 17:30:02 +0200 Subject: [PATCH 208/571] refactor(conf2uedata): move networks function to conf_networks.[c|h] --- cmake_targets/nas_sim_tools/CMakeLists.txt | 1 + openair3/NAS/TOOLS/conf2uedata.c | 113 +-------------------- openair3/NAS/TOOLS/conf2uedata.h | 45 +------- openair3/NAS/TOOLS/conf_network.c | 112 ++++++++++++++++++++ openair3/NAS/TOOLS/conf_network.h | 54 ++++++++++ 5 files changed, 170 insertions(+), 155 deletions(-) create mode 100644 openair3/NAS/TOOLS/conf_network.c create mode 100644 openair3/NAS/TOOLS/conf_network.h diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 39e7102357..1bf158a904 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -20,6 +20,7 @@ set(conf2uedata_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_network.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 44005b9dd1..853bca3d88 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -82,9 +82,8 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { return (EXIT_FAILURE); } - rc = parse_plmns(all_plmn_setting, &networks); - if (rc == EXIT_FAILURE) { - return rc; + if ( parse_plmns(all_plmn_setting, &networks) == false ) { + return EXIT_FAILURE; } for (int i = 0; i < ue_nb; i++) { @@ -159,65 +158,6 @@ int get_config_from_file(const char *filename, config_t *config) { } -int parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf) { - int rc = 0; - rc = config_setting_lookup_string(plmn_setting, FULLNAME, &conf->fullname); - if (rc != 1) { - printf("Error on FULLNAME\n"); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(plmn_setting, SHORTNAME, &conf->shortname); - if (rc != 1) { - printf("Error on SHORTNAME\n"); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(plmn_setting, MNC, &conf->mnc); - if (rc != 1 || strlen(conf->mnc) > 3 - || strlen(conf->mnc) < 2) { - printf("Error ond MNC. Exiting\n"); - return EXIT_FAILURE; - } - rc = config_setting_lookup_string(plmn_setting, MCC, &conf->mcc); - if (rc != 1 || strlen(conf->mcc) != 3) { - printf("Error on MCC\n"); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} - -int parse_plmns(config_setting_t *all_plmn_setting, networks_t *networks) { - config_setting_t *plmn_setting = NULL; - char plmn[10]; - int rc = EXIT_SUCCESS; - int size = 0; - - size = config_setting_length(all_plmn_setting); - - networks->size = size; - networks->items = malloc(sizeof(network_t) * size); - for (int i = 0; i < size; i++) { - memset(&networks->items[i].record, 0xff, sizeof(network_record_t)); - } - - for (int i = 0; i < networks->size; i++) { - network_t *network = &networks->items[i]; - sprintf(plmn, "%s%d", PLMN, i); - plmn_setting = config_setting_get_member(all_plmn_setting, plmn); - if (plmn_setting != NULL) { - rc = parse_plmn_param(plmn_setting, &network->conf); - if (rc == EXIT_FAILURE) { - return rc; - } - } else { - printf("Problem in PLMN%d. Exiting...\n", i); - return EXIT_FAILURE; - } - gen_network_record_from_conf(&network->conf, &network->record); - network->plmn = network->record.plmn; - } - return rc; -} - int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, user_plmns_t *user_plmns, const char **h, const networks_t networks) { @@ -285,55 +225,6 @@ int parse_Xplmn(config_setting_t *ue_setting, const char *section, return EXIT_SUCCESS; } -int get_plmn_index(const char * mccmnc, const networks_t networks) { - char mcc[4]; - char mnc[strlen(mccmnc) - 2]; - strncpy(mcc, mccmnc, 3); - mcc[3] = '\0'; - strncpy(mnc, mccmnc + 3, 3); - mnc[strlen(mccmnc) - 3] = '\0'; - for (int i = 0; i < networks.size; i++) { - if (strcmp(networks.items[i].conf.mcc, mcc) == 0) { - if (strcmp(networks.items[i].conf.mnc, mnc) == 0) { - return i; - } - } - } - return -1; -} - -plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) { - plmn_t plmn; - char num[6]; - - memset(&plmn, 0xff, sizeof(plmn)); - - snprintf(num, 6, "%s%s", plmn_conf->mcc, plmn_conf->mnc); - - plmn.MCCdigit2 = plmn_conf->mcc[1]; - plmn.MCCdigit1 = plmn_conf->mcc[0]; - plmn.MCCdigit3 = plmn_conf->mcc[2]; - plmn.MNCdigit2 = plmn_conf->mnc[1]; - plmn.MNCdigit1 = plmn_conf->mnc[0]; - if (strlen(plmn_conf->mnc) > 2) { - plmn.MNCdigit3 = plmn_conf->mnc[2]; - } - return plmn; -} - -void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record) { - strcpy(record->fullname, conf->fullname); - strcpy(record->shortname, conf->shortname); - - char num[6]; - sprintf(num, "%s%s", conf->mcc, conf->mnc); - record->num = atoi(num); - - record->plmn = make_plmn_from_conf(conf); - record->tac_end = 0xfffd; - record->tac_start = 0x0001; -} - /* * Displays command line usage */ diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index 3693aafffb..f7afdde0c4 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -4,16 +4,10 @@ #include #include "usim_api.h" +#include "conf_network.h" #define UE "UE" -#define PLMN "PLMN" - -#define FULLNAME "FULLNAME" -#define SHORTNAME "SHORTNAME" -#define MNC "MNC" -#define MCC "MCC" - #define HPLMN "HPLMN" #define UCPLMN "UCPLMN_LIST" #define OPLMN "OPLMN_LIST" @@ -21,28 +15,6 @@ #define FPLMN "FPLMN_LIST" #define EHPLMN "EHPLMN_LIST" -#define MIN_TAC 0x0000 -#define MAX_TAC 0xFFFE - -/* - * PLMN network operator record - */ -typedef struct { - unsigned int num; - plmn_t plmn; - char fullname[NET_FORMAT_LONG_SIZE + 1]; - char shortname[NET_FORMAT_SHORT_SIZE + 1]; - tac_t tac_start; - tac_t tac_end; -} network_record_t; - -typedef struct { - const char *fullname; - const char *shortname; - const char *mnc; - const char *mcc; -} plmn_conf_param_t; - typedef struct { int size; int *items; @@ -56,26 +28,11 @@ typedef struct { plmns_list equivalents_home; } user_plmns_t; -typedef struct { - plmn_conf_param_t conf; - network_record_t record; - plmn_t plmn; -} network_t; - -typedef struct { - int size; - network_t *items; -} networks_t; - int get_config_from_file(const char *filename, config_t *config); int parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); -void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record); -int parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf); -int parse_plmns(config_setting_t *all_plmn_setting, networks_t *plmns); -int get_plmn_index(const char * mccmnc, const networks_t networks); int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, user_plmns_t *user_plmns, const char **h, const networks_t networks); diff --git a/openair3/NAS/TOOLS/conf_network.c b/openair3/NAS/TOOLS/conf_network.c new file mode 100644 index 0000000000..96e2183327 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_network.c @@ -0,0 +1,112 @@ +#include +#include + +#include "conf_network.h" + +int get_plmn_index(const char * mccmnc, const networks_t networks) { + char mcc[4]; + char mnc[strlen(mccmnc) - 2]; + strncpy(mcc, mccmnc, 3); + mcc[3] = '\0'; + strncpy(mnc, mccmnc + 3, 3); + mnc[strlen(mccmnc) - 3] = '\0'; + for (int i = 0; i < networks.size; i++) { + if (strcmp(networks.items[i].conf.mcc, mcc) == 0) { + if (strcmp(networks.items[i].conf.mnc, mnc) == 0) { + return i; + } + } + } + return -1; +} + +plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) { + plmn_t plmn; + char num[6]; + + memset(&plmn, 0xff, sizeof(plmn)); + + snprintf(num, 6, "%s%s", plmn_conf->mcc, plmn_conf->mnc); + + plmn.MCCdigit2 = plmn_conf->mcc[1]; + plmn.MCCdigit1 = plmn_conf->mcc[0]; + plmn.MCCdigit3 = plmn_conf->mcc[2]; + plmn.MNCdigit2 = plmn_conf->mnc[1]; + plmn.MNCdigit1 = plmn_conf->mnc[0]; + if (strlen(plmn_conf->mnc) > 2) { + plmn.MNCdigit3 = plmn_conf->mnc[2]; + } + return plmn; +} + +void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record) { + strcpy(record->fullname, conf->fullname); + strcpy(record->shortname, conf->shortname); + + char num[6]; + sprintf(num, "%s%s", conf->mcc, conf->mnc); + record->num = atoi(num); + + record->plmn = make_plmn_from_conf(conf); + record->tac_end = 0xfffd; + record->tac_start = 0x0001; +} + +bool parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf) { + int rc = 0; + rc = config_setting_lookup_string(plmn_setting, FULLNAME, &conf->fullname); + if (rc != 1) { + printf("Error on FULLNAME\n"); + return false; + } + rc = config_setting_lookup_string(plmn_setting, SHORTNAME, &conf->shortname); + if (rc != 1) { + printf("Error on SHORTNAME\n"); + return false; + } + rc = config_setting_lookup_string(plmn_setting, MNC, &conf->mnc); + if (rc != 1 || strlen(conf->mnc) > 3 + || strlen(conf->mnc) < 2) { + printf("Error ond MNC. Exiting\n"); + return false; + } + rc = config_setting_lookup_string(plmn_setting, MCC, &conf->mcc); + if (rc != 1 || strlen(conf->mcc) != 3) { + printf("Error on MCC\n"); + return false; + } + return true; +} + +bool parse_plmns(config_setting_t *all_plmn_setting, networks_t *networks) { + config_setting_t *plmn_setting = NULL; + char plmn[10]; + int size = 0; + + size = config_setting_length(all_plmn_setting); + + networks->size = size; + networks->items = malloc(sizeof(network_t) * size); + for (int i = 0; i < size; i++) { + memset(&networks->items[i].record, 0xff, sizeof(network_record_t)); + } + + for (int i = 0; i < networks->size; i++) { + network_t *network = &networks->items[i]; + sprintf(plmn, "%s%d", PLMN, i); + plmn_setting = config_setting_get_member(all_plmn_setting, plmn); + if (plmn_setting == NULL) { + printf("PLMN%d not fouund\n", i); + return false; + } + + if ( parse_plmn_param(plmn_setting, &network->conf) == false ) { + return false; + } + gen_network_record_from_conf(&network->conf, &network->record); + network->plmn = network->record.plmn; + } + return true; +} + + diff --git a/openair3/NAS/TOOLS/conf_network.h b/openair3/NAS/TOOLS/conf_network.h new file mode 100644 index 0000000000..a535841a4c --- /dev/null +++ b/openair3/NAS/TOOLS/conf_network.h @@ -0,0 +1,54 @@ +#ifndef _CONF_NETWORK_H +#define _CONF_NETWORK_H + +#include +#include +#include "usim_api.h" + +#define PLMN "PLMN" + +#define FULLNAME "FULLNAME" +#define SHORTNAME "SHORTNAME" +#define MNC "MNC" +#define MCC "MCC" + +#define MIN_TAC 0x0000 +#define MAX_TAC 0xFFFE + +/* + * PLMN network operator record + */ +typedef struct { + unsigned int num; + plmn_t plmn; + char fullname[NET_FORMAT_LONG_SIZE + 1]; + char shortname[NET_FORMAT_SHORT_SIZE + 1]; + tac_t tac_start; + tac_t tac_end; +} network_record_t; + +typedef struct { + const char *fullname; + const char *shortname; + const char *mnc; + const char *mcc; +} plmn_conf_param_t; + +typedef struct { + plmn_conf_param_t conf; + network_record_t record; + plmn_t plmn; +} network_t; + +typedef struct { + int size; + network_t *items; +} networks_t; + +bool parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf); +bool parse_plmns(config_setting_t *all_plmn_setting, networks_t *plmns); + +void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record); +int get_plmn_index(const char * mccmnc, const networks_t networks); + +#endif From 86c8d0f95a8f4ed62fe5fcefdc76b79a5f0dd8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Tue, 23 Aug 2016 17:52:19 +0200 Subject: [PATCH 209/571] refactor(conf2uedata): move plmns functions to conf_user_plmn.[c|h] --- cmake_targets/nas_sim_tools/CMakeLists.txt | 1 + openair3/NAS/TOOLS/conf2uedata.c | 73 +------------------ openair3/NAS/TOOLS/conf2uedata.h | 27 -------- openair3/NAS/TOOLS/conf_user_plmn.c | 81 ++++++++++++++++++++++ openair3/NAS/TOOLS/conf_user_plmn.h | 37 ++++++++++ openair3/NAS/TOOLS/conf_usim.h | 1 + 6 files changed, 123 insertions(+), 97 deletions(-) create mode 100644 openair3/NAS/TOOLS/conf_user_plmn.c create mode 100644 openair3/NAS/TOOLS/conf_user_plmn.h diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 1bf158a904..966c928a2b 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -21,6 +21,7 @@ set(conf2uedata_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_network.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_plmn.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 853bca3d88..5112d737ac 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -105,8 +105,7 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { return EXIT_FAILURE; } - rc = parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn, networks); - if (rc != EXIT_SUCCESS) { + if ( parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn, networks) == false ) { return EXIT_FAILURE; } @@ -130,6 +129,8 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { user_plmns.equivalents_home.size, networks); write_emm_data(output_dir, i, &emm_data); + user_plmns_free(&user_plmns); + } free(networks.items); networks.size=0; @@ -157,74 +158,6 @@ int get_config_from_file(const char *filename, config_t *config) { return EXIT_SUCCESS; } - -int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, - user_plmns_t *user_plmns, const char **h, - const networks_t networks) { - int nb_errors = 0; - const char *hplmn; - - if ( config_setting_lookup_string(ue_setting, HPLMN, h) != 1 ) { - printf("Check HPLMN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; - } - hplmn = *h; - if (get_plmn_index(hplmn, networks) == -1) { - printf("HPLMN for UE%d is not defined in PLMN section. Exiting\n", - user_id); - return EXIT_FAILURE; - } - - if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &user_plmns->users_controlled, networks) == EXIT_FAILURE ) - nb_errors++; - if ( parse_Xplmn(ue_setting, OPLMN, user_id, &user_plmns->operators, networks) == EXIT_FAILURE ) - nb_errors++; - if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &user_plmns->operators_controlled, networks) == EXIT_FAILURE ) - nb_errors++; - if ( parse_Xplmn(ue_setting, FPLMN, user_id, &user_plmns->forbiddens, networks) == EXIT_FAILURE ) - nb_errors++; - if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &user_plmns->equivalents_home, networks) == EXIT_FAILURE ) - nb_errors++; - - if ( nb_errors > 0 ) - return EXIT_FAILURE; - return EXIT_SUCCESS; -} - -int parse_Xplmn(config_setting_t *ue_setting, const char *section, - int user_id, plmns_list *plmns, const networks_t networks) { - int rc; - int item_count; - config_setting_t *setting; - - setting = config_setting_get_member(ue_setting, section); - if (setting == NULL) { - printf("Check %s section for UE%d. Exiting\n", section, user_id); - return EXIT_FAILURE; - } - - item_count = config_setting_length(setting); - int *datas = malloc(item_count * sizeof(int)); - for (int i = 0; i < item_count; i++) { - const char *mccmnc = config_setting_get_string_elem(setting, i); - if (mccmnc == NULL) { - printf("Check %s section for UE%d. Exiting\n", section, user_id); - return EXIT_FAILURE; - } - rc = get_plmn_index(mccmnc, networks); - if (rc == -1) { - printf("The PLMN %s is not defined in PLMN section. Exiting...\n", - mccmnc); - return EXIT_FAILURE; - } - datas[i] = rc; - } - - plmns->size = item_count; - plmns->items = datas; - return EXIT_SUCCESS; -} - /* * Displays command line usage */ diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index f7afdde0c4..d43dbce500 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -8,36 +8,9 @@ #define UE "UE" -#define HPLMN "HPLMN" -#define UCPLMN "UCPLMN_LIST" -#define OPLMN "OPLMN_LIST" -#define OCPLMN "OCPLMN_LIST" -#define FPLMN "FPLMN_LIST" -#define EHPLMN "EHPLMN_LIST" - -typedef struct { - int size; - int *items; -} plmns_list; - -typedef struct { - plmns_list users_controlled; - plmns_list operators; - plmns_list operators_controlled; - plmns_list forbiddens; - plmns_list equivalents_home; -} user_plmns_t; - int get_config_from_file(const char *filename, config_t *config); int parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); -int parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, - user_plmns_t *user_plmns, const char **h, - const networks_t networks); -int parse_Xplmn(config_setting_t *ue_setting, const char *section, - int user_id, plmns_list *plmns, const networks_t networks); - - #endif // _CONF2UEDATA_H diff --git a/openair3/NAS/TOOLS/conf_user_plmn.c b/openair3/NAS/TOOLS/conf_user_plmn.c new file mode 100644 index 0000000000..3b3c6dd3e6 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_plmn.c @@ -0,0 +1,81 @@ +#include +#include +#include "conf_user_plmn.h" + +bool parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, + user_plmns_t *user_plmns, const char **h, + const networks_t networks) { + int nb_errors = 0; + const char *hplmn; + + if ( config_setting_lookup_string(ue_setting, HPLMN, h) != 1 ) { + printf("Check HPLMN section for UE%d. Exiting\n", user_id); + return false; + } + hplmn = *h; + if (get_plmn_index(hplmn, networks) == -1) { + printf("HPLMN for UE%d is not defined in PLMN section. Exiting\n", + user_id); + return false; + } + + if ( parse_Xplmn(ue_setting, UCPLMN, user_id, &user_plmns->users_controlled, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, OPLMN, user_id, &user_plmns->operators, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, OCPLMN, user_id, &user_plmns->operators_controlled, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, FPLMN, user_id, &user_plmns->forbiddens, networks) == false ) + nb_errors++; + if ( parse_Xplmn(ue_setting, EHPLMN, user_id, &user_plmns->equivalents_home, networks) == false ) + nb_errors++; + + if ( nb_errors > 0 ) + return false; + return true; +} + +bool parse_Xplmn(config_setting_t *ue_setting, const char *section, + int user_id, plmns_list *plmns, const networks_t networks) { + int rc; + int item_count; + config_setting_t *setting; + + setting = config_setting_get_member(ue_setting, section); + if (setting == NULL) { + printf("Check %s section for UE%d. Exiting\n", section, user_id); + return false; + } + + item_count = config_setting_length(setting); + int *datas = malloc(item_count * sizeof(int)); + for (int i = 0; i < item_count; i++) { + const char *mccmnc = config_setting_get_string_elem(setting, i); + if (mccmnc == NULL) { + printf("Check %s section for UE%d. Exiting\n", section, user_id); + free(datas); + return false; + } + rc = get_plmn_index(mccmnc, networks); + if (rc == -1) { + printf("The PLMN %s is not defined in PLMN section. Exiting...\n", + mccmnc); + free(datas); + return false; + } + datas[i] = rc; + } + + plmns->size = item_count; + plmns->items = datas; + return true; +} + +void user_plmns_free(user_plmns_t *user_plmns) { + free(user_plmns->users_controlled.items); + free(user_plmns->operators.items); + free(user_plmns->operators_controlled.items); + free(user_plmns->forbiddens.items); + free(user_plmns->equivalents_home.items); + memset(user_plmns, 0, sizeof(user_plmns_t)); +} diff --git a/openair3/NAS/TOOLS/conf_user_plmn.h b/openair3/NAS/TOOLS/conf_user_plmn.h new file mode 100644 index 0000000000..561767b6c4 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_user_plmn.h @@ -0,0 +1,37 @@ +#ifndef _CONF_USER_H +#define _CONF_USER_H + +#include +#include +#include "conf_network.h" + +#define HPLMN "HPLMN" +#define UCPLMN "UCPLMN_LIST" +#define OPLMN "OPLMN_LIST" +#define OCPLMN "OCPLMN_LIST" +#define FPLMN "FPLMN_LIST" +#define EHPLMN "EHPLMN_LIST" + +typedef struct { + int size; + int *items; +} plmns_list; + +typedef struct { + plmns_list users_controlled; + plmns_list operators; + plmns_list operators_controlled; + plmns_list forbiddens; + plmns_list equivalents_home; +} user_plmns_t; + +bool parse_user_plmns_conf(config_setting_t *ue_setting, int user_id, + user_plmns_t *user_plmns, const char **h, + const networks_t networks); + +bool parse_Xplmn(config_setting_t *ue_setting, const char *section, + int user_id, plmns_list *plmns, const networks_t networks); + +void user_plmns_free(user_plmns_t *user_plmns); + +#endif diff --git a/openair3/NAS/TOOLS/conf_usim.h b/openair3/NAS/TOOLS/conf_usim.h index 90b3a9e418..71e6c63d6b 100644 --- a/openair3/NAS/TOOLS/conf_usim.h +++ b/openair3/NAS/TOOLS/conf_usim.h @@ -3,6 +3,7 @@ #include #include "usim_api.h" +#include "conf_user_plmn.h" #define SIM "SIM" #define MSIN "MSIN" From bf699414d10df14ae51f33607813ec79b6c1dd87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 24 Aug 2016 10:24:13 +0200 Subject: [PATCH 210/571] style(conf2uedata): use bool type for readability --- openair3/NAS/TOOLS/conf2uedata.c | 44 ++++++++++++++--------------- openair3/NAS/TOOLS/conf2uedata.h | 4 +-- openair3/NAS/TOOLS/conf_emm.c | 6 ++-- openair3/NAS/TOOLS/conf_emm.h | 2 +- openair3/NAS/TOOLS/conf_user_data.c | 22 ++++++++------- openair3/NAS/TOOLS/conf_user_data.h | 3 +- openair3/NAS/TOOLS/conf_usim.c | 18 ++++++------ openair3/NAS/TOOLS/conf_usim.h | 4 +-- openair3/NAS/TOOLS/display.c | 6 ++-- 9 files changed, 56 insertions(+), 53 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 5112d737ac..338d1b11ef 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -28,7 +28,7 @@ int main(int argc, char**argv) { break; case 'h': _display_usage(); - return EXIT_SUCCESS; + return true; break; default: break; @@ -38,26 +38,26 @@ int main(int argc, char**argv) { if (output_dir == NULL ) { printf("No output option found\n"); _display_usage(); - return EXIT_FAILURE; + exit(1); } if ( conf_file == NULL ) { printf("No Configuration file is given\n"); _display_usage(); - return EXIT_FAILURE; + exit(1); } - if ( parse_config_file(output_dir, conf_file) == EXIT_FAILURE ) { - exit(EXIT_FAILURE); + if ( parse_config_file(output_dir, conf_file) == false ) { + exit(1); } display_data_from_directory(output_dir); - exit(EXIT_SUCCESS); + exit(0); } -int parse_config_file(const char *output_dir, const char *conf_filename) { - int rc = EXIT_SUCCESS; +bool parse_config_file(const char *output_dir, const char *conf_filename) { + int rc = true; int ret; int ue_nb = 0; config_setting_t *root_setting = NULL; @@ -69,7 +69,7 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { networks_t networks;; ret = get_config_from_file(conf_filename, &cfg); - if (ret == EXIT_FAILURE) { + if (ret == false) { exit(1); } @@ -79,11 +79,11 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { all_plmn_setting = config_setting_get_member(root_setting, PLMN); if (all_plmn_setting == NULL) { printf("NO PLMN SECTION...EXITING...\n"); - return (EXIT_FAILURE); + return (false); } if ( parse_plmns(all_plmn_setting, &networks) == false ) { - return EXIT_FAILURE; + return false; } for (int i = 0; i < ue_nb; i++) { @@ -102,25 +102,25 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { ue_setting = config_setting_get_member(root_setting, user); if (ue_setting == NULL) { printf("Check UE%d settings\n", i); - return EXIT_FAILURE; + return false; } if ( parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn, networks) == false ) { - return EXIT_FAILURE; + return false; } rc = parse_ue_user_data(ue_setting, i, &user_data_conf); - if (rc != EXIT_SUCCESS) { + if (rc != true) { printf("Problem in USER section for UE%d. EXITING...\n", i); - return EXIT_FAILURE; + return false; } gen_user_data(&user_data_conf, &user_data); write_user_data(output_dir, i, &user_data); rc = parse_ue_sim_param(ue_setting, i, &usim_data_conf); - if (rc != EXIT_SUCCESS) { + if (rc != true) { printf("Problem in SIM section for UE%d. EXITING...\n", i); - return EXIT_FAILURE; + return false; } gen_usim_data(&usim_data_conf, &usim_data, &user_plmns, networks); write_usim_data(output_dir, i, &usim_data); @@ -135,14 +135,14 @@ int parse_config_file(const char *output_dir, const char *conf_filename) { free(networks.items); networks.size=0; config_destroy(&cfg); - return(EXIT_SUCCESS); + return(true); } -int get_config_from_file(const char *filename, config_t *config) { +bool get_config_from_file(const char *filename, config_t *config) { config_init(config); if (filename == NULL) { // XXX write error message ? - exit(EXIT_FAILURE); + return(false); } /* Read the file. If there is an error, report it and exit. */ @@ -153,9 +153,9 @@ int get_config_from_file(const char *filename, config_t *config) { fprintf(stderr, "This is line %d\n", config_error_line(config)); } config_destroy(config); - return (EXIT_FAILURE); + return (false); } - return EXIT_SUCCESS; + return true; } /* diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index d43dbce500..b97116eaa9 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -8,8 +8,8 @@ #define UE "UE" -int get_config_from_file(const char *filename, config_t *config); -int parse_config_file(const char *output_dir, const char *filename); +bool get_config_from_file(const char *filename, config_t *config); +bool parse_config_file(const char *output_dir, const char *filename); void _display_usage(void); diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c index 04debda412..48627cdc0e 100644 --- a/openair3/NAS/TOOLS/conf_emm.c +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -56,16 +56,16 @@ void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, i emm_data->eplmn.n_plmns = ehplmn_count; } -int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { +bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { int rc; char* filename = make_filename(directory, EMM_NVRAM_FILENAME, user_id); rc = memory_write(filename, emm_data, sizeof(emm_nvdata_t)); free(filename); if (rc != RETURNok) { perror("ERROR\t: memory_write() failed"); - exit(EXIT_FAILURE); + exit(false); } - return(EXIT_SUCCESS); + return(true); } int get_msin_parity(const char * msin, const char *mcc, const char *mnc) { diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h index 0b5f737091..32506acdb5 100644 --- a/openair3/NAS/TOOLS/conf_emm.h +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -5,7 +5,7 @@ #include "emmData.h" void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count, const networks_t networks); -int write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); +bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); int get_msin_parity(const char * msin, const char *mcc, const char *mnc); #endif diff --git a/openair3/NAS/TOOLS/conf_user_data.c b/openair3/NAS/TOOLS/conf_user_data.c index 4dcfc3cf78..5e14797e16 100644 --- a/openair3/NAS/TOOLS/conf_user_data.c +++ b/openair3/NAS/TOOLS/conf_user_data.c @@ -1,6 +1,7 @@ #include #include +#include "commonDef.h" #include "memory.h" #include "fs.h" #include "conf_user_data.h" @@ -8,34 +9,34 @@ int parse_ue_user_data(config_setting_t *ue_setting, int user_id, user_data_conf_t *u) { config_setting_t *ue_param_setting = NULL; - int rc = EXIT_SUCCESS; + int rc = true; ue_param_setting = config_setting_get_member(ue_setting, USER); if (ue_param_setting == NULL) { printf("Check USER section of UE%d. EXITING...\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, UE_IMEI, &u->imei); if (rc != 1) { printf("Check USER IMEI section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, MANUFACTURER, &u->manufacturer); if (rc != 1) { printf("Check USER MANUFACTURER for UE%d FULLNAME. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, MODEL, &u->model); if (rc != 1) { printf("Check USER MODEL for UE%d FULLNAME. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, PINCODE, &u->pin); if (rc != 1) { printf("Check USER PIN for UE%d FULLNAME. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } - return EXIT_SUCCESS; + return true; } void gen_user_data(user_data_conf_t *u, user_nvdata_t *user_data) { @@ -55,15 +56,16 @@ void gen_user_data(user_data_conf_t *u, user_nvdata_t *user_data) { strncpy(user_data->PIN, u->pin, USER_PIN_SIZE); } -void write_user_data(const char *directory, int user_id, user_nvdata_t *data) { +bool write_user_data(const char *directory, int user_id, user_nvdata_t *data) { int rc; char* filename = make_filename(directory, USER_NVRAM_FILENAME, user_id); rc = memory_write(filename, data, sizeof(user_nvdata_t)); free(filename); - if (rc != EXIT_SUCCESS) { + if (rc != RETURNok) { perror("ERROR\t: memory_write() failed"); - exit(EXIT_FAILURE); + return false; } + return true; } /* diff --git a/openair3/NAS/TOOLS/conf_user_data.h b/openair3/NAS/TOOLS/conf_user_data.h index ac168e3c72..6b1d641e03 100644 --- a/openair3/NAS/TOOLS/conf_user_data.h +++ b/openair3/NAS/TOOLS/conf_user_data.h @@ -1,6 +1,7 @@ #ifndef _CONF_USER_DATA_H #define _CONF_USER_DATA_H +#include #include #include "userDef.h" @@ -18,7 +19,7 @@ typedef struct { } user_data_conf_t; void gen_user_data(user_data_conf_t *u, user_nvdata_t *user_data); -void write_user_data(const char *directory, int user_id, user_nvdata_t *data); +bool write_user_data(const char *directory, int user_id, user_nvdata_t *data); int parse_ue_user_data(config_setting_t *ue_setting, int user_id, user_data_conf_t *u); int _luhn(const char* cc); diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c index da2c44dc23..5418f01932 100644 --- a/openair3/NAS/TOOLS/conf_usim.c +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -8,36 +8,36 @@ #include "conf2uedata.h" #include "conf_usim.h" -int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u) { - int rc = EXIT_SUCCESS; +bool parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u) { + int rc = true; config_setting_t *ue_param_setting = NULL; ue_param_setting = config_setting_get_member(ue_setting, SIM); if (ue_param_setting == NULL) { printf("Check SIM section for UE%d. EXITING...\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, MSIN, &u->msin); if (rc != 1 || strlen(u->msin) > 10 || strlen(u->msin) < 9) { printf("Check SIM MSIN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, USIM_API_K, &u->usim_api_k); if (rc != 1) { printf("Check SIM USIM_API_K section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, OPC, &u->opc); if (rc != 1) { printf("Check SIM OPC section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } rc = config_setting_lookup_string(ue_param_setting, MSISDN, &u->msisdn); if (rc != 1) { printf("Check SIM MSISDN section for UE%d. Exiting\n", user_id); - return EXIT_FAILURE; + return false; } - return EXIT_SUCCESS; + return true; } void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, @@ -295,7 +295,7 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, OPC_SIZE); } -int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ +bool write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ int rc; char *filename = make_filename(directory, USIM_API_NVRAM_FILENAME, user_id); rc = usim_api_write(filename, usim_data); diff --git a/openair3/NAS/TOOLS/conf_usim.h b/openair3/NAS/TOOLS/conf_usim.h index 71e6c63d6b..b53265a76a 100644 --- a/openair3/NAS/TOOLS/conf_usim.h +++ b/openair3/NAS/TOOLS/conf_usim.h @@ -39,8 +39,8 @@ typedef struct { const char *hplmn; } usim_data_conf_t; -int parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u); -int write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); +bool parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u); +bool write_usim_data(const char *directory, int user_id, usim_data_t *usim_data); void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, const user_plmns_t *user_plmns, const networks_t networks); diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c index b130ef2c07..672a9950de 100644 --- a/openair3/NAS/TOOLS/display.c +++ b/openair3/NAS/TOOLS/display.c @@ -64,7 +64,7 @@ void display_ue_data(const char *filename) { if (rc != RETURNok) { perror("ERROR\t: memory_read() failed"); - exit(EXIT_FAILURE); + exit(false); } /* @@ -92,7 +92,7 @@ void display_emm_data(const char *filename) { rc = memory_read(filename, &data, sizeof(emm_nvdata_t)); if (rc != RETURNok) { perror("ERROR\t: memory_read() failed "); - exit(EXIT_FAILURE); + exit(false); } /* @@ -168,7 +168,7 @@ void display_usim_data(const char *filename) { if (rc != RETURNok) { perror("ERROR\t: usim_api_read() failed"); - exit(EXIT_FAILURE); + exit(2); } /* From 6c588589ac96d27f4f3933996fcbe3ba0d3150f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 24 Aug 2016 10:38:12 +0200 Subject: [PATCH 211/571] refactor(conf2uedata): move parser functions to conf_parser.[c|h] --- cmake_targets/nas_sim_tools/CMakeLists.txt | 1 + openair3/NAS/TOOLS/conf2uedata.c | 109 +------------------- openair3/NAS/TOOLS/conf2uedata.h | 10 -- openair3/NAS/TOOLS/conf_emm.h | 2 +- openair3/NAS/TOOLS/conf_parser.c | 110 +++++++++++++++++++++ openair3/NAS/TOOLS/conf_parser.h | 12 +++ openair3/NAS/TOOLS/conf_usim.c | 1 - 7 files changed, 125 insertions(+), 120 deletions(-) create mode 100644 openair3/NAS/TOOLS/conf_parser.c create mode 100644 openair3/NAS/TOOLS/conf_parser.h diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 966c928a2b..025c35c441 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -22,6 +22,7 @@ set(conf2uedata_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_network.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_plmn.c + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_parser.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index 338d1b11ef..b162979dc2 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -4,13 +4,8 @@ #include #include "conf2uedata.h" -#include "memory.h" -#include "utils.h" #include "display.h" -#include "fs.h" -#include "conf_emm.h" -#include "conf_user_data.h" -#include "conf_usim.h" +#include "conf_parser.h" int main(int argc, char**argv) { int option; @@ -56,108 +51,6 @@ int main(int argc, char**argv) { exit(0); } -bool parse_config_file(const char *output_dir, const char *conf_filename) { - int rc = true; - int ret; - int ue_nb = 0; - config_setting_t *root_setting = NULL; - config_setting_t *ue_setting = NULL; - config_setting_t *all_plmn_setting = NULL; - char user[10]; - config_t cfg; - - networks_t networks;; - - ret = get_config_from_file(conf_filename, &cfg); - if (ret == false) { - exit(1); - } - - root_setting = config_root_setting(&cfg); - ue_nb = config_setting_length(root_setting) - 1; - - all_plmn_setting = config_setting_get_member(root_setting, PLMN); - if (all_plmn_setting == NULL) { - printf("NO PLMN SECTION...EXITING...\n"); - return (false); - } - - if ( parse_plmns(all_plmn_setting, &networks) == false ) { - return false; - } - - for (int i = 0; i < ue_nb; i++) { - emm_nvdata_t emm_data; - - user_nvdata_t user_data; - user_data_conf_t user_data_conf; - - usim_data_t usim_data; - usim_data_conf_t usim_data_conf; - - user_plmns_t user_plmns; - - sprintf(user, "%s%d", UE, i); - - ue_setting = config_setting_get_member(root_setting, user); - if (ue_setting == NULL) { - printf("Check UE%d settings\n", i); - return false; - } - - if ( parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn, networks) == false ) { - return false; - } - - rc = parse_ue_user_data(ue_setting, i, &user_data_conf); - if (rc != true) { - printf("Problem in USER section for UE%d. EXITING...\n", i); - return false; - } - gen_user_data(&user_data_conf, &user_data); - write_user_data(output_dir, i, &user_data); - - rc = parse_ue_sim_param(ue_setting, i, &usim_data_conf); - if (rc != true) { - printf("Problem in SIM section for UE%d. EXITING...\n", i); - return false; - } - gen_usim_data(&usim_data_conf, &usim_data, &user_plmns, networks); - write_usim_data(output_dir, i, &usim_data); - - gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, - user_plmns.equivalents_home.size, networks); - write_emm_data(output_dir, i, &emm_data); - - user_plmns_free(&user_plmns); - - } - free(networks.items); - networks.size=0; - config_destroy(&cfg); - return(true); -} - -bool get_config_from_file(const char *filename, config_t *config) { - config_init(config); - if (filename == NULL) { - // XXX write error message ? - return(false); - } - - /* Read the file. If there is an error, report it and exit. */ - if (!config_read_file(config, filename)) { - fprintf(stderr, "Cant read config file '%s': %s\n", filename, - config_error_text(config)); - if ( config_error_type(config) == CONFIG_ERR_PARSE ) { - fprintf(stderr, "This is line %d\n", config_error_line(config)); - } - config_destroy(config); - return (false); - } - return true; -} - /* * Displays command line usage */ diff --git a/openair3/NAS/TOOLS/conf2uedata.h b/openair3/NAS/TOOLS/conf2uedata.h index b97116eaa9..ed56a22718 100644 --- a/openair3/NAS/TOOLS/conf2uedata.h +++ b/openair3/NAS/TOOLS/conf2uedata.h @@ -1,16 +1,6 @@ #ifndef _CONF2UEDATA_H #define _CONF2UEDATA_H -#include - -#include "usim_api.h" -#include "conf_network.h" - -#define UE "UE" - -bool get_config_from_file(const char *filename, config_t *config); -bool parse_config_file(const char *output_dir, const char *filename); - void _display_usage(void); #endif // _CONF2UEDATA_H diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h index 32506acdb5..a7b97c5da2 100644 --- a/openair3/NAS/TOOLS/conf_emm.h +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -1,8 +1,8 @@ #ifndef _CONF_EMM_H #define _CONF_EMM_H -#include "conf2uedata.h" #include "emmData.h" +#include "conf_network.h" void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count, const networks_t networks); bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); diff --git a/openair3/NAS/TOOLS/conf_parser.c b/openair3/NAS/TOOLS/conf_parser.c new file mode 100644 index 0000000000..816c5c6ec9 --- /dev/null +++ b/openair3/NAS/TOOLS/conf_parser.c @@ -0,0 +1,110 @@ +#include "conf_parser.h" + +#include "conf_network.h" +#include "conf_emm.h" +#include "conf_usim.h" +#include "conf_user_data.h" +#include "conf_user_plmn.h" + +bool parse_config_file(const char *output_dir, const char *conf_filename) { + int rc = true; + int ret; + int ue_nb = 0; + config_setting_t *root_setting = NULL; + config_setting_t *ue_setting = NULL; + config_setting_t *all_plmn_setting = NULL; + char user[10]; + config_t cfg; + + networks_t networks;; + + ret = get_config_from_file(conf_filename, &cfg); + if (ret == false) { + exit(1); + } + + root_setting = config_root_setting(&cfg); + ue_nb = config_setting_length(root_setting) - 1; + + all_plmn_setting = config_setting_get_member(root_setting, PLMN); + if (all_plmn_setting == NULL) { + printf("NO PLMN SECTION...EXITING...\n"); + return (false); + } + + if ( parse_plmns(all_plmn_setting, &networks) == false ) { + return false; + } + + for (int i = 0; i < ue_nb; i++) { + emm_nvdata_t emm_data; + + user_nvdata_t user_data; + user_data_conf_t user_data_conf; + + usim_data_t usim_data; + usim_data_conf_t usim_data_conf; + + user_plmns_t user_plmns; + + sprintf(user, "%s%d", UE, i); + + ue_setting = config_setting_get_member(root_setting, user); + if (ue_setting == NULL) { + printf("Check UE%d settings\n", i); + return false; + } + + if ( parse_user_plmns_conf(ue_setting, i, &user_plmns, &usim_data_conf.hplmn, networks) == false ) { + return false; + } + + rc = parse_ue_user_data(ue_setting, i, &user_data_conf); + if (rc != true) { + printf("Problem in USER section for UE%d. EXITING...\n", i); + return false; + } + gen_user_data(&user_data_conf, &user_data); + write_user_data(output_dir, i, &user_data); + + rc = parse_ue_sim_param(ue_setting, i, &usim_data_conf); + if (rc != true) { + printf("Problem in SIM section for UE%d. EXITING...\n", i); + return false; + } + gen_usim_data(&usim_data_conf, &usim_data, &user_plmns, networks); + write_usim_data(output_dir, i, &usim_data); + + gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, + user_plmns.equivalents_home.size, networks); + write_emm_data(output_dir, i, &emm_data); + + user_plmns_free(&user_plmns); + + } + free(networks.items); + networks.size=0; + config_destroy(&cfg); + return(true); +} + +bool get_config_from_file(const char *filename, config_t *config) { + config_init(config); + if (filename == NULL) { + // XXX write error message ? + return(false); + } + + /* Read the file. If there is an error, report it and exit. */ + if (!config_read_file(config, filename)) { + fprintf(stderr, "Cant read config file '%s': %s\n", filename, + config_error_text(config)); + if ( config_error_type(config) == CONFIG_ERR_PARSE ) { + fprintf(stderr, "This is line %d\n", config_error_line(config)); + } + config_destroy(config); + return (false); + } + return true; +} + diff --git a/openair3/NAS/TOOLS/conf_parser.h b/openair3/NAS/TOOLS/conf_parser.h new file mode 100644 index 0000000000..4e160ab73a --- /dev/null +++ b/openair3/NAS/TOOLS/conf_parser.h @@ -0,0 +1,12 @@ +#ifndef _CONF_PARSER_H +#define _CONF_PARSER_H + +#include +#include + +#define UE "UE" + +bool get_config_from_file(const char *filename, config_t *config); +bool parse_config_file(const char *output_dir, const char *filename); + +#endif diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c index 5418f01932..5004363275 100644 --- a/openair3/NAS/TOOLS/conf_usim.c +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -5,7 +5,6 @@ #include "utils.h" #include "conf_emm.h" #include "fs.h" -#include "conf2uedata.h" #include "conf_usim.h" bool parse_ue_sim_param(config_setting_t *ue_setting, int user_id, usim_data_conf_t *u) { From af4027660ba597fb89cb1c00615898818d8046da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Wed, 24 Aug 2016 11:50:53 +0200 Subject: [PATCH 212/571] feat(conf2uedata): add a selector for writing files --- openair3/NAS/TOOLS/conf2uedata.c | 2 +- openair3/NAS/TOOLS/conf_parser.c | 17 +++++++++++++---- openair3/NAS/TOOLS/conf_parser.h | 7 ++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index b162979dc2..ad15d1bb4f 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -42,7 +42,7 @@ int main(int argc, char**argv) { exit(1); } - if ( parse_config_file(output_dir, conf_file) == false ) { + if ( parse_config_file(output_dir, conf_file, OUTPUT_ALL) == false ) { exit(1); } diff --git a/openair3/NAS/TOOLS/conf_parser.c b/openair3/NAS/TOOLS/conf_parser.c index 816c5c6ec9..e7d1240fad 100644 --- a/openair3/NAS/TOOLS/conf_parser.c +++ b/openair3/NAS/TOOLS/conf_parser.c @@ -6,7 +6,7 @@ #include "conf_user_data.h" #include "conf_user_plmn.h" -bool parse_config_file(const char *output_dir, const char *conf_filename) { +bool parse_config_file(const char *output_dir, const char *conf_filename, int output_flags) { int rc = true; int ret; int ue_nb = 0; @@ -65,7 +65,6 @@ bool parse_config_file(const char *output_dir, const char *conf_filename) { return false; } gen_user_data(&user_data_conf, &user_data); - write_user_data(output_dir, i, &user_data); rc = parse_ue_sim_param(ue_setting, i, &usim_data_conf); if (rc != true) { @@ -73,11 +72,21 @@ bool parse_config_file(const char *output_dir, const char *conf_filename) { return false; } gen_usim_data(&usim_data_conf, &usim_data, &user_plmns, networks); - write_usim_data(output_dir, i, &usim_data); gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, user_plmns.equivalents_home.size, networks); - write_emm_data(output_dir, i, &emm_data); + + if ( output_flags & OUTPUT_UEDATA ) { + write_user_data(output_dir, i, &user_data); + } + + if ( output_flags & OUTPUT_USIM ) { + write_usim_data(output_dir, i, &usim_data); + } + + if ( output_flags & OUTPUT_EMM ) { + write_emm_data(output_dir, i, &emm_data); + } user_plmns_free(&user_plmns); diff --git a/openair3/NAS/TOOLS/conf_parser.h b/openair3/NAS/TOOLS/conf_parser.h index 4e160ab73a..49d3645faf 100644 --- a/openair3/NAS/TOOLS/conf_parser.h +++ b/openair3/NAS/TOOLS/conf_parser.h @@ -6,7 +6,12 @@ #define UE "UE" +#define OUTPUT_EMM 1 +#define OUTPUT_USIM 2 +#define OUTPUT_UEDATA 4 +#define OUTPUT_ALL 7 + bool get_config_from_file(const char *filename, config_t *config); -bool parse_config_file(const char *output_dir, const char *filename); +bool parse_config_file(const char *output_dir, const char *filename, int output_flags); #endif From 747cea249bd87d6320e52a9e94b04444a53fe9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 26 Aug 2016 11:49:43 +0200 Subject: [PATCH 213/571] feat(conf2uedata): add a selector for displaying files --- openair3/NAS/TOOLS/conf2uedata.c | 4 +-- openair3/NAS/TOOLS/display.c | 56 ++++++++++++++++++++++---------- openair3/NAS/TOOLS/display.h | 9 ++++- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/openair3/NAS/TOOLS/conf2uedata.c b/openair3/NAS/TOOLS/conf2uedata.c index ad15d1bb4f..80a6933c05 100644 --- a/openair3/NAS/TOOLS/conf2uedata.c +++ b/openair3/NAS/TOOLS/conf2uedata.c @@ -46,7 +46,7 @@ int main(int argc, char**argv) { exit(1); } - display_data_from_directory(output_dir); + display_data_from_directory(output_dir, DISPLAY_ALL); exit(0); } @@ -55,7 +55,7 @@ int main(int argc, char**argv) { * Displays command line usage */ void _display_usage(void) { - fprintf(stderr, "usage: conf2uedata [OPTION] [directory] ...\n"); + fprintf(stderr, "usage: conf2uedata [OPTION]...\n"); fprintf(stderr, "\t[-c]\tConfig file to use\n"); fprintf(stderr, "\t[-o]\toutput file directory\n"); fprintf(stderr, "\t[-h]\tDisplay this usage\n"); diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c index 672a9950de..fdd2ad7670 100644 --- a/openair3/NAS/TOOLS/display.c +++ b/openair3/NAS/TOOLS/display.c @@ -28,29 +28,49 @@ PRINT_PLMN_DIGIT((plmn).MNCdigit2); \ PRINT_PLMN_DIGIT((plmn).MNCdigit3) -void display_data_from_directory(const char *directory) { - int user_id = 0; - char *filename; +// return number of files displayed +int display_data_from_directory(const char *directory, int flags) { + int user_id = 0; + char *filename; + bool found = true; + int displayed_count = 0; - filename = get_ue_filename(directory, user_id); - while ( file_exist_and_is_readable(filename) ) { + while ( found ) { + found = false; - display_ue_data(filename); - free(filename); + if ( flags & DISPLAY_UEDATA ) { + filename = get_ue_filename(directory, user_id); + if ( file_exist_and_is_readable(filename) ) { + display_ue_data(filename); + displayed_count += 1; + found = true; + } + free(filename); + } - filename = get_emm_filename(directory, user_id); - display_emm_data(filename); - free(filename); + if ( flags & DISPLAY_EMM ) { + filename = get_emm_filename(directory, user_id); + if ( file_exist_and_is_readable(filename) ) { + display_emm_data(filename); + displayed_count += 1; + found = true; + } + free(filename); + } - filename = get_usim_filename(directory, user_id); - display_usim_data(filename); - free(filename); + if ( flags & DISPLAY_USIM ) { + filename = get_usim_filename(directory, user_id); + if ( file_exist_and_is_readable(filename) ) { + display_usim_data(filename); + displayed_count += 1; + found = true; + } + free(filename); + } - - user_id += 1; - filename = get_ue_filename(directory, user_id); - } - free(filename); + user_id += 1; + } + return displayed_count; } void display_ue_data(const char *filename) { diff --git a/openair3/NAS/TOOLS/display.h b/openair3/NAS/TOOLS/display.h index fd4f4ff1e3..fef721c490 100644 --- a/openair3/NAS/TOOLS/display.h +++ b/openair3/NAS/TOOLS/display.h @@ -1,7 +1,14 @@ #ifndef _DISPLAY_H #define _DISPLAY_H -void display_data_from_directory(const char *directory); +#define DISPLAY_EMM 1 +#define DISPLAY_USIM 2 +#define DISPLAY_UEDATA 4 +#define DISPLAY_ALL 7 + +// return number of files displayed +int display_data_from_directory(const char *directory, int flags); + void display_ue_data(const char *filename); void display_emm_data(const char *filename); void display_usim_data(const char *filename); From 95503ffd52b7a150bb3e35257ad8eb028fca4084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 26 Aug 2016 11:52:36 +0200 Subject: [PATCH 214/571] fix(conf2uedata): update ue_eurecom_test_sfr.conf to match openair develop branch --- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index 42d174bbbf..e12793c970 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -86,20 +86,20 @@ UE0: }; SIM: { - MSIN="0000001234"; + MSIN="0100001111"; USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; OPC="00000000000000000000000000000000"; MSISDN="33611123456"; }; # Home PLMN Selector with Access Technology - HPLMN= "20810"; + HPLMN= "20893"; # User controlled PLMN Selector with Access Technology UCPLMN_LIST = (); # Operator PLMN List - OPLMN_LIST = ("00101", "20810", "20811", "20813", "310280", "310028"); + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20893", "310280", "310028"); # Operator controlled PLMN Selector with Access Technology OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); From d8aa8d4a6472b6d738a5cd2b92c672e8ef59c5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 26 Aug 2016 11:55:12 +0200 Subject: [PATCH 215/571] fix(conf2uedata): update INT_ALGO to match openair develop branch --- openair3/NAS/TOOLS/conf_usim.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair3/NAS/TOOLS/conf_usim.h b/openair3/NAS/TOOLS/conf_usim.h index b53265a76a..4768a6d8c0 100644 --- a/openair3/NAS/TOOLS/conf_usim.h +++ b/openair3/NAS/TOOLS/conf_usim.h @@ -27,7 +27,8 @@ #define DEFAULT_MME_ID 0x0102 #define DEFAULT_MME_CODE 0x0F -#define INT_ALGO USIM_INT_EIA1 +// TODO add this setting in configuration file +#define INT_ALGO USIM_INT_EIA2 #define ENC_ALGO USIM_ENC_EEA0 #define SECURITY_ALGORITHMS (ENC_ALGO | INT_ALGO) From e439a24f03707d4ef5ba0c84d0e4f4c7cb536492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 26 Aug 2016 14:00:31 +0200 Subject: [PATCH 216/571] feat(conf2uedata): print USIM filename on display --- openair3/NAS/TOOLS/display.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c index fdd2ad7670..287679820d 100644 --- a/openair3/NAS/TOOLS/display.c +++ b/openair3/NAS/TOOLS/display.c @@ -42,7 +42,7 @@ int display_data_from_directory(const char *directory, int flags) { filename = get_ue_filename(directory, user_id); if ( file_exist_and_is_readable(filename) ) { display_ue_data(filename); - displayed_count += 1; + displayed_count += 1; found = true; } free(filename); @@ -52,7 +52,7 @@ int display_data_from_directory(const char *directory, int flags) { filename = get_emm_filename(directory, user_id); if ( file_exist_and_is_readable(filename) ) { display_emm_data(filename); - displayed_count += 1; + displayed_count += 1; found = true; } free(filename); @@ -62,15 +62,16 @@ int display_data_from_directory(const char *directory, int flags) { filename = get_usim_filename(directory, user_id); if ( file_exist_and_is_readable(filename) ) { display_usim_data(filename); - displayed_count += 1; + displayed_count += 1; found = true; + printf("USIM data file: %s\n", filename); } free(filename); } user_id += 1; } - return displayed_count; + return displayed_count; } void display_ue_data(const char *filename) { From 30fde6bfe260677a5dd08b0e64d8e2470b06860d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 26 Aug 2016 14:01:03 +0200 Subject: [PATCH 217/571] feat(conf2uedata): reintroduce usim binary --- cmake_targets/nas_sim_tools/CMakeLists.txt | 23 ++- openair3/NAS/TOOLS/usim.c | 169 +++++++++++++++++++++ 2 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 openair3/NAS/TOOLS/usim.c diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 025c35c441..a57dd119c7 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -15,8 +15,7 @@ set(CMAKE_C_FLAGS set(OPENAIR_DIR $ENV{OPENAIR_DIR}) set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3) -set(conf2uedata_SRC - ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c +set(CONF2UEDATA_LIB_SRC ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c @@ -58,5 +57,23 @@ include_directories( ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL ) -ADD_EXECUTABLE(conf2uedata ${conf2uedata_SRC} ${conf2uedata_HDR}) +# conf2uedata binary + +set(conf2uedata_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c + ${CONF2UEDATA_LIB_SRC} +) + +add_executable(conf2uedata ${conf2uedata_SRC} ${conf2uedata_HDR} ) target_link_libraries(conf2uedata ${CONFIG_LIBRARIES}) + +# usim binary + +set(usim_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/usim.c + ${CONF2UEDATA_LIB_SRC} +) + + +add_executable(usim ${usim_SRC} ${conf2uedata_HDR} ) +target_link_libraries(usim ${CONFIG_LIBRARIES}) diff --git a/openair3/NAS/TOOLS/usim.c b/openair3/NAS/TOOLS/usim.c new file mode 100644 index 0000000000..53aefb4a2c --- /dev/null +++ b/openair3/NAS/TOOLS/usim.c @@ -0,0 +1,169 @@ +/******************************************************************************* + 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 . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ +/***************************************************************************** +Source usim_data.c + +Version 0.1 + +Date 2012/10/31 + +Product USIM data generator + +Subsystem USIM data generator main process + +Author Frederic Maurel + +Description Implements the utility used to generate data stored in the + USIM application + + *****************************************************************************/ + +#include +#include +#include +#include + +#include "conf_parser.h" +#include "display.h" + +#define DEFAULT_NAS_PATH "PWD" +#define OUTPUT_DIR_ENV "USIM_DIR" +void _display_usage(const char* command); + +int main (int argc, char * const argv[]) +{ + enum usim_command { + USIM_COMMAND_NONE, + USIM_COMMAND_PRINT, + USIM_COMMAND_GEN, + } command = USIM_COMMAND_NONE; + + char *output_dir = NULL; + char *conf_file = NULL; + const char options[]="gpc:o:h"; + const struct option options_long_option[] = { + {"gen", no_argument, NULL, 'g'}, + {"print", no_argument, NULL, 'p'}, + {"conf", required_argument, NULL, 'c'}, + {"output", required_argument, NULL, 'o'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + int option_index; + char option_short; + + /* + * Read command line parameters + */ + while ( true ) { + option_short = getopt_long(argc, argv, options, options_long_option, &option_index ); + + if ( option_short == -1 ) + break; + + switch (option_short) { + case 'c': + conf_file = optarg; + break; + case 'g': + command = USIM_COMMAND_GEN; + break; + case 'p': + command = USIM_COMMAND_PRINT; + break; + case 'o': + output_dir = optarg; + break; + default: + break; + } + } + + if ( command == USIM_COMMAND_NONE ) { + _display_usage(argv[0]); + exit(EXIT_SUCCESS); + } + + /* compute default data directory if no output_dir is given */ + if ( output_dir == NULL ) { + output_dir = getenv(OUTPUT_DIR_ENV); + + if (output_dir == NULL) { + output_dir = getenv(DEFAULT_NAS_PATH); + } + + if (output_dir == NULL) { + fprintf(stderr, "%s and %s environment variables are not defined trying local directory", + OUTPUT_DIR_ENV, DEFAULT_NAS_PATH); + output_dir = "."; + } + } + + if ( command == USIM_COMMAND_GEN ) { + if ( conf_file == NULL ) { + printf("No Configuration file is given\n"); + _display_usage(argv[0]); + exit(EXIT_FAILURE); + } + + if ( parse_config_file(output_dir, conf_file, OUTPUT_USIM) == false ) { + exit(EXIT_FAILURE); + } + } + + if ( display_data_from_directory(output_dir, DISPLAY_USIM) == 0) { + fprintf(stderr, "No USIM files found in %s\n", output_dir); + } + + exit(EXIT_SUCCESS); +} + +/****************************************************************************/ +/********************* L O C A L F U N C T I O N S *********************/ +/****************************************************************************/ + +/* + * Displays command line usage + */ +void _display_usage(const char* command) +{ + fprintf(stderr, "usage: %s [OPTION]\n", command); + fprintf(stderr, "\t[--gen|-g]\tGenerate the USIM data file\n"); + fprintf(stderr, "\t[--print|-p]\tDisplay the content of the USIM data file\n"); + fprintf(stderr, "\t[-c]\tConfig file to use\n"); + fprintf(stderr, "\t[-o]\toutput file directory\n"); + fprintf(stderr, "\t[--help|-h]\tDisplay this usage\n"); + const char* path = getenv("USIM_DIR"); + + if (path != NULL) { + fprintf(stderr, "USIM_DIR = %s\n", path); + } else { + fprintf(stderr, "USIM_DIR environment variable is not defined\n"); + } +} From 3d0fbc00a1d7fcd2ecf55ad7f82bf244ad5246fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 26 Aug 2016 15:13:07 +0200 Subject: [PATCH 218/571] feat(conf2uedata): reintroduce nvram binary --- cmake_targets/nas_sim_tools/CMakeLists.txt | 11 ++ openair3/NAS/TOOLS/display.c | 2 + openair3/NAS/TOOLS/nvram.c | 169 +++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 openair3/NAS/TOOLS/nvram.c diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index a57dd119c7..81e3fe4b3c 100644 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -77,3 +77,14 @@ set(usim_SRC add_executable(usim ${usim_SRC} ${conf2uedata_HDR} ) target_link_libraries(usim ${CONFIG_LIBRARIES}) + +# nvram binary + +set(nvram_SRC + ${OPENAIR_DIR}/openair3/NAS/TOOLS/nvram.c + ${CONF2UEDATA_LIB_SRC} +) + + +add_executable(nvram ${nvram_SRC} ${conf2uedata_HDR} ) +target_link_libraries(nvram ${CONFIG_LIBRARIES}) diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c index 287679820d..7d145d1f3b 100644 --- a/openair3/NAS/TOOLS/display.c +++ b/openair3/NAS/TOOLS/display.c @@ -44,6 +44,7 @@ int display_data_from_directory(const char *directory, int flags) { display_ue_data(filename); displayed_count += 1; found = true; + printf("UE identity data file: %s\n", filename); } free(filename); } @@ -54,6 +55,7 @@ int display_data_from_directory(const char *directory, int flags) { display_emm_data(filename); displayed_count += 1; found = true; + printf("EPS Mobility Management data file: %s\n", filename); } free(filename); } diff --git a/openair3/NAS/TOOLS/nvram.c b/openair3/NAS/TOOLS/nvram.c new file mode 100644 index 0000000000..2bf5f6ed82 --- /dev/null +++ b/openair3/NAS/TOOLS/nvram.c @@ -0,0 +1,169 @@ +/******************************************************************************* + 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 . + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ +/***************************************************************************** +Source usim_data.c + +Version 0.1 + +Date 2012/10/31 + +Product NVRAM data generator + +Subsystem NVRAM data generator main process + +Author Frederic Maurel + +Description Implements the utility used to generate data stored in the + NVRAM application + + *****************************************************************************/ + +#include +#include +#include +#include + +#include "conf_parser.h" +#include "display.h" + +#define DEFAULT_NAS_PATH "PWD" +#define OUTPUT_DIR_ENV "NVRAM_DIR" +void _display_usage(const char* command); + +int main (int argc, char * const argv[]) +{ + enum usim_command { + NVRAM_COMMAND_NONE, + NVRAM_COMMAND_PRINT, + NVRAM_COMMAND_GEN, + } command = NVRAM_COMMAND_NONE; + + char *output_dir = NULL; + char *conf_file = NULL; + const char options[]="gpc:o:h"; + const struct option options_long_option[] = { + {"gen", no_argument, NULL, 'g'}, + {"print", no_argument, NULL, 'p'}, + {"conf", required_argument, NULL, 'c'}, + {"output", required_argument, NULL, 'o'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0} + }; + int option_index; + char option_short; + + /* + * Read command line parameters + */ + while ( true ) { + option_short = getopt_long(argc, argv, options, options_long_option, &option_index ); + + if ( option_short == -1 ) + break; + + switch (option_short) { + case 'c': + conf_file = optarg; + break; + case 'g': + command = NVRAM_COMMAND_GEN; + break; + case 'p': + command = NVRAM_COMMAND_PRINT; + break; + case 'o': + output_dir = optarg; + break; + default: + break; + } + } + + if ( command == NVRAM_COMMAND_NONE ) { + _display_usage(argv[0]); + exit(EXIT_SUCCESS); + } + + /* compute default data directory if no output_dir is given */ + if ( output_dir == NULL ) { + output_dir = getenv(OUTPUT_DIR_ENV); + + if (output_dir == NULL) { + output_dir = getenv(DEFAULT_NAS_PATH); + } + + if (output_dir == NULL) { + fprintf(stderr, "%s and %s environment variables are not defined trying local directory", + OUTPUT_DIR_ENV, DEFAULT_NAS_PATH); + output_dir = "."; + } + } + + if ( command == NVRAM_COMMAND_GEN ) { + if ( conf_file == NULL ) { + printf("No Configuration file is given\n"); + _display_usage(argv[0]); + exit(EXIT_FAILURE); + } + + if ( parse_config_file(output_dir, conf_file, OUTPUT_UEDATA|OUTPUT_EMM) == false ) { + exit(EXIT_FAILURE); + } + } + + if ( display_data_from_directory(output_dir, DISPLAY_UEDATA|DISPLAY_EMM) == 0) { + fprintf(stderr, "No NVRAM files found in %s\n", output_dir); + } + + exit(EXIT_SUCCESS); +} + +/****************************************************************************/ +/********************* L O C A L F U N C T I O N S *********************/ +/****************************************************************************/ + +/* + * Displays command line usage + */ +void _display_usage(const char* command) +{ + fprintf(stderr, "usage: %s [OPTION]\n", command); + fprintf(stderr, "\t[--gen|-g]\tGenerate the NVRAM data file\n"); + fprintf(stderr, "\t[--print|-p]\tDisplay the content of the NVRAM data file\n"); + fprintf(stderr, "\t[-c]\tConfig file to use\n"); + fprintf(stderr, "\t[-o]\toutput file directory\n"); + fprintf(stderr, "\t[--help|-h]\tDisplay this usage\n"); + const char* path = getenv("NVRAM_DIR"); + + if (path != NULL) { + fprintf(stderr, "NVRAM_DIR = %s\n", path); + } else { + fprintf(stderr, "NVRAM_DIR environment variable is not defined\n"); + } +} From 3fdcf5b676124652c36f1b343370d6f94b246f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Leroy?= Date: Fri, 26 Aug 2016 15:24:11 +0200 Subject: [PATCH 219/571] feat(conf2uedata): uses nvram and usim binary This commit reverts behaviour of data generation as before commit 7207c65b05fd812a18371827f2bfb1431fc58696: fix .ue* filenames in scripts and documentation TODO add option to conf2uedata and adapt script --- cmake_targets/build_oai | 16 ++++++++++++++++ cmake_targets/tools/build_helper | 18 ++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index ea28a7131a..7c438aabd8 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -519,6 +519,12 @@ function main() { cd $DIR/nas_sim_tools/build cmake .. + compilations \ + nas_sim_tools usim \ + usim $dbin/usim + compilations \ + nas_sim_tools nvram \ + nvram $dbin/nvram compilations \ nas_sim_tools conf2uedata \ conf2uedata $dbin/conf2uedata @@ -526,6 +532,10 @@ function main() { # generate USIM data if [ -f $dbin/conf2uedata ]; then install_nas_tools $conf_nvram_path $gen_nvram_path + echo_info "Copying UE specific part to $DIR/$lte_build_dir/build" + cp -Rvf $dbin/.ue_emm.nvram0 $DIR/$lte_build_dir/build + cp -Rvf $dbin/.ue.nvram0 $DIR/$lte_build_dir/build + cp -Rvf $dbin/.usim.nvram0 $DIR/$lte_build_dir/build else echo_warning "not generated UE NAS files: binaries not found" fi @@ -641,6 +651,12 @@ function main() { mkdir -p $DIR/nas_sim_tools/build cd $DIR/nas_sim_tools/build cmake .. + compilations \ + nas_sim_tools usim \ + usim $dbin/usim + compilations \ + nas_sim_tools nvram \ + nvram $dbin/nvram compilations \ nas_sim_tools conf2uedata \ conf2uedata $dbin/conf2uedata diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 5d4a1dbeae..da3ef1c355 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -450,13 +450,23 @@ install_asn1c_from_source(){ ################################################ install_nas_tools() { - if [ ! -f $2/.ue.nvram0 -o ! -f $2/.usim.nvram0 ]; then - cd $OPENAIR_DIR/targets/bin - ./conf2uedata -c $1 -o $2 - echo_success "$1 $2" + if [ ! -f .ue.nvram0 ]; then + echo_success "generate .ue_emm.nvram .ue.nvram" + ./nvram --gen -c $1 -o $2 + else + [ ./nvram -nt .ue.nvram0 -o ./nvram -nt .ue_emm.nvram0 ] && ./nvram --gen -c $1 -o $2 fi + + if [ ! -f .usim.nvram0 ]; then + echo_success "generate .usim.nvram" + ./usim --gen -c $1 -o $2 + else + [ ./usim -nt .usim.nvram0 ] && ./usim --gen -c $1 -o $2 + fi + } + ################################ # set_openair_env ############################### From a731de2f133f966dc82783e3feb8837a14054308 Mon Sep 17 00:00:00 2001 From: Imad ALAWE Date: Tue, 21 Jun 2016 13:35:49 +0200 Subject: [PATCH 220/571] openair2: fix abstraction mode for oaisim with MME When using abstraction mode, layer2_init_UE() and openair_rrc_ue_init() are called according to first_sync state and only without MME support. We added the global variable abstraction_flag to allow abstraction mode when MME is enabled. Openair2 is also used in lte-softmodem, so it must have a global variable abstraction_flag. So we moved it out from the main() scope. --- openair2/LAYER2/MAC/main.c | 12 +++++++----- targets/RT/USER/lte-softmodem.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index d812ec0087..a879fb8146 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -62,24 +62,26 @@ #endif //PHY_EMUL #include "SCHED/defs.h" - +extern uint8_t abstraction_flag; void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR { LOG_D(MAC,"[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", module_idP, frameP, eNB_index); -#if ! defined(ENABLE_USE_MME) +#if defined(ENABLE_USE_MME) + int mme_enabled=1; +#else + int mme_enabled=0; +#endif - if (first_sync==1) { + if (first_sync==1 && !(mme_enabled==1 && abstraction_flag==0)) { layer2_init_UE(module_idP); openair_rrc_ue_init(module_idP,eNB_index); } else -#endif { rrc_in_sync_ind(module_idP,frameP,eNB_index); } - } void mrbch_phy_sync_failure(module_id_t module_idP, frame_t frameP, uint8_t free_eNB_index) //init as CH diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 6a2aa28d7a..f09d93bf36 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -121,6 +121,27 @@ extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openai extern void fill_ue_band_info(void); extern void init_UE(int); +struct timing_info_t { + //unsigned int frame, hw_slot, last_slot, next_slot; + RTIME time_min, time_max, time_avg, time_last, time_now; + //unsigned int mbox0, mbox1, mbox2, mbox_target; + unsigned int n_samples; +} timing_info; + +uint8_t abstraction_flag=0; + +openair0_config_t openair0_cfg[MAX_CARDS]; + +int32_t **rxdata; +int32_t **txdata; +int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); +int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); + +uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] +uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] +double cpuf; + +void fill_ue_band_info(void); #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE @@ -1395,7 +1416,12 @@ int main( int argc, char **argv ) #endif int CC_id; +<<<<<<< 3fdcf5b676124652c36f1b343370d6f94b246f5c uint8_t abstraction_flag=0; +======= + uint16_t Nid_cell = 0; + uint8_t cooperation_flag=0; +>>>>>>> openair2: fix abstraction mode for oaisim with MME uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; #if defined (XFORMS) From b3ded7799a8326434be597d860bc468e958f384d Mon Sep 17 00:00:00 2001 From: Imad ALAWE Date: Wed, 22 Jun 2016 12:00:29 +0200 Subject: [PATCH 221/571] openairinterface5g: Fix multi definition of UE/eNB NB_MAX In openairinterface5g many definitions in many layers of UE or eNB NB_MAX. We created a file called openairinterface5g_limits.h located at openairinterface5g_dir/targets/COMMON/ declaring the number max of UE and eNB to be used in ALL layers depending on launching conditions (LARGE_SCALE for example). --- cmake_targets/at_commands/CMakeLists.txt | 3 +++ openair1/PHY/impl_defs_top.h | 16 +--------------- openair2/NETWORK_DRIVER/UE_IP/constant.h | 3 ++- openair2/UTIL/OMV/structures.h | 11 +++++------ openair2/UTIL/OTG/otg_defs.h | 8 ++++---- openair3/NAS/UE/nas_ue_task.h | 3 +-- targets/COMMON/openairinterface5g_limits.h | 20 ++++++++++++++++++++ 7 files changed, 36 insertions(+), 28 deletions(-) create mode 100644 targets/COMMON/openairinterface5g_limits.h diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index bf964cec46..8993466bc2 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -452,6 +452,7 @@ set(esm_SRC ) set(esm_HDR + ${OPENAIR_TARGETS}/COMMON/openairinterface5g_limits.h ${OPENAIR_NAS_DIR}/UE/ESM/esm_main.h ${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.h ${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.h @@ -491,6 +492,7 @@ target_include_directories(esm PRIVATE ${OPENAIR_NAS_DIR}/UE ${OPENAIR_NAS_DIR}/UE/API/USER ${OPENAIR_NAS_DIR}/UE/ESM + ${OPENAIR_TARGETS}/COMMON ${OPENAIR_NAS_DIR}/COMMON/ESM/MSG ${OPENAIR_NAS_DIR}/UE/ESM/SAP ${OPENAIR_NAS_DIR}/COMMON/IES @@ -673,6 +675,7 @@ target_include_directories(ies PRIVATE # EXECUTABLE at_nas_ue ################################################################################ include_directories( + ${OPENAIR_TARGETS}/COMMON ${OPENAIR_NAS_DIR}/UE ${OPENAIR_DIR}/common/utils ${OPENAIR_DIR}/common/utils/msc diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index dd09749fbf..4ef0131516 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -284,21 +284,7 @@ typedef enum { #define NUMBER_OF_HARQ_PID_MAX 8 #define MAX_FRAME_NUMBER 0x400 -#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) -#define NUMBER_OF_eNB_MAX 1 -#define NUMBER_OF_UE_MAX 16 -#define NUMBER_OF_CONNECTED_eNB_MAX 3 -#else -#ifdef LARGE_SCALE -#define NUMBER_OF_eNB_MAX 2 -#define NUMBER_OF_UE_MAX 120 -#define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory -#else -#define NUMBER_OF_eNB_MAX 7 -#define NUMBER_OF_UE_MAX 16 -#define NUMBER_OF_CONNECTED_eNB_MAX 3 -#endif -#endif +#include "openairinterface5g_limits.h" #define NUMBER_OF_RN_MAX 3 typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t; diff --git a/openair2/NETWORK_DRIVER/UE_IP/constant.h b/openair2/NETWORK_DRIVER/UE_IP/constant.h index 9b4017773b..42fd0b6303 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/constant.h +++ b/openair2/NETWORK_DRIVER/UE_IP/constant.h @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include "openairinterface5g_limits.h" #ifndef _UE_IP_CST #define _UE_IP_CST @@ -51,7 +52,7 @@ -#define UE_IP_NB_INSTANCES_MAX 8 +#define UE_IP_NB_INSTANCES_MAX NUMBER_OF_UE_MAX #endif diff --git a/openair2/UTIL/OMV/structures.h b/openair2/UTIL/OMV/structures.h index c50e7b2297..434fa4c383 100644 --- a/openair2/UTIL/OMV/structures.h +++ b/openair2/UTIL/OMV/structures.h @@ -31,13 +31,12 @@ #ifndef STRUCTURES_H #define STRUCTURES_H +#include "openairinterface5g_limits.h" #ifndef __PHY_IMPLEMENTATION_DEFS_H__ -#define Maxneighbor 64 -#define NUMBER_OF_UE_MAX 64 -#define NUMBER_OF_eNB_MAX 3 -#ifndef NB_ANTENNAS_RX -# define NB_ANTENNAS_RX 4 -#endif + #define Maxneighbor NUMBER_OF_UE_MAX + #ifndef NB_ANTENNAS_RX + #define NB_ANTENNAS_RX 4 + #endif #endif // diff --git a/openair2/UTIL/OTG/otg_defs.h b/openair2/UTIL/OTG/otg_defs.h index 0cef777b8f..ebb3f29989 100644 --- a/openair2/UTIL/OTG/otg_defs.h +++ b/openair2/UTIL/OTG/otg_defs.h @@ -33,12 +33,12 @@ #ifndef __OTG_DEFS_H__ # define __OTG_DEFS_H__ - +/* \brief To define the NUMBER_OF_eNB_MAX and NUMBER_OF_UE_MAX */ #if STANDALONE==1 -# define NUMBER_OF_eNB_MAX 3 -# define NUMBER_OF_UE_MAX 3 + #include "openairinterface5g_limits.h" #else -#include "PHY/impl_defs_top.h" /* \brief To define the NUMBER_OF_eNB_MAX and NUMBER_OF_UE_MAX */ + // impl_defs_top.h includes openairinterface5g_limits.h + #include "PHY/impl_defs_top.h" #endif #include "otg_config.h" diff --git a/openair3/NAS/UE/nas_ue_task.h b/openair3/NAS/UE/nas_ue_task.h index 4c7cd14249..90ef26bd80 100644 --- a/openair3/NAS/UE/nas_ue_task.h +++ b/openair3/NAS/UE/nas_ue_task.h @@ -22,8 +22,7 @@ #ifndef NAS_UE_TASK_H_ #define NAS_UE_TASK_H_ -// FIXME There is multiple definition of NUMBER_OF_UE_MAX -#include "defs.h" +#include "openairinterface5g_limits.h" #include "user_defs.h" // XXX simple array container for multiple users diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h new file mode 100644 index 0000000000..6185dd8bbe --- /dev/null +++ b/targets/COMMON/openairinterface5g_limits.h @@ -0,0 +1,20 @@ +#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) + #define NUMBER_OF_eNB_MAX 1 + #define NUMBER_OF_UE_MAX 16 + #define NUMBER_OF_CONNECTED_eNB_MAX 3 +#else + #define NUMBER_OF_eNB_MAX 7 + #define NUMBER_OF_UE_MAX 20 + #define NUMBER_OF_CONNECTED_eNB_MAX 3 + + #if STANDALONE==1 + #define NUMBER_OF_eNB_MAX 3 + #define NUMBER_OF_UE_MAX 3 + #endif + + #if LARGE_SCALE + #define NUMBER_OF_eNB_MAX 2 + #define NUMBER_OF_UE_MAX 120 + #define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory + #endif +#endif From 8bff2cff3e8f5a25fbacab1c56dbd86bdf5158be Mon Sep 17 00:00:00 2001 From: Imad ALAWE Date: Fri, 1 Jul 2016 15:49:12 +0200 Subject: [PATCH 222/571] BUGFIX(GTP-U): Add missing ip rules in order to have point to point connection --- cmake_targets/tools/run_enb_ue_virt_s1 | 6 ------ .../ESM/DedicatedEpsBearerContextActivation.c | 2 +- .../ESM/DefaultEpsBearerContextActivation.c | 2 +- openair3/NAS/UE/ESM/esm_ebr_context.c | 20 ++++++++++++------- openair3/NAS/UE/ESM/esm_ebr_context.h | 2 +- targets/SIMU/USER/oaisim.c | 3 +++ 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/cmake_targets/tools/run_enb_ue_virt_s1 b/cmake_targets/tools/run_enb_ue_virt_s1 index ecd5993ff4..ff65946803 100755 --- a/cmake_targets/tools/run_enb_ue_virt_s1 +++ b/cmake_targets/tools/run_enb_ue_virt_s1 @@ -247,12 +247,6 @@ function main() if [ $? -ne 0 ]; then echo "200 lte " >> /etc/iproute2/rt_tables fi - ip rule add fwmark 1 table lte - ifconfig oip1 up - ip route add default dev oip1 table lte - # the actual IP address depends on the EPC/MME config file for address pool - ip route add from 192.188.0.0/24 table lte - ip route add to 192.188.0.0/24 table lte exe_arguments="$exe_arguments -s15 -AAWGN -y1 -b1 -u1 -Q0" diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 3a32d3040d..e213356332 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -165,7 +165,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int *esm_cause = ESM_CAUSE_SYNTACTICAL_ERROR_IN_PACKET_FILTER; } else { /* Create new dedicated EPS bearer context */ - default_ebi = esm_ebr_context_create(esm_data, pid, ebi, FALSE, qos, tft); + default_ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, FALSE, qos, tft); if (default_ebi != ESM_EBI_UNASSIGNED) { /* Dedicated EPS bearer contextx successfully created */ diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 71421a475d..a438d65ddb 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -127,7 +127,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e if (ebi != ESM_EBI_UNASSIGNED) { /* Create new default EPS bearer context */ - ebi = esm_ebr_context_create(esm_data, pid, ebi, TRUE, qos, NULL); + ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, TRUE, qos, NULL); if (ebi != ESM_EBI_UNASSIGNED) { /* Default EPS bearer contextx successfully created */ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 4ce201260a..bfa4a04cc8 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -98,7 +98,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ** ** ***************************************************************************/ int esm_ebr_context_create( - esm_data_t *esm_data, + esm_data_t *esm_data, int ueid, int pid, int ebi, int is_default, const network_qos_t *qos, const network_tft_t *tft) { @@ -206,7 +206,7 @@ int esm_ebr_context_create( char *netmask = NULL; char broadcast[INET_ADDRSTRLEN]; struct in_addr in_addr; - char command_line[128]; + char command_line[500]; int res; switch (pdn->type) { @@ -272,11 +272,17 @@ int esm_ebr_context_create( } res = sprintf(command_line, - "ifconfig oip1 %s netmask %s broadcast %s", - ipv4_addr, netmask, broadcast); - (void)res; /* avoid gcc warning "set but not used" */ - // AssertFatal((res > 0) && (res < 128), - // "error in system command line"); + "ifconfig oip%d %s netmask %s broadcast %s up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev oip%d table %d", + ueid + 1, ipv4_addr, netmask, broadcast, + ipv4_addr, ueid + 201, + ipv4_addr, ueid + 201, + ueid + 1, ueid + 201); + if ( res<0 ) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); + } LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.h b/openair3/NAS/UE/ESM/esm_ebr_context.h index ceb6553846..a0016555a3 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.h +++ b/openair3/NAS/UE/ESM/esm_ebr_context.h @@ -66,7 +66,7 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_ebr_context_create(esm_data_t *esm_data, int pid, int ebi, int is_default, +int esm_ebr_context_create(esm_data_t *esm_data, int ueid, int pid, int ebi, int is_default, const network_qos_t *qos, const network_tft_t *tft); int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 3a06a62780..864ffc720e 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1886,6 +1886,9 @@ oai_shutdown (void) for (int i = 0; i < NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX; i++) if (oai_emulation.info.oai_ifup[i] == 1) { char interfaceName[8]; + char command_line[100]; + sprintf(command_line, "while ip rule del table %d; do true; done",i+201); + system(command_line); snprintf (interfaceName, sizeof(interfaceName), "oai%d", i); bringInterfaceUp (interfaceName, 0); } From d2e02ee2e67f6f0dd4d057267def34531d325ff2 Mon Sep 17 00:00:00 2001 From: Imad ALAWE Date: Mon, 4 Jul 2016 10:30:08 +0200 Subject: [PATCH 223/571] BUGFIX: Ip table clean when oaisim starts Ip table clean use to run on oaisim shutdown. It is moved to run on oaisim starts. --- targets/SIMU/USER/oaisim.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 864ffc720e..1d1e9c947b 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1218,6 +1218,12 @@ main (int argc, char **argv) //Default values if not changed by the user in get_simulation_options(); pdcp_period = 1; omg_period = 1; + //Clean ip rule table + for(int i =0; i Date: Wed, 25 Jan 2017 17:06:37 +0100 Subject: [PATCH 224/571] add changes for Tx Status PDU report --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 22 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h | 17 + .../RLC/AM_v9.3.0/rlc_am_status_report.c | 350 ++++++++++++++++++ .../RLC/AM_v9.3.0/rlc_am_timer_reordering.c | 54 ++- .../AM_v9.3.0/rlc_am_timer_status_prohibit.c | 2 + 5 files changed, 417 insertions(+), 28 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 1d93055487..3050d00d6b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -323,7 +323,8 @@ rlc_am_get_pdus ( case RLC_DATA_TRANSFER_READY_STATE: // TRY TO SEND CONTROL PDU FIRST - if ((rlc_pP->nb_bytes_requested_by_mac > 2) && (rlc_pP->status_requested)) { + if ((rlc_pP->nb_bytes_requested_by_mac >= 2) && + ((rlc_pP->status_requested) && !(rlc_pP->status_requested & RLC_AM_STATUS_NO_TX_MASK))) { // When STATUS reporting has been triggered, the receiving side of an AM RLC entity shall: // - if t-StatusProhibit is not running: // - at the first transmission opportunity indicated by lower layer, construct a STATUS PDU and deliver it to lower layer; @@ -334,22 +335,23 @@ rlc_am_get_pdus ( // // When a STATUS PDU has been delivered to lower layer, the receiving side of an AM RLC entity shall: // - start t-StatusProhibit. - if (rlc_pP->t_status_prohibit.running == 0) { - rlc_am_send_status_pdu(ctxt_pP, rlc_pP); - mem_block_t* pdu = list_remove_head(&rlc_pP->control_pdu_list); - if (pdu) { + rlc_am_send_status_pdu(ctxt_pP, rlc_pP); + mem_block_t* pdu = list_remove_head(&rlc_pP->control_pdu_list); + + if (pdu) { list_add_tail_eurecom (pdu, &rlc_pP->pdus_to_mac_layer); - rlc_pP->status_requested = 0; + RLC_AM_CLEAR_ALL_STATUS(rlc_pP->status_requested); rlc_pP->status_buffer_occupancy = 0; rlc_am_start_timer_status_prohibit(ctxt_pP, rlc_pP); + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_PROHIBIT); return; } - } else { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" DELAYED SENT STATUS PDU BECAUSE T-STATUS-PROHIBIT RUNNING (TIME-OUT %u)\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->t_status_prohibit.ms_time_out); } + else { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" DELAYED SENT STATUS PDU (Available MAC Data %u)(T-PROHIBIT %u) (DELAY FLAG %u)\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + rlc_pP->nb_bytes_requested_by_mac,rlc_pP->t_status_prohibit.ms_time_out,(rlc_pP->status_requested & RLC_AM_STATUS_TRIGGERED_DELAYED)); } /*while ((rlc_pP->nb_bytes_requested_by_mac > 0) && (stay_on_this_list)) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h index b63c7e3132..77bf31db86 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h @@ -72,6 +72,22 @@ # define RLC_AM_MAX_HOLES_REPORT_PER_PDU 16 /** @} */ +/* Common to Data and Status PDU */ +#define RLC_AM_SN_BITS 10 +#define RLC_AM_PDU_D_C_BITS 1 +#define RLC_AM_PDU_E_BITS 1 + +/* STATUS PDU */ +#define RLC_AM_STATUS_PDU_CPT_STATUS 0 + +#define RLC_AM_STATUS_PDU_CPT_OFFSET 4 +#define RLC_AM_STATUS_PDU_CPT_LENGTH 3 + +#define RLC_AM_STATUS_PDU_ACK_SN_OFFSET 2 + +#define RLC_AM_STATUS_PDU_SO_LENGTH 15 + +#define RLC_AM_STATUS_PDU_SO_END_ALL_BYTES 0x7FFF /* MACRO DEFINITIONS */ #define RLC_AM_NEXT_SN(sn) (((sn)+1) & ((RLC_AM_SN_MODULO)-1)) @@ -93,6 +109,7 @@ #define RLC_AM_STATUS_TRIGGERED_T_REORDERING 0x02 /* Status Report is triggered by Timer Reordering Expiry */ #define RLC_AM_STATUS_TRIGGERED_DELAYED 0x10 /* Status is delayed until SN(receivedPoll) < VR(MS) */ #define RLC_AM_STATUS_PROHIBIT 0x20 /* TimerStatusProhibit still running */ +#define RLC_AM_STATUS_NO_TX_MASK (RLC_AM_STATUS_PROHIBIT | RLC_AM_STATUS_TRIGGERED_DELAYED) /* Status triggered (bit 5-7) will be concatenated with Poll triggered (bit 0-4) for RLCdec. RLC_AM_STATUS_TRIGGERED_DELAYED is not recorded. */ #define RLC_AM_SET_STATUS(x,event) (RLC_SET_EVENT(x,event)) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index cab0a5340a..4cc987d301 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -449,6 +449,353 @@ rlc_am_send_status_pdu( // - set the ACK_SN to the SN of the next not received RLC Data PDU which is not indicated as missing in the // resulting STATUS PDU. + signed int nb_bits_to_transmit = rlc_pP->nb_bytes_requested_by_mac << 3; + // minimum header size in bits to be transmitted: D/C + CPT + ACK_SN + E1 + signed int nb_bits_transmitted = RLC_AM_PDU_D_C_BITS + RLC_AM_STATUS_PDU_CPT_LENGTH + RLC_AM_SN_BITS + RLC_AM_PDU_E_BITS; + rlc_am_control_pdu_info_t control_pdu_info; + rlc_am_pdu_info_t *pdu_info_cursor_p = NULL; + rlc_sn_t sn_cursor = 0; + rlc_sn_t sn_nack = rlc_pP->vr_r; + mem_block_t *cursor_p = rlc_pP->receiver_buffer.head; + int all_segments_received = 0; + int waited_so = 0; + mem_block_t *tb_p = NULL; + sdu_size_t pdu_size = 0; + boolean_t status_report_completed = false; + boolean_t lsf_received = false; + boolean_t segment_loop_end = false; + + memset(&control_pdu_info, 0, sizeof(rlc_am_control_pdu_info_t)); + +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] nb_bits_to_transmit %d (15 already allocated for header)\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + nb_bits_to_transmit); + rlc_am_rx_list_display(rlc_pP, " DISPLAY BEFORE CONSTRUCTION OF STATUS REPORT"); +#endif + + /* Handle no NACK first */ + if (rlc_pP->vr_r == rlc_pP->vr_ms) { + + control_pdu_info.ack_sn = rlc_pP->vr_ms; + status_report_completed = true; + } + else if (cursor_p != NULL) { + + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + sn_cursor = pdu_info_cursor_p->sn; + + // Not very clear why this is needed + // commenting +#if 0 + while (!(RLC_AM_SN_IN_WINDOW(sn_cursor, rlc_pP->vr_r))) { + cursor_p = cursor_p->next; + previous_sn_cursor = sn_cursor; + + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + sn_cursor = pdu_info_cursor_p->sn; +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d FIND VR(R) <= SN sn_cursor %04d -> %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + previous_sn_cursor, + sn_cursor); +#endif + } +#endif + + // 12 bits = size of NACK_SN field + E1, E2 bits + // 42 bits = size of NACK_SN field + SO_START, SO_END fields, E1, E2 bits + while ((!status_report_completed) && (RLC_AM_DIFF_SN(sn_nack,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r)) + && (cursor_p != NULL) && (nb_bits_transmitted <= nb_bits_to_transmit)) { + + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + sn_cursor = pdu_info_cursor_p->sn; + all_segments_received = ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received; + // E1 bit is set at the end + + /* First fill NACK_SN with each missing PDU between current sn_nack and sn_cursor */ + while ((sn_nack != sn_cursor) && (sn_nack != rlc_pP->vr_ms)) { + if (nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) <= nb_bits_to_transmit) { + /* Fill NACK_SN infos */ + if (control_pdu_info.num_nack) { + /* Set E1 of previous NACK_SN */ + control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; + } + control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_nack; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES; + control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 0; + control_pdu_info.num_nack += 1; + nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)); +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + sn_nack); +#endif + sn_nack = RLC_AM_NEXT_SN(sn_nack); + } + else { + /* Not enough UL TBS*/ + /* latest value of sn_nack shall be used as ACK_SN */ + control_pdu_info.ack_sn = sn_nack; + status_report_completed = true; + break; + } + } + + /* Now process all Segments of sn_cursor if PDU not fully received */ + if ((!status_report_completed) && (all_segments_received == 0) && (sn_nack != rlc_pP->vr_ms)) { + AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id); + + /* First ensure there is enough TBS for at least 1 SOStart/SOEnd, else break */ + if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { + /* Set E1 of previous NACK_SN */ + if (control_pdu_info.num_nack) { + control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; + } + /* Init loop flags */ + lsf_received = false; + segment_loop_end = false; + + /* Init first SO Start according to first segment */ + if (pdu_info_cursor_p->so) { + waited_so = 0; + /* Fill the first SO */ + control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so - 1; + control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; + control_pdu_info.num_nack += 1; + nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d SO START %05d SO END %05d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + previous_sn_cursor, + waited_so, + 0x7FFF); +#endif + waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size; + /* Go to next segment */ + cursor_p = cursor_p->next; + } + else { + waited_so = pdu_info_cursor_p->payload_size; + } + + /* Find the first discontinuity and then fill SOStart/SOEnd */ + while (!segment_loop_end) { + if (cursor_p != NULL) { + + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + + if (pdu_info_cursor_p->sn == sn_cursor) { + /* PDU segment is for the same SN*/ + if (waited_so < pdu_info_cursor_p->so) { + /* SO is greater than previous received portion : gap identified to fill */ + if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { + /* Set E1 of previous NACK_SN */ + if (control_pdu_info.num_nack) { + control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; + } + + control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so; + control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; + control_pdu_info.num_nack += 1; + nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); + } + else { + /* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */ + control_pdu_info.ack_sn = sn_cursor; + status_report_completed = true; + segment_loop_end = true; + break; + } + + } + else { + /* Assuming so and payload_size updated according to duplication removal done at reception ... */ + waited_so += pdu_info_cursor_p->payload_size; + } + + } //end if (pdu_info_cursor_p->sn == sn_cursor) + else if (!lsf_received) { + /* We just switched to next SN, fill last gap if not end received */ + if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { + /* Set E1 of previously received NACK */ + control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; + control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES; + control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; + control_pdu_info.num_nack += 1; + nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); + } + else { + /* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */ + control_pdu_info.ack_sn = sn_cursor; + status_report_completed = true; + } + + segment_loop_end = true; + continue; //in order not to go to next cursor + } // end if (!lsf_received) + + /* Go to next received PDU or PDU Segment */ + cursor_p = cursor_p->next; + + } //end if (cursor_p != NULL) + else if (!lsf_received) { + /* Previous PDU segment was the last one and had lsf indication : fill the latest gap */ + if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { + /* Set E1 of previously received NACK */ + control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; + control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES; + control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; + control_pdu_info.num_nack += 1; + nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); + } + else { + /* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */ + control_pdu_info.ack_sn = sn_cursor; + status_report_completed = true; + } + + segment_loop_end = true; + } + } //end while (!segment_loop_end) + } // end if enough resource for transmitting at least one SOStart/SOEnd + else { + /* Not enough UL TBS to set at least one SOStart/SOEnd */ + /* latest value of sn_nack shall be used as ACK_SN */ + control_pdu_info.ack_sn = sn_nack; + status_report_completed = true; + } + } + + /* Increment sn_nack except if sn_nack = vrMS and if current SN was not fully received */ + if ((sn_nack != rlc_pP->vr_ms) && (all_segments_received)) { + sn_nack = RLC_AM_NEXT_SN(sn_nack); + cursor_p = cursor_p->next; + } + + + } + + /* Set ACK_SN unless it was set before */ + if (!status_report_completed){ + + control_pdu_info.ack_sn = sn_nack; + } + + if (control_pdu_info.num_nack) { + control_pdu_info.e1 = 1; + } + + + } else { + control_pdu_info.ack_sn = rlc_pP->vr_r; +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING ACK %04d = VR(R)\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + control_pdu_info.ack_sn); +#endif + } + + + //msg ("[FRAME %5u][%s][RLC_AM][MOD %u/%u][RB %u] nb_bits_to_transmit %d\n", + // rlc_pP->module_id, rlc_pP->rb_id, ctxt_pP->frame,nb_bits_to_transmit); + +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING ACK %04d NUM NACK %d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + control_pdu_info.ack_sn, + control_pdu_info.num_nack); +#endif + + + /* encode the control pdu */ + pdu_size = (nb_bits_transmitted + 7) >> 3; + AssertFatal (pdu_size <= rlc_pP->nb_bytes_requested_by_mac, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n", + pdu_size,rlc_pP->nb_bytes_requested_by_mac,nb_bits_transmitted, rlc_pP->channel_id); + + +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d forecast pdu_size %d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + pdu_size); +#endif + tb_p = get_free_mem_block(sizeof(struct mac_tb_req) + pdu_size, __func__); + memset(tb_p->data, 0, sizeof(struct mac_tb_req) + pdu_size); + //estimation only ((struct mac_tb_req*)(tb_p->data))->tb_size = pdu_size; + ((struct mac_tb_req*)(tb_p->data))->data_ptr = (uint8_t*)&(tb_p->data[sizeof(struct mac_tb_req)]); + + // warning reuse of pdu_size + // TODO : rlc_am_write_status_pdu should be rewritten as not very tested ... + pdu_size = rlc_am_write_status_pdu(ctxt_pP, rlc_pP,(rlc_am_pdu_sn_10_t*)(((struct mac_tb_req*)(tb_p->data))->data_ptr), &control_pdu_info); + ((struct mac_tb_req*)(tb_p->data))->tb_size = pdu_size; + //assert((((struct mac_tb_req*)(tb_p->data))->tb_size) < 3000); + +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] SEND STATUS PDU SIZE %d, rlc_pP->nb_bytes_requested_by_mac %d, nb_bits_to_transmit>>3 %d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_size, + rlc_pP->nb_bytes_requested_by_mac, + nb_bits_to_transmit >> 3); +#endif + + AssertFatal (pdu_size == ((nb_bits_transmitted + 7) >> 3), "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n", + pdu_size,((nb_bits_transmitted + 7) >> 3), rlc_pP->channel_id); + + // remaining bytes to transmit for RLC (retrans pdus and new data pdus) + rlc_pP->nb_bytes_requested_by_mac = rlc_pP->nb_bytes_requested_by_mac - pdu_size; + // put pdu in trans + list_add_head(tb_p, &rlc_pP->control_pdu_list); + rlc_pP->stat_tx_control_pdu += 1; + rlc_pP->stat_tx_control_bytes += pdu_size; + +} + + +#if 0 +//----------------------------------------------------------------------------- +void +rlc_am_send_status_pdu_backup( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP +) +{ + // When STATUS reporting has been triggered, the receiving side of an AM RLC entity shall: + // - if t-StatusProhibit is not running: + // - at the first transmission opportunity indicated by lower layer, construct a STATUS PDU and deliver it to lower layer; + // - else: + // - at the first transmission opportunity indicated by lower layer after t-StatusProhibit expires, construct a single + // STATUS PDU even if status reporting was triggered several times while t-StatusProhibit was running and + // deliver it to lower layer; + // + // When a STATUS PDU has been delivered to lower layer, the receiving side of an AM RLC entity shall: + // - start t-StatusProhibit. + // + // When constructing a STATUS PDU, the AM RLC entity shall: + // - for the AMD PDUs with SN such that VR(R) <= SN < VR(MR) that has not been completely received yet, in + // increasing SN of PDUs and increasing byte segment order within PDUs, starting with SN = VR(R) up to + // the point where the resulting STATUS PDU still fits to the total size of RLC PDU(s) indicated by lower layer: + // - for an AMD PDU for which no byte segments have been received yet:: + // - include in the STATUS PDU a NACK_SN which is set to the SN of the AMD PDU; + // - for a continuous sequence of byte segments of a partly received AMD PDU that have not been received yet: + // - include in the STATUS PDU a set of NACK_SN, SOstart and SOend + // - set the ACK_SN to the SN of the next not received RLC Data PDU which is not indicated as missing in the + // resulting STATUS PDU. + signed int nb_bits_to_transmit = rlc_pP->nb_bytes_requested_by_mac << 3; rlc_am_control_pdu_info_t control_pdu_info; rlc_am_pdu_info_t *pdu_info_cursor_p = NULL; @@ -470,6 +817,7 @@ rlc_am_send_status_pdu( rlc_am_rx_list_display(rlc_pP, " DISPLAY BEFORE CONSTRUCTION OF STATUS REPORT"); #endif + if (cursor_p != NULL) { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; sn_cursor = pdu_info_cursor_p->sn; @@ -757,3 +1105,5 @@ end_push_nack: rlc_pP->stat_tx_control_bytes += pdu_size; } +#endif + diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c index 3bbc2e87ac..fa214cd5a9 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c @@ -70,6 +70,8 @@ rlc_am_check_timer_reordering( PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP)); #endif + AssertFatal (rlc_pP->vr_x != RLC_SN_UNDEFINED, "RLC AM TReordering Expiry vrX not defined LcId=%d\n", rlc_pP->channel_id); + rlc_pP->t_reordering.running = 0; rlc_pP->t_reordering.timed_out = 1; rlc_pP->stat_timer_reordering_timed_out += 1; @@ -77,38 +79,54 @@ rlc_am_check_timer_reordering( rlc_am_pdu_info_t* pdu_info; mem_block_t* cursor; cursor = rlc_pP->receiver_buffer.head; + rlc_usn_t vr_ms_new = rlc_pP->vr_x; - if (cursor) { - do { - pdu_info = &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info; + AssertFatal (cursor != NULL, "RLC AM TReordering Expiry Rx PDU list empty LcId=%d\n", rlc_pP->channel_id); - // NOT VERY SURE ABOUT THAT, THINK ABOUT IT - rlc_pP->vr_ms = (pdu_info->sn + 1) & RLC_AM_SN_MASK; + while ((cursor != NULL) && (vr_ms_new != rlc_pP->vr_h)) { + pdu_info = &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info; - if (rlc_am_sn_gte_vr_x(ctxt_pP, rlc_pP, pdu_info->sn)) { - if (((rlc_am_rx_pdu_management_t*)(cursor->data))->all_segments_received == 0) { - rlc_pP->vr_ms = pdu_info->sn; - break; - } - } - cursor = cursor->next; - } while (cursor != NULL); + // First find an element with SN greater or equal than vrX + if (RLC_AM_DIFF_SN(pdu_info->sn,rlc_pP->vr_r) >= RLC_AM_DIFF_SN(rlc_pP->vr_x,rlc_pP->vr_r)) { + if (((rlc_am_rx_pdu_management_t*)(cursor->data))->all_segments_received == 0) { + // Stop at first found discontinuity + // vr_ms_new holds SN following the latest in sequence fully received PDU >= old vrX + break; + } + else { + vr_ms_new = RLC_AM_NEXT_SN(vr_ms_new); + } - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T-REORDERING] TIME-OUT UPDATED VR(MS) %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->vr_ms); + } + cursor = cursor->next; } - if (rlc_am_sn_gt_vr_ms(ctxt_pP, rlc_pP, rlc_pP->vr_h)) { + /* Update vr_ms */ + rlc_pP->vr_ms = vr_ms_new; + + + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T-REORDERING] TIME-OUT UPDATED VR(MS) %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + rlc_pP->vr_ms); + + /* if new vrMS is lower than vrH, update vrX and restart timerReordering */ + if (rlc_pP->vr_ms != rlc_pP->vr_h) { rlc_pP->vr_x = rlc_pP->vr_h; rlc_pP->t_reordering.ms_time_out = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) + rlc_pP->t_reordering.ms_duration; + + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T-REORDERING] TIME-OUT, RESTARTED T-REORDERING, UPDATED VR(X) to VR(R) %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->vr_x); } - rlc_pP->status_requested = 1; + /* Trigger a STATUS report */ + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_T_REORDERING); + // Clear Delay flag if it was setup as it is useless due to Status PDU to be sent for TReordering expiry + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED); + rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; + } } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c index b41fa1c17f..d067c5d9bb 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c @@ -70,6 +70,8 @@ rlc_am_check_timer_status_prohibit( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); //#warning TO DO rlc_am_check_timer_status_prohibit rlc_am_stop_and_reset_timer_status_prohibit(ctxt_pP, rlc_pP); + /* Clear StatusProhibit flag */ + RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_PROHIBIT); //rlc_pP->t_status_prohibit.frame_time_out = ctxt_pP->frame + rlc_pP->t_status_prohibit.time_out; } } From a33a3ead22a849a7a34cadc1340da559c876ca21 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 25 Jan 2017 17:21:56 +0100 Subject: [PATCH 225/571] 1.Fixing the bug in lte_ue_measuments.c for rank indicator. 2. Fixing the arguments in the dump_dlsch2. --- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 34 +- openair1/SCHED/defs.h | 4 +- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 758 +++++++++--------- 3 files changed, 398 insertions(+), 398 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 96ccac848b..5d86bbd92a 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -199,7 +199,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, rxF_sss = (int16_t *)&ue->common_vars.rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)]; rxF_pss = (int16_t *)&ue->common_vars.rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)]; - + //-ve spectrum from SSS // printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]); @@ -249,7 +249,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, // note this is a dummy pointer, the pss is not really there! // in FDD the pss is in the symbol after the sss, but not in TDD rxF_pss = (int16_t *)&ue->common_vars.rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)]; - + //-ve spectrum from SSS // ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71])); ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69])); @@ -262,14 +262,14 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67])); ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65])); // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63])); - + ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(6)); - ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; - } + ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; + } ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(6*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); - - + + } } } @@ -312,7 +312,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, // if ((ue->frame_rx&0x3ff) == 0) // printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1]))); - + off+=12; if (off>=(ue->frame_parms.ofdm_symbol_size<<1)) @@ -423,10 +423,10 @@ void lte_ue_measurements(PHY_VARS_UE *ue, int nb_subbands,subband_size,last_subband_size; int N_RB_DL = frame_parms->N_RB_DL; ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; - + if (ue->transmission_mode[eNB_id]!=4) ue->measurements.rank[eNB_id] = 0; - else + else ue->measurements.rank[eNB_id] = 1; // printf ("tx mode %d\n", ue->transmission_mode[eNB_id]); // printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]); @@ -597,7 +597,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, // pmi #if defined(__x86_64__) || defined(__i386__) - + pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re); pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im); #elif defined(__arm__) @@ -613,8 +613,8 @@ void lte_ue_measurements(PHY_VARS_UE *ue, limit = last_subband_size>>2; for (i=0; imeasurements.rank[eNB_id] = 0; + //ue->measurements.rank[eNB_id] = 0; for (i=0; imeasurements.selected_rx_antennas[eNB_id][i] = 0; diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index df8652e3dc..11856398f4 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -199,7 +199,7 @@ void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB,relaying_type_t r_type); */ void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type); -/*! \brief Scheduling for eNB PRACH RX procedures +/*! \brief Scheduling for eNB PRACH RX procedures @param phy_vars_eNB Pointer to eNB variables on which to act @param proc Pointer to RXn-TXnp4 proc information */ @@ -477,7 +477,7 @@ int get_ue_active_harq_pid(uint8_t Mod_id,uint8_t CC_id,uint16_t rnti,int frame, void dump_dlsch(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid); void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); -void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round); +void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid); /*@}*/ diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 5375175fb2..a5baa6a8a7 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -172,10 +172,10 @@ int main(int argc, char **argv) unsigned char *input_buffer0[2],*input_buffer1[2]; unsigned short input_buffer_length0,input_buffer_length1; - /* A variable "ret" is a nuumber of turbo iterations, that are performed in the turbo-decoder for each CW. + /* A variable "ret" is a nuumber of turbo iterations, that are performed in the turbo-decoder for each CW. The decoder checks CRC, and if CRC test fails, it increments "ret". Ret is between 1 and 4, where 4 is for - the max number of turbo iterations. If the CRC is passed, ret is equal to a current iteration. - This is done separately for each CW inside decoding process. + the max number of turbo iterations. If the CRC is passed, ret is equal to a current iteration. + This is done separately for each CW inside decoding process. Again: this is not a HARQ retransmission!*/ unsigned int ret[2]; unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; @@ -353,7 +353,7 @@ int main(int argc, char **argv) common_flag = 1; TPC = atoi(optarg); break; - + case 'E': threequarter_fs=1; break; @@ -424,7 +424,7 @@ int main(int argc, char **argv) case 'w': snr_int = atof(optarg); break; - + case 'N': n_ch_rlz= atof(optarg); break; @@ -452,10 +452,10 @@ int main(int argc, char **argv) case 'E': channel_model=EPA; break; - case 'F': + case 'F': channel_model=EVA; break; - case 'G': + case 'G': channel_model=ETU; break; case 'H': @@ -531,7 +531,7 @@ int main(int argc, char **argv) exit(-1); } break; - + case 'R': num_rounds=atoi(optarg); break; @@ -540,7 +540,7 @@ int main(int argc, char **argv) break; case 'T': n_rnti=atoi(optarg); - break; + break; case 'u': rx_type = (RX_type_t) atoi(optarg); if (rx_typerx_SIC_dual_stream) { @@ -569,7 +569,7 @@ int main(int argc, char **argv) break; case 'V': interf_unaw_shift0=atoi(optarg); - break; + break; case 'W': interf_unaw_shift1=atoi(optarg); break; @@ -605,10 +605,10 @@ int main(int argc, char **argv) printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n"); exit(1); break; - + } } - + if (common_flag == 0) { switch (N_RB_DL) { case 6: @@ -633,7 +633,7 @@ int main(int argc, char **argv) } else NB_RB = 4; - NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); + NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); if ((transmission_mode > 1) && (n_tx != 2)) { @@ -668,12 +668,12 @@ int main(int argc, char **argv) */ } - if (transmission_mode==5) { + if (transmission_mode==5) { n_users = 2; eNB_id_i = UE->n_connected_eNB; //eNB_id_i=1; } - else + else eNB_id_i = eNB_id; lte_param_init(n_tx, @@ -727,7 +727,7 @@ int main(int argc, char **argv) SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); if(transmission_mode==5) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); - else if (abstx == 1) + else if (abstx == 1) if (perfect_ce==1) sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_ab_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2,interf_unaw_shift ); else @@ -737,7 +737,7 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_pce_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx,mcs1, mcs2, interf_unaw_shift); else sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_mcs%d_mcsi%d_sh%d_pnort_r45.csv",transmission_mode,rx_type,channel_model,n_frames,n_rx,mcs1, mcs2, interf_unaw_shift); - + bler_fd = fopen(bler_fname,"w"); if (bler_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",bler_fname); @@ -746,7 +746,7 @@ int main(int argc, char **argv) fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); if (test_perf != 0) { - + char hostname[1024]; hostname[1023] = '\0'; @@ -763,14 +763,14 @@ int main(int argc, char **argv) exit(-1); } } - + if(abstx){ // CSV file // add here second stream mcs - + if (transmission_mode == 5) sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d_abstr.m",transmission_mode,rx_type,mcs1,channel_model,n_frames,num_rounds); - - else + + else if (perfect_ce==1) sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); else @@ -898,7 +898,7 @@ n(tikz_fname,"w"); UE->transmission_mode[eNB_id]=transmission_mode; if (UE->transmission_mode[eNB_id] !=4) UE->measurements.rank[eNB_id]=0; - else + else UE->measurements.rank[eNB_id]=1; // Fill in UL_alloc UL_alloc_pdu.type = 0; @@ -908,7 +908,7 @@ n(tikz_fname,"w"); UL_alloc_pdu.ndi = 1; UL_alloc_pdu.TPC = 0; UL_alloc_pdu.cqi_req = 1; - + CCCH_alloc_pdu.type = 0; CCCH_alloc_pdu.vrb_type = 0; CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; @@ -968,7 +968,7 @@ n(tikz_fname,"w"); exit(-1); } - if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8)) + if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8)) Kmimo=2; else Kmimo=1; @@ -1054,9 +1054,9 @@ n(tikz_fname,"w"); case 1: case 2: if (common_flag == 0) { - + if (eNB->frame_parms.frame_type == TDD) { - + switch (eNB->frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1_1_5MHz_TDD_t; @@ -1066,7 +1066,7 @@ n(tikz_fname,"w"); ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1078,7 +1078,7 @@ n(tikz_fname,"w"); ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1090,7 +1090,7 @@ n(tikz_fname,"w"); ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1100,7 +1100,7 @@ n(tikz_fname,"w"); ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1_20MHz_TDD_t; @@ -1117,7 +1117,7 @@ n(tikz_fname,"w"); ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1128,7 +1128,7 @@ n(tikz_fname,"w"); ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1139,7 +1139,7 @@ n(tikz_fname,"w"); ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1150,18 +1150,18 @@ n(tikz_fname,"w"); ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; dci_alloc[num_dci].L = 1; dci_alloc[num_dci].rnti = n_rnti+k; dci_alloc[num_dci].format = format1; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, @@ -1181,7 +1181,7 @@ n(tikz_fname,"w"); } else { //common flag =1 if (eNB->frame_parms.frame_type == TDD) { - + switch (eNB->frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; @@ -1192,7 +1192,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1205,7 +1205,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1218,7 +1218,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1229,7 +1229,7 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; @@ -1247,7 +1247,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1259,7 +1259,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1271,7 +1271,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1283,11 +1283,11 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -1295,7 +1295,7 @@ n(tikz_fname,"w"); dci_alloc[num_dci].rnti = SI_RNTI; dci_alloc[num_dci].format = format1A; dci_alloc[num_dci].firstCCE = 0; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, @@ -1310,19 +1310,19 @@ n(tikz_fname,"w"); 0, P_RNTI, eNB->UE_stats[0].DL_pmi_single); - + num_common_dci++; num_dci++; - + } break; case 3: //LARGE CDD if (common_flag == 0) { - + if (eNB->frame_parms.nb_antennas_tx == 2) {// here DCI does not contain any precoder information. matrix is fixed as identity, but dont forget aboy cycling if (eNB->frame_parms.frame_type == TDD) { - + switch (eNB->frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; @@ -1331,10 +1331,10 @@ n(tikz_fname,"w"); ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1346,10 +1346,10 @@ n(tikz_fname,"w"); ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1361,10 +1361,10 @@ n(tikz_fname,"w"); ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1374,10 +1374,10 @@ n(tikz_fname,"w"); ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; @@ -1385,7 +1385,7 @@ n(tikz_fname,"w"); break; } } - + else { // fdd switch (eNB->frame_parms.N_RB_DL) { case 6: @@ -1394,10 +1394,10 @@ n(tikz_fname,"w"); ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1408,10 +1408,10 @@ n(tikz_fname,"w"); ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1422,10 +1422,10 @@ n(tikz_fname,"w"); ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; @@ -1436,27 +1436,27 @@ n(tikz_fname,"w"); ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; break; - } + } } } else if (eNB->frame_parms.nb_antennas_tx == 4) { //4 antenna, needs diff precoding codebook index depeneding on layers } - + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; dci_alloc[num_dci].L = 1; dci_alloc[num_dci].rnti = n_rnti+k; dci_alloc[num_dci].format = format2A; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -1470,13 +1470,13 @@ n(tikz_fname,"w"); 0, P_RNTI, eNB->UE_stats[0].DL_pmi_single); - + num_dci++; num_ue_spec_dci++; } else { //commonn flag 1 if (eNB->frame_parms.frame_type == TDD) { //tdd - + switch (eNB->frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; @@ -1487,7 +1487,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1500,7 +1500,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1513,7 +1513,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1524,7 +1524,7 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; @@ -1542,7 +1542,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1554,7 +1554,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1566,7 +1566,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1578,11 +1578,11 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -1590,8 +1590,8 @@ n(tikz_fname,"w"); dci_alloc[num_dci].rnti = SI_RNTI; dci_alloc[num_dci].format = format1A; dci_alloc[num_dci].firstCCE = 0; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -1605,33 +1605,33 @@ n(tikz_fname,"w"); 0, P_RNTI, eNB->UE_stats[0].DL_pmi_single); - + num_common_dci++; num_dci++; - + } printf("Generated DCI format 2A (Transmission Mode 3)\n"); break; case 4: // !!! this dci format contains precoder information if (common_flag == 0) { - + if (eNB->frame_parms.nb_antennas_tx == 2) { if (eNB->frame_parms.frame_type == TDD) { - + switch (eNB->frame_parms.N_RB_DL) { case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; + dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1642,13 +1642,13 @@ n(tikz_fname,"w"); dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1663,10 +1663,10 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1679,10 +1679,10 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1692,7 +1692,7 @@ n(tikz_fname,"w"); break; } } - + else { switch (eNB->frame_parms.N_RB_DL) { case 6: @@ -1701,10 +1701,10 @@ n(tikz_fname,"w"); ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1717,10 +1717,10 @@ n(tikz_fname,"w"); ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1733,10 +1733,10 @@ n(tikz_fname,"w"); ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; @@ -1749,36 +1749,36 @@ n(tikz_fname,"w"); ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; break; - } + } } } else if (eNB->frame_parms.nb_antennas_tx == 4) { } - - printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); - if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { + + printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); + if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); - + } - + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; dci_alloc[num_dci].L = 1; dci_alloc[num_dci].rnti = n_rnti+k; dci_alloc[num_dci].format = format2; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, subframe, @@ -1792,13 +1792,13 @@ n(tikz_fname,"w"); 0, P_RNTI, eNB->UE_stats[0].DL_pmi_single); - + num_dci++; num_ue_spec_dci++; } else { //common_flag==1 if (eNB->frame_parms.frame_type == TDD) { - + switch (eNB->frame_parms.N_RB_DL) { case 6: dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; @@ -1809,7 +1809,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1822,7 +1822,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1835,7 +1835,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1846,7 +1846,7 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; @@ -1864,7 +1864,7 @@ n(tikz_fname,"w"); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1876,7 +1876,7 @@ n(tikz_fname,"w"); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1888,7 +1888,7 @@ n(tikz_fname,"w"); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; @@ -1900,11 +1900,11 @@ n(tikz_fname,"w"); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; break; - } + } } memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); dci_alloc[num_dci].dci_length = dci_length; @@ -1912,7 +1912,7 @@ n(tikz_fname,"w"); dci_alloc[num_dci].rnti = SI_RNTI; dci_alloc[num_dci].format = format1A; dci_alloc[num_dci].firstCCE = 0; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, @@ -1927,7 +1927,7 @@ n(tikz_fname,"w"); 0, P_RNTI, eNB->UE_stats[0].DL_pmi_single); - + num_common_dci++; num_dci++; @@ -1979,12 +1979,12 @@ n(tikz_fname,"w"); */ } - if (n_frames==1) + if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE); numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe)); - if (n_frames==1) + if (n_frames==1) printf("%d\n",numCCE); // apply RNTI-based nCCE allocation @@ -2062,7 +2062,7 @@ n(tikz_fname,"w"); errs[0][i]=0; errs[1][i]=0; /*Let see, how it will work, if */ - round_trials[i] = 0; + round_trials[i] = 0; // round_trials_1[i] = 0; } dci_errors=0; @@ -2118,7 +2118,7 @@ n(tikz_fname,"w"); initialize(&time_vector_rx_demod); struct list time_vector_rx_dec; initialize(&time_vector_rx_dec); - + for (trials = 0;trialsdlsch[0][0]->max_turbo_iterations+1; ret[1] = UE->dlsch[0][0]->max_turbo_iterations+1; - /*This condition indicates, that the round_trials must go on, while CRC keeps failing at - least for one of the CW and round < num_rounds. This also means that round_trials is a unique + /*This condition indicates, that the round_trials must go on, while CRC keeps failing at + least for one of the CW and round < num_rounds. This also means that round_trials is a unique variable for both CW*/ while (((transmission_mode == 3 || transmission_mode == 4) && ((round < num_rounds) && ((ret[0] > UE->dlsch[0][0]->max_turbo_iterations) - || (ret[1] > UE->dlsch[0][0]->max_turbo_iterations)))) || + || (ret[1] > UE->dlsch[0][0]->max_turbo_iterations)))) || ((transmission_mode!=4 && transmission_mode != 3)&& ((round < num_rounds) && (ret[0] > UE->dlsch[0][0]->max_turbo_iterations)))) { - + //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); //printf("round_trials %d round %d\n", round_trials[round], round); @@ -2147,11 +2147,11 @@ n(tikz_fname,"w"); //printf("round_trials %d round %d\n", round_trials[round], round); - if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) pmi_feedback=1; - else + else pmi_feedback=0; - + if (abstx) { if (trials==0 && round==0 && SNR==snr0) //generate a new channel hold_channel = 0; @@ -2162,25 +2162,25 @@ n(tikz_fname,"w"); hold_channel = 0;//(round==0) ? 0 : 1; PMI_FEEDBACK: - + //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aaframe_parms.nb_antennas_tx;aa++) { memset(&eNB->common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } - + if (input_fd==NULL) { start_meas(&eNB->phy_proc_tx); // Simulate HARQ procedures!!! if (common_flag == 0) { - + if (round == 0) { // First round TB0_active = 1; - + eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; if (eNB->frame_parms.frame_type == TDD) { - + switch (transmission_mode) { case 1: case 2: @@ -2240,7 +2240,7 @@ n(tikz_fname,"w"); } break; case 4: - switch (eNB->frame_parms.N_RB_DL) { + switch (eNB->frame_parms.N_RB_DL) { case 6: ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; @@ -2270,8 +2270,8 @@ n(tikz_fname,"w"); memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); break; } - break; - + break; + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; @@ -2339,7 +2339,7 @@ n(tikz_fname,"w"); } break; case 4: - switch (eNB->frame_parms.N_RB_DL) { + switch (eNB->frame_parms.N_RB_DL) { case 6: ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; @@ -2369,19 +2369,19 @@ n(tikz_fname,"w"); memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); break; } - break; + break; case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = 0; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); break; } - + } } - else { + else { eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; - + if (eNB->frame_parms.frame_type == TDD) { switch (transmission_mode) { case 1: @@ -2537,7 +2537,7 @@ n(tikz_fname,"w"); break; } break; - + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; @@ -2700,9 +2700,9 @@ n(tikz_fname,"w"); memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); break; } - break; - - + break; + + case 5: DLSCH_alloc_pdu2_1E[0].ndi = trials&1; DLSCH_alloc_pdu2_1E[0].rv = round&3; @@ -2712,7 +2712,7 @@ n(tikz_fname,"w"); } } } - + num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci, num_common_dci, dci_alloc, @@ -2745,7 +2745,7 @@ n(tikz_fname,"w"); #endif rate[cw] = (double)tbs[cw]/(double)coded_bits_per_codeword[cw]; - + if ((SNR==snr0) && (trials==0) && (round==0) && (pmi_feedback==0)) printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", k,cw,rate[cw],rate[cw]*get_Qm(eNB->dlsch[k][cw]->harq_processes[0]->mcs), @@ -2759,27 +2759,27 @@ n(tikz_fname,"w"); if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); UE->dlsch[0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); - if (n_users>1) - eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); + if (n_users>1) + eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); /* if ((trials<10) && (round==0)) { printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(eNB->dlsch[0][0]->pmi_alloc),pmi_feedback); if (transmission_mode ==5) printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(eNB->dlsch[1][0]->pmi_alloc)); } - */ + */ } - - + + if (transmission_mode==4 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2))){ eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); UE->dlsch[0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); } - - - start_meas(&eNB->dlsch_encoding_stats); + + + start_meas(&eNB->dlsch_encoding_stats); if (dlsch_encoding(((cw==0) ? input_buffer0[k] : input_buffer1[k]), &eNB->frame_parms, num_pdcch_symbols, @@ -2789,9 +2789,9 @@ n(tikz_fname,"w"); &eNB->dlsch_turbo_encoding_stats, &eNB->dlsch_interleaving_stats)<0) exit(-1); - - - + + + /* if (transmission_mode == 3) { if (dlsch_encoding(input_buffer1[k], @@ -2806,17 +2806,17 @@ n(tikz_fname,"w"); exit(-1); } */ - stop_meas(&eNB->dlsch_encoding_stats); + stop_meas(&eNB->dlsch_encoding_stats); - eNB->dlsch[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; - start_meas(&eNB->dlsch_scrambling_stats); + eNB->dlsch[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; + start_meas(&eNB->dlsch_scrambling_stats); dlsch_scrambling(&eNB->frame_parms, 0, eNB->dlsch[k][cw], coded_bits_per_codeword[cw], cw, subframe<<1); - stop_meas(&eNB->dlsch_scrambling_stats); + stop_meas(&eNB->dlsch_scrambling_stats); if (n_frames==1) { for (s=0;sdlsch[k][cw]->harq_processes[0]->C;s++) { @@ -2824,16 +2824,16 @@ n(tikz_fname,"w"); Kr = eNB->dlsch[k][cw]->harq_processes[0]->Kminus; else Kr = eNB->dlsch[k][cw]->harq_processes[0]->Kplus; - + Kr_bytes = Kr>>3; - + // for (i=0;idlsch[k][cw]->harq_processes[0]->c[s][i]); } } } - - start_meas(&eNB->dlsch_modulation_stats); + + start_meas(&eNB->dlsch_modulation_stats); re_allocated = dlsch_modulation(eNB->common_vars.txdataF[eNB_id], AMP, subframe, @@ -2842,21 +2842,21 @@ n(tikz_fname,"w"); eNB->dlsch[k][0], eNB->dlsch[k][1] ); - stop_meas(&eNB->dlsch_modulation_stats); + stop_meas(&eNB->dlsch_modulation_stats); /* if (trials==0 && round==0) printf("RE count %d\n",re_allocated); */ } //n_users - + generate_pilots(eNB, eNB->common_vars.txdataF[eNB_id], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - + start_meas(&eNB->ofdm_mod_stats); - + do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], eNB->common_vars.txdata[eNB_id], (subframe*2), @@ -2866,10 +2866,10 @@ n(tikz_fname,"w"); eNB->common_vars.txdata[eNB_id], (subframe*2)+1, &eNB->frame_parms); - + stop_meas(&eNB->ofdm_mod_stats); - stop_meas(&eNB->phy_proc_tx); - + stop_meas(&eNB->phy_proc_tx); + do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], eNB->common_vars.txdata[eNB_id], (subframe*2)+2, @@ -2888,7 +2888,7 @@ n(tikz_fname,"w"); eNB->frame_parms.samples_per_tti); } tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - + if (n_frames==1) { printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe* eNB->frame_parms.samples_per_tti], @@ -2900,7 +2900,7 @@ n(tikz_fname,"w"); i=0; while (!feof(input_fd)) { fscanf(input_fd,"%s %s",input_val_str,input_val_str2); - + if ((i%4)==0) { ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); @@ -2919,7 +2919,7 @@ n(tikz_fname,"w"); tx_lev_dB = (unsigned int) dB_fixed(tx_lev); } */ - + // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag); for (i=0;i<2*frame_parms->samples_per_tti;i++) { for (aa=0;aaframe_parms.nb_antennas_tx;aa++) { @@ -2938,7 +2938,7 @@ n(tikz_fname,"w"); //printf("r_im0 = %d\n",r_im[0][i]); //printf("r_re1 = %d\n",r_re[1][i]); //printf("r_im1 = %d\n",r_im[1][i]); - + } else { for (aarx=0;aarxframe_parms.nb_antennas_rx;aarx++) { @@ -2957,7 +2957,7 @@ n(tikz_fname,"w"); } // Multipath channel - if (awgn_flag == 0) { + if (awgn_flag == 0) { multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, 2*frame_parms->samples_per_tti,hold_channel); // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); @@ -2973,7 +2973,7 @@ n(tikz_fname,"w"); // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL +1,1,8); } } - + // freq_channel(eNB2UE[0], NB_RB,12*NB_RB + 1); if(abstx){ if (trials==0 && round==0) { @@ -2981,7 +2981,7 @@ n(tikz_fname,"w"); freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1); // snr=pow(10.0,.1*SNR); fprintf(csv_fd,"%f,",SNR); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -2991,10 +2991,10 @@ n(tikz_fname,"w"); } } } - + if(num_rounds>1){ freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -3005,7 +3005,7 @@ n(tikz_fname,"w"); } } freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -3015,9 +3015,9 @@ n(tikz_fname,"w"); } } } - + freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1); - + for (u=0;u<2*NB_RB;u++){ for (aarx=0;aarxnb_rx;aarx++) { for (aatx=0;aatxnb_tx;aatx++) { @@ -3030,28 +3030,28 @@ n(tikz_fname,"w"); } } } - + //AWGN // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(eNB->pdsch_config_dedicated); sigma2 = pow(10,sigma2_dB/10); if (n_frames==1) printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(eNB->pdsch_config_dedicated)); - + for (i=0; i<2*frame_parms->samples_per_tti; i++) { for (aa=0;aaframe_parms.nb_antennas_rx;aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = + ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = + ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); } - } - + } + // lte_sync_time_init(eNB->frame_parms,common_vars); // lte_sync_time(common_vars->rxdata, eNB->frame_parms); // lte_sync_time_free(); - + /* // optional: read rx_frame from file if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL) @@ -3059,22 +3059,22 @@ n(tikz_fname,"w"); printf("Cannot open rx_frame.m data file\n"); exit(0); } - + result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); printf("Read %d bytes\n",result); result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); printf("Read %d bytes\n",result); - + fclose(rx_frame_file); */ - + if (n_frames==1) { printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); } - + if (eNB->frame_parms.Ncp == 0) { // normal prefix pilot1 = 4; pilot2 = 7; @@ -3084,8 +3084,8 @@ n(tikz_fname,"w"); pilot1 = 3; pilot2 = 6; pilot3 = 9; - } - + } + start_meas(&UE->phy_proc_rx); // Inner receiver scheduling for 3 slots for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) { @@ -3094,17 +3094,17 @@ n(tikz_fname,"w"); printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2); /* This function implements the OFDM front end processor (FEP). - + Parameters: frame_parms LTE DL Frame Parameters ue_common_vars LTE UE Common Vars l symbol within slot (0..6/7) Ns Slot number (0..19) sample_offset offset within rxdata (points to beginning of subframe) - no_prefix if 1 prefix is removed by HW - + no_prefix if 1 prefix is removed by HW + */ - + start_meas(&UE->ofdm_demod_stats); slot_fep(UE, l, @@ -3145,14 +3145,14 @@ n(tikz_fname,"w"); for (aarx=0; aarxnb_antennas_rx; aarx++) { for (i=0; iN_RB_DL*12; i++) { ((int16_t *) UE->common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) UE->common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; + ((int16_t *) UE->common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; } } } } } } - + if ((Ns==((2*subframe))) && (l==0)) { lte_ue_measurements(UE, subframe*UE->frame_parms.samples_per_tti, @@ -3217,7 +3217,7 @@ n(tikz_fname,"w"); eNB_id, subframe); printf("dci_cnt %d\n",dci_cnt); - + if (dci_cnt==0) { dlsch_active = 0; if (round==0) { @@ -3233,14 +3233,14 @@ n(tikz_fname,"w"); //round_trials[i]--; //round=5; } - + for (i=0;idlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->first_tx=1; UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->first_tx=1; } - if ((dci_alloc_rx[i].rnti == n_rnti) && + if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, subframe, dci_alloc_rx[i].dci_pdu, @@ -3276,9 +3276,9 @@ n(tikz_fname,"w"); //round_trials[0]++; round=5; - if (n_frames==1) + if (n_frames==1) printf("DCI misdetection trial %d\n",trials); - + } // for (i=1;i<=round;i++) // round_trials[i]--; @@ -3324,7 +3324,7 @@ n(tikz_fname,"w"); break; case 4: generate_ue_dlsch_params_from_dci(0, - subframe, + subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A,//format1A only for a codeblock @@ -3368,7 +3368,7 @@ n(tikz_fname,"w"); start_meas(&UE->dlsch_llr_stats); - + for (m=UE->pdcch_vars[0]->num_pdcch_symbols; mdlsch_llr_stats); } - - if ((Ns==(1+(2*subframe))) && (l==pilot1)){// process symbols (6 Extended Prefix),7,8,9 + + if ((Ns==(1+(2*subframe))) && (l==pilot1)){// process symbols (6 Extended Prefix),7,8,9 start_meas(&UE->dlsch_llr_stats); for (m=pilot2;mdlsch_llr_stats); } - + if ((Ns==(2+(2*subframe))) && (l==0)) { // process symbols 10,11,(12,13 Normal Prefix) do deinterleaving for TTI start_meas(&UE->dlsch_llr_stats); for (m=pilot3; mframe_parms.symbols_per_tti; m++) { @@ -3441,15 +3441,15 @@ n(tikz_fname,"w"); } } } - + if (rx_type==rx_SIC_dual_stream){ cw_to_decode_interf=1; cw_to_decode_interf_free=1; } else { - cw_to_decode_interf=Kmimo; - } - + cw_to_decode_interf=Kmimo; + } + for (cw_non_sic=0; cw_non_sicdlsch[0][cw_non_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; @@ -3463,16 +3463,16 @@ n(tikz_fname,"w"); UE->dlsch[0][cw_non_sic]->harq_processes[UE->dlsch[0][cw_non_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_non_sic]; UE->dlsch[0][cw_non_sic]->harq_processes[UE->dlsch[0][cw_non_sic]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][cw_non_sic]->harq_processes[0]->mcs); - + if (n_frames==1) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_non_sic,coded_bits_per_codeword[cw_non_sic], UE->dlsch[0][cw_non_sic]->harq_processes[UE->dlsch[0][cw_non_sic]->current_harq_pid]->TBS); - + // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_non_sic]); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); - + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, cw_non_sic); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, cw_non_sic); write_output(fname,vname, UE->pdsch_vars[0]->llr[cw_non_sic],coded_bits_per_codeword[cw_non_sic],1,0); @@ -3482,28 +3482,28 @@ n(tikz_fname,"w"); uncoded_ber=0; printf("trials=%d\n", trials); - for (i=0;idlsch[0][cw_non_sic]->harq_processes[0]->e[i] != (UE->pdsch_vars[0]->llr[cw_non_sic][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } else uncoded_ber_bit[i] = 0; - + uncoded_ber/=coded_bits_per_codeword[cw_non_sic]; avg_ber += uncoded_ber; sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_non_sic); sprintf(vname,"uncoded_ber_bit_cw%d", cw_non_sic); write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[cw_non_sic],1,0); printf("cw %d, uncoded ber %f\n",cw_non_sic,uncoded_ber); - + free(uncoded_ber_bit); - uncoded_ber_bit = NULL; + uncoded_ber_bit = NULL; } - start_meas(&UE->dlsch_unscrambling_stats); + start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, 0, UE->dlsch[0][cw_non_sic], @@ -3511,26 +3511,26 @@ n(tikz_fname,"w"); UE->pdsch_vars[eNB_id]->llr[cw_non_sic], cw_non_sic, subframe<<1); - stop_meas(&UE->dlsch_unscrambling_stats); + stop_meas(&UE->dlsch_unscrambling_stats); start_meas(&UE->dlsch_decoding_stats); ret[cw_non_sic] = dlsch_decoding(UE, - UE->pdsch_vars[eNB_id]->llr[cw_non_sic], + UE->pdsch_vars[eNB_id]->llr[cw_non_sic], &UE->frame_parms, UE->dlsch[0][cw_non_sic], UE->dlsch[0][cw_non_sic]->harq_processes[UE->dlsch[0][cw_non_sic]->current_harq_pid], subframe, UE->dlsch[0][cw_non_sic]->current_harq_pid, 1,llr8_flag); - stop_meas(&UE->dlsch_decoding_stats); - - + stop_meas(&UE->dlsch_decoding_stats); + + if (ret[cw_non_sic] <= UE->dlsch[0][cw_non_sic]->max_turbo_iterations ) { //If CRC for the first CW did not fail - if (cw_non_sic==0) { + if (cw_non_sic==0) { avg_iter[0] += ret[0]; iter_trials[0]++; } - + if (n_frames==2) { printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); #ifdef PRINT_BYTES @@ -3539,9 +3539,9 @@ n(tikz_fname,"w"); Kr = UE->dlsch[0][cw_non_sic]->harq_processes[0]->Kminus; else Kr = UE->dlsch[0][cw_non_sic]->harq_processes[0]->Kplus; - + Kr_bytes = Kr>>3; - + printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][cw_non_sic]->harq_processes[0]->c[s][i], @@ -3549,10 +3549,10 @@ n(tikz_fname,"w"); } #endif } - + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[eNB_id][cw_non_sic]->harq_processes[UE->dlsch[eNB_id][cw_non_sic]->current_harq_pid]->TBS; - // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER + // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) if (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* @@ -3568,15 +3568,15 @@ n(tikz_fname,"w"); dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; dlsch0_eNB_harq->round = dlsch0_ue_harq->round; - + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - + UE->dlsch[eNB_id]->active = UE->dlsch[eNB_id][0]->active; UE->dlsch[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti; UE->dlsch[eNB_id]->current_harq_pid = UE->dlsch[eNB_id][0]->current_harq_pid; - + dlsch_encoding(UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, @@ -3586,7 +3586,7 @@ n(tikz_fname,"w"); &UE->dlsch_turbo_encoding_stats, &UE->dlsch_interleaving_stats ); - + coded_bits_per_codeword = get_G(&UE->frame_parms, UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->nb_rb, UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->rb_alloc, @@ -3594,8 +3594,8 @@ n(tikz_fname,"w"); UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->Nl, num_pdcch_symbols, 0,subframe); - - + + //scrambling dlsch_scrambling(&UE->frame_parms, 0, @@ -3603,8 +3603,8 @@ n(tikz_fname,"w"); coded_bits_per_codeword, 0, subframe<<1); - - + + //modulation re_allocated = dlsch_modulation(sic_buffer, AMP, @@ -3618,7 +3618,7 @@ n(tikz_fname,"w"); // compute the norm of the effective channel for both receive antennas -> alphha[0], alphha[2] // multiply with the norm of the effective channnel */ - + //stripping (from matched filter output of first stream = rxdataF_comp0) // this is pseudocode /* @@ -3626,8 +3626,8 @@ n(tikz_fname,"w"); UE->pdsch_vars[eNB_id].rxdataF_ext[i] -= alpha[i].*sic_buffer[i]; } */ - - //apply rho to output + + //apply rho to output /* dlsch_channel_compensation(UE->pdsch_vars[eNB_id].rxdataF_ext, UE->pdsch_vars[eNB_id].dl_ch_rho_ext[harq_pid][round], @@ -3645,19 +3645,19 @@ n(tikz_fname,"w"); */ - //detection of second stream + //detection of second stream //} - + } - + if ((UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && rx_type==rx_SIC_dual_stream) { - + // for (round = 0 ; round < 1 ; round++) { dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; - + dlsch0_eNB_harq->mimo_mode = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; @@ -3668,11 +3668,11 @@ n(tikz_fname,"w"); dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - + UE->dlsch_eNB[eNB_id]->active = UE->dlsch[eNB_id][0]->active; UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti; UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[eNB_id][0]->current_harq_pid; - + dlsch_encoding(input_buffer0[0], //UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, @@ -3682,8 +3682,8 @@ n(tikz_fname,"w"); &UE->dlsch_rate_matching_stats, &UE->dlsch_turbo_encoding_stats, &UE->dlsch_interleaving_stats); - - + + coded_bits_per_codeword[cw_non_sic]= get_G(&UE->frame_parms, UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, @@ -3707,13 +3707,13 @@ n(tikz_fname,"w"); UE->dlsch_eNB[0], NULL, coded_bits_per_codeword[cw_non_sic]); - + // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1); // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1); switch (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){ - + case 2: dlsch_qpsk_llr_SIC(&UE->frame_parms, @@ -3725,7 +3725,7 @@ n(tikz_fname,"w"); dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], - get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), + get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), UE->dlsch[eNB_id][0]); break; @@ -3760,9 +3760,9 @@ n(tikz_fname,"w"); UE->dlsch[eNB_id][0]); break; } - + // write_output("rxdata_llr1.m","llr1", UE->pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); - + for (cw_sic=cw_to_decode_interf_free; cw_sicdlsch[0][cw_sic]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[cw_sic]= get_G(&eNB->frame_parms, @@ -3773,14 +3773,14 @@ n(tikz_fname,"w"); num_pdcch_symbols, 0, subframe); - + UE->dlsch[0][cw_sic]->harq_processes[UE->dlsch[0][cw_sic]->current_harq_pid]->G = coded_bits_per_codeword[cw_sic]; UE->dlsch[0][cw_sic]->harq_processes[UE->dlsch[0][cw_sic]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][cw_sic]->harq_processes[0]->mcs); - + if (n_frames==2) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,cw_sic,coded_bits_per_codeword[cw_sic], UE->dlsch[0][cw_sic]->harq_processes[UE->dlsch[0][cw_sic]->current_harq_pid]->TBS); - + // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[cw_sic]); AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); @@ -3792,24 +3792,24 @@ n(tikz_fname,"w"); write_output(fname, vname,eNB->dlsch[0][cw_sic]->harq_processes[0]->e,coded_bits_per_codeword[cw_sic],1,4); uncoded_ber=0; printf("trials=%d\n", trials); - for (i=0;idlsch[0][cw_sic]->harq_processes[0]->e[i] != (UE->pdsch_vars[0]->llr[cw_sic][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } else uncoded_ber_bit[i] = 0; - + uncoded_ber/=coded_bits_per_codeword[cw_sic]; avg_ber += uncoded_ber; sprintf(fname,"cw%d_uncoded_ber_bit.m", cw_sic); sprintf(vname,"uncoded_ber_bit_cw%d", cw_sic); write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[cw_sic],1,0); - printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); + printf("cw %d, uncoded ber %f\n",cw_sic,uncoded_ber); free(uncoded_ber_bit); - uncoded_ber_bit = NULL; + uncoded_ber_bit = NULL; } - start_meas(&UE->dlsch_unscrambling_stats); + start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, 0, UE->dlsch[0][cw_sic], @@ -3817,26 +3817,26 @@ n(tikz_fname,"w"); UE->pdsch_vars[eNB_id]->llr[cw_sic], cw_sic, subframe<<1); - stop_meas(&UE->dlsch_unscrambling_stats); + stop_meas(&UE->dlsch_unscrambling_stats); start_meas(&UE->dlsch_decoding_stats); ret[1] = dlsch_decoding(UE, - UE->pdsch_vars[eNB_id]->llr[cw_sic], + UE->pdsch_vars[eNB_id]->llr[cw_sic], &UE->frame_parms, UE->dlsch[0][cw_sic], UE->dlsch[0][cw_sic]->harq_processes[UE->dlsch[0][cw_sic]->current_harq_pid], subframe, UE->dlsch[0][cw_sic]->current_harq_pid, 1,llr8_flag); - stop_meas(&UE->dlsch_decoding_stats); - - - if (ret[1] <= UE->dlsch[0][cw_sic]->max_turbo_iterations ) { //if (ret <= UE->dlsch[0][cw_sic]->max_turbo_iterations ) - + stop_meas(&UE->dlsch_decoding_stats); + + + if (ret[1] <= UE->dlsch[0][cw_sic]->max_turbo_iterations ) { //if (ret <= UE->dlsch[0][cw_sic]->max_turbo_iterations ) + avg_iter[1] += ret[1]; iter_trials[1]++; - - + + if (n_frames==2) { printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); #ifdef PRINT_BYTES @@ -3845,29 +3845,29 @@ n(tikz_fname,"w"); Kr = UE->dlsch[0][cw_sic]->harq_processes[0]->Kminus; else Kr = UE->dlsch[0][cw_sic]->harq_processes[0]->Kplus; - + Kr_bytes = Kr>>3; - + printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][cw_sic]->harq_processes[0]->c[s][i], UE->dlsch[0][cw_sic]->harq_processes[0]->c[s][i]^eNB->dlsch[0][cw_sic]->harq_processes[0]->c[s][i]); } #endif - } - - } - - + } + + } + + else { errs[cw_sic][round]++; // exit(0); - + if (cw_sic==1) { avg_iter[1] += ret[1]-1; iter_trials[1]++; } - + if (n_frames==2) { //if ((n_frames==1) || (SNR>=30)) { printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_sic,round,uncoded_ber); @@ -3877,9 +3877,9 @@ n(tikz_fname,"w"); Kr = UE->dlsch[0][cw_sic]->harq_processes[0]->Kminus; else Kr = UE->dlsch[0][cw_sic]->harq_processes[0]->Kplus; - + Kr_bytes = Kr>>3; - + printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][cw_sic]->harq_processes[0]->c[s][i], @@ -3888,33 +3888,33 @@ n(tikz_fname,"w"); #endif } //n_frames==1 // exit(0); - } //if (ret > UE->dlsch[0][cw_sic]->max_turbo_iterations ) + } //if (ret > UE->dlsch[0][cw_sic]->max_turbo_iterations ) } //for (int cw_1=cw_to_decode_interf_free; cw_1dlsch[0][cw_non_sic]->max_turbo_iterations ) else { errs[cw_non_sic][round]++; - + if (cw_non_sic==0) { avg_iter[0] += ret[0]-1; iter_trials[0]++; } - + if (rx_type==rx_SIC_dual_stream) { errs[1][round]++; } - + if (cw_non_sic==1) { avg_iter[1] += ret[1]-1; iter_trials[1]++; } - - - if (n_frames==2) { + + + if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",cw_non_sic,round,uncoded_ber); #ifdef PRINT_BYTES @@ -3923,9 +3923,9 @@ n(tikz_fname,"w"); Kr = UE->dlsch[0][cw_non_sic]->harq_processes[0]->Kminus; else Kr = UE->dlsch[0][cw_non_sic]->harq_processes[0]->Kplus; - + Kr_bytes = Kr>>3; - + printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][cw_non_sic]->harq_processes[0]->c[s][i], @@ -3935,10 +3935,10 @@ n(tikz_fname,"w"); } } } - + stop_meas(&UE->phy_proc_rx); - - if (n_frames==2) { + + if (n_frames==1) { //rxsig sprintf(fname,"rxsig0_r%d.m",round); @@ -3998,7 +3998,7 @@ n(tikz_fname,"w"); UE->frame_parms.ofdm_symbol_size*nsymb,1,1); } //pdsch_vars - //dump_dlsch2(UE,eNB_id,coded_bits_per_codeword[0],round,UE->dlsch[0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,coded_bits_per_codeword[0],round,UE->dlsch[0][0]->current_harq_pid); /* write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); @@ -4009,56 +4009,56 @@ n(tikz_fname,"w"); //pdcch_vars write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4); - - + + if (round == 3) exit(-1); } if (xforms==1) { - phy_scope_UE(form_ue, + phy_scope_UE(form_ue, UE, eNB_id, 0,// UE_id - subframe); + subframe); } - + round++; } //round if(transmission_mode != 3 && transmission_mode !=4 ){ if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) break; - } - + } + //len = chbch_stats_read(stats_buffer,NULL,0,4096); //printf("%s\n\n",stats_buffer); - + if (UE->proc.proc_rxtx[0].frame_rx % 10 == 0) { UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10; LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],UE->bitrate[eNB_id]/1000); UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id]; } - + UE->proc.proc_rxtx[0].frame_rx++; - - /* calculate the total processing time for each packet, + + /* calculate the total processing time for each packet, * get the max, min, and number of packets that exceed t>2000us */ - double t_tx = (double)eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - - - double t_rx = (double)UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; - + double t_tx = (double)eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; + double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; + + + double t_rx = (double)UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + if (t_tx > t_tx_max) t_tx_max = t_tx; if (t_tx < t_tx_min) @@ -4071,13 +4071,13 @@ n(tikz_fname,"w"); n_tx_dropped++; if (t_rx > 2000) n_rx_dropped++; - + push_front(&time_vector_tx, t_tx); push_front(&time_vector_tx_ifft, t_tx_ifft); push_front(&time_vector_tx_mod, t_tx_mod); push_front(&time_vector_tx_enc, t_tx_enc); - + push_front(&time_vector_rx, t_rx); push_front(&time_vector_rx_fft, t_rx_fft); push_front(&time_vector_rx_demod, t_rx_demod); @@ -4179,7 +4179,7 @@ n(tikz_fname,"w"); SNR, (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)), sigma2_dB); - + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e))," "dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f), " "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n", @@ -4220,8 +4220,8 @@ n(tikz_fname,"w"); rate[1]*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), rate[0], rate[1]); - - + + if (print_perf==1) { printf("eNB TX function statistics (per 1ms subframe)\n\n"); @@ -4369,19 +4369,19 @@ n(tikz_fname,"w"); rate[1]*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[0])), dci_errors); } - + if(abstx){ //ABSTRACTION - if ((transmission_mode != 3)&& (transmission_mode != 4)) { + if ((transmission_mode != 3)&& (transmission_mode != 4)) { blerr[0][0] = (double)errs[0][0]/(round_trials[0]); - + if(num_rounds>1){ blerr[0][1] = (double)errs[0][1]/(round_trials[1]); - + blerr[0][2] = (double)errs[0][2]/(round_trials[2]); - + blerr[0][3] = (double)errs[0][3]/(round_trials[3]); - + fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]); } else { @@ -4405,7 +4405,7 @@ n(tikz_fname,"w"); } } } - + if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); if ((transmission_mode != 3) && (transmission_mode != 4)) { @@ -4467,7 +4467,7 @@ n(tikz_fname,"w"); errs[0][3], round_trials[3], dci_errors); - + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", SNR, @@ -4497,7 +4497,7 @@ n(tikz_fname,"w"); (1.0*(round_trials[0]-errs[0][0])+2.0*(round_trials[1]-errs[0][1])+3.0*(round_trials[2]-errs[0][2])+4.0*(round_trials[3]-errs[0][3]))/((double)round_trials[0])); } //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", - fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", + fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", eNB->phy_proc_tx.trials, eNB->ofdm_mod_stats.trials, eNB->dlsch_modulation_stats.trials, @@ -4525,31 +4525,31 @@ n(tikz_fname,"w"); ); //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); - + //fprintf(time_meas_fd,"IFFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - + //fprintf(time_meas_fd,"MOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - + //fprintf(time_meas_fd,"ENC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - - + + //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); //fprintf(time_meas_fd,"FFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - + //fprintf(time_meas_fd,"DEMOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); - + //fprintf(time_meas_fd,"DEC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - - /* + + /* fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", eNB->phy_proc_tx.trials, eNB->ofdm_mod_stats.trials, @@ -4573,34 +4573,34 @@ n(tikz_fname,"w"); if (((double)errs[0][0]/(round_trials[0]))<1e-2 && ((double)errs[1][0]/(round_trials[0]))<1e-2) break; } - else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-2) + else{ + if (((double)errs[0][0]/(round_trials[0]))<1e-2) break; - + } } else { - + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { if (((double)errs[0][0]/(round_trials[0]))<1e-3 && ((double)errs[1][0]/(round_trials[0]))<1e-3) break; } - else{ - if (((double)errs[0][0]/(round_trials[0]))<1e-3) + else{ + if (((double)errs[0][0]/(round_trials[0]))<1e-3) break; - + } - + } - - + + if (n_frames==1) break; }// SNR - + } //ch_realization - + fclose(bler_fd); if (test_perf !=0) From 60eddd2c8f35ab6f5c8dc360632a1225e4a95507 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 25 Jan 2017 17:42:04 +0100 Subject: [PATCH 226/571] Fixing write_output arguments in dlsim_tm4.c --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index a5baa6a8a7..5bc8f5fac5 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -3946,14 +3946,14 @@ n(tikz_fname,"w"); write_output(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); sprintf(fname,"rxsigF0_r%d.m",round); sprintf(vname,"rxs0F_r%d",round); - write_output(fname,vname, &UE->common_vars.rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1); + write_output(fname,vname, &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); if (UE->frame_parms.nb_antennas_rx>1) { sprintf(fname,"rxsig1_r%d.m",round); sprintf(vname,"rxs1_r%d",round); write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1); sprintf(fname,"rxsig1F_r%d.m",round); sprintf(vname,"rxs1F_r%d",round); - write_output(fname,vname, UE->common_vars.rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1); + write_output(fname,vname, UE->common_vars.rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); } //channel From e88561e90d179c89a2af8857f1daef01d904b4c5 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Thu, 26 Jan 2017 10:51:29 +0100 Subject: [PATCH 227/571] copying dlsim.c to dlsim_tm4.c --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 5300 +++++++++++++++++++++++ 1 file changed, 5300 insertions(+) create mode 100755 openair1/SIMULATION/LTE_PHY/dlsim_tm4.c diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c new file mode 100755 index 0000000000..8e0e6ac0e7 --- /dev/null +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -0,0 +1,5300 @@ +/******************************************************************************* + 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 . + + 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 dlsim.c + \brief Top-level DL simulator + \author R. Knopp + \date 2011 - 2014 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr + \note + \warning +*/ + +//#define DEBUG_HARQ +//#define PRINT_THROUGHPUT + +#include +#include +#include +#include +#include +#include +#include "SIMULATION/TOOLS/defs.h" +#include "PHY/types.h" +#include "PHY/defs.h" +#include "PHY/vars.h" + +#include "SCHED/defs.h" +#include "SCHED/vars.h" +#include "LAYER2/MAC/vars.h" +#include "OCG_vars.h" +#include "UTIL/LOG/log.h" +#include "UTIL/LISTS/list.h" + +extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; +extern unsigned char offset_mumimo_llr_drange_fix; + +extern uint8_t interf_unaw_shift0; +extern uint8_t interf_unaw_shift1; +extern uint8_t interf_unaw_shift; + +#include "PHY/TOOLS/lte_phy_scope.h" + +#define PRINT_BYTES + +PHY_VARS_eNB *PHY_vars_eNB; +PHY_VARS_UE *PHY_vars_UE; + +int otg_enabled=0; +/*the following parameters are used to control the processing times calculations*/ +double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */ +double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */ +double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ +double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */ +int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ +int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ + +void handler(int sig) +{ + void *array[10]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, 10); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(1); +} + + + +//DCI2_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_2A[2]; + +DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_1E[2]; +uint64_t DLSCH_alloc_pdu_1[2]; + +#define UL_RB_ALLOC 0x1ff; +#define CCCH_RB_ALLOC computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_UL,0,2) +//#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13 +//#define DLSCH_RB_ALLOC 0x0001 +void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) +{ + + int aa, slot_offset, slot_offset_F; + + slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7); + slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); + + for (aa=0; aanb_antennas_tx; aa++) { + // printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc()); + + if (frame_parms->Ncp == 1) + PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input + &txdata[aa][slot_offset], // output + frame_parms->ofdm_symbol_size, + 6, // number of symbols + frame_parms->nb_prefix_samples, // number of prefix samples + CYCLIC_PREFIX); + else { + normal_prefix_mod(&txdataF[aa][slot_offset_F], + &txdata[aa][slot_offset], + 7, + frame_parms); + } + + + } + +} + +int main(int argc, char **argv) +{ + + int c; + int k,i,aa,aarx,aatx; + + int s,Kr,Kr_bytes; + + double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1,rate[2]; + double snr_step=1,input_snr_step=1, snr_int=30; + + LTE_DL_FRAME_PARMS *frame_parms; + double **s_re,**s_im,**r_re,**r_im; + double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel + double iqim=0.0; + + uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx=1,n_rx=1; + uint16_t Nid_cell=0; + + int8_t eNB_id = 0, eNB_id_i = 1; + unsigned char mcs1=0,mcs2=0,mcs_i=0,awgn_flag=0,dci_flag=0; + unsigned char i_mod = 2; + unsigned short NB_RB; + unsigned char Ns,l,m; + uint16_t tdd_config=3; + uint16_t n_rnti=0x1234; + int n_users = 1; + int TB=0; + RX_type_t rx_type=rx_standard; + unsigned char cur_harq_pid; + int hold_rank1_precoder=0; + int tpmi_retr=2; + bool is_first_time; + int updated_csi = 0; + + + SCM_t channel_model=Rayleigh1; + // unsigned char *input_data,*decoded_output; + + unsigned char *input_buffer0[2],*input_buffer1[2]; + unsigned short input_buffer_length0,input_buffer_length1; + + /* A variable "ret" is a nuumber of turbo iterations, that are performed in the turbo-decoder for each CW. + The decoder checks CRC, and if CRC test fails, it increments "ret". Ret is between 1 and 4, where 4 is for + the max number of turbo iterations. If the CRC is passed, ret is equal to a current iteration. + This is done separately for each CW inside decoding process. + Again: this is not a HARQ retransmission!*/ + unsigned int ret[2]; + unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; + + unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, decoded_in_sic[4]={0,0,0,0}, sic_attempt[4]={0,0,0,0}, round_sic=0; + unsigned int dci_errors=0, dlsch_active=0, num_layers; + unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}, TB0_deact[4]={0,0,0,0}, TB1_deact[4]={0,0,0,0}; + + int re_allocated; + char fname[32],vname[32]; + FILE *bler_fd; + char bler_fname[256]; + FILE *time_meas_fd; + char time_meas_fname[256]; + + //qFILE *tikz_fd; + //char tikz_fname[256]; + + FILE *input_trch_fd=NULL; + unsigned char input_trch_file=0; + FILE *input_fd=NULL; + unsigned char input_file=0; + // char input_val_str[50],input_val_str2[50]; + + char input_trch_val[16]; + double channelx,channely; + + // unsigned char pbch_pdu[6]; + + DCI_ALLOC_t dci_alloc[8],dci_alloc_rx[8]; + int num_common_dci=0,num_ue_spec_dci=0,num_dci=0; + + // FILE *rx_frame_file; + + int n_frames; + int n_ch_rlz = 1; + channel_desc_t *eNB2UE[8]; + uint8_t num_pdcch_symbols=1,num_pdcch_symbols_2=0; + uint8_t pilot1,pilot2,pilot3; + uint8_t rx_sample_offset = 0; + //char stats_buffer[4096]; + //int len; + + uint8_t num_rounds = 4; + uint8_t subframe=7; + int u; + int n=0; + int abstx=0; + int iii; + FILE *csv_fd=NULL; + char csv_fname[512]; + int ch_realization; + int pmi_feedback=0; + int hold_channel=0; + + + // temporarily for retransmissions: + unsigned char resend_cw1=0; //if 0 resend only cw0 + unsigned char resend_cw0_cw1=1; //if 0 resend both cw in a normal way + + // void *data; + // int ii; + int bler; + double blerr[2][4],uncoded_ber,avg_ber; + short *uncoded_ber_bit=NULL; + uint8_t N_RB_DL=25,osf=1; + uint8_t fdd_flag = 0; + frame_t frame_type = FDD; + int xforms=0; + FD_lte_phy_scope_ue *form_ue = NULL; + char title[255]; + uint32_t DLSCH_RB_ALLOC = 0x1fff; + int numCCE=0; + int dci_length_bytes=0,dci_length=0; + int common_flag=0,TPC=0; + + double cpu_freq_GHz; + //time_stats_t ts;//,sts,usts; + int avg_iter[2],iter_trials[2]; + int rballocset=0; + int print_perf=0; + int test_perf=0; + int dump_table=0; + int llr8_flag=0; + + double effective_rate=0.0; + double thr_cw0_tm4 = 0.0; + double thr_cw0_tm4_nonconst = 0.0; + double thr_cw0[4]={0,0,0,0}, thr_cw1[4]={0,0,0,0}, thr_cw0_tot = 0.0, thr_cw1_tot = 0.0; + unsigned int tbs0_init=0, tbs1_init=0; + double rate0_init=0.0, rate1_init=0.0; + int mcs0_init=0, mcs1_init=0, mod_order0_init = 0, mod_order1_init=0; + char channel_model_input[17]="I"; + + int TB0_active = 1; + int TB1_active = 1; + + uint32_t perfect_ce = 0; + + LTE_DL_UE_HARQ_t *dlsch0_ue_harq; + LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; + uint8_t Kmimo; + + int32_t **sic_buffer; + int8_t cw_to_decode_interf; + int8_t cw_to_decode_interf_free; + int8_t cw_non_sic; + int8_t cw_sic; + FILE *proc_fd = NULL; + char buf[64]; + uint8_t ue_category=4; + uint32_t Nsoft; + + int CCE_table[800]; + + int threequarter_fs=0; + + + + opp_enabled=1; // to enable the time meas + +#if defined(__arm__) + FILE *proc_fd = NULL; + char buf[64]; + + proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r"); + if(!proc_fd) + printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq"); + else { + while(fgets(buf, 63, proc_fd)) + printf("%s", buf); + } + fclose(proc_fd); + cpu_freq_GHz = ((double)atof(buf))/1e6; +#else + cpu_freq_GHz = get_cpu_freq_GHz(); +#endif + printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + + //signal(SIGSEGV, handler); + //signal(SIGABRT, handler); + + logInit(); + set_glog(LOG_INFO, LOG_MED); + + // default parameters + n_frames = 1000; + snr0 = 0; + // num_layers = 1; + perfect_ce = 0; + + while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XYv:W:J:K:U")) != -1) { + + switch (c) { + case 'a': + awgn_flag = 1; + channel_model = AWGN; + break; + + case 'A': + abstx = 1; + break; + + case 'b': + tdd_config=atoi(optarg); + break; + + case 'B': + N_RB_DL=atoi(optarg); + break; + + case 'c': + num_pdcch_symbols=atoi(optarg); + break; + + case 'C': + Nid_cell = atoi(optarg); + break; + + case 'd': + dci_flag = 1; + break; + + case 'D': + frame_type=TDD; + break; + + case 'e': + num_rounds=1; + common_flag = 1; + TPC = atoi(optarg); + break; + + case 'E': + threequarter_fs=1; + break; + + case 'f': + input_snr_step= atof(optarg); + break; + + case 'F': + forgetting_factor = atof(optarg); + break; + + case 'i': + input_fd = fopen(optarg,"r"); + input_file=1; + dci_flag = 1; + break; + + case 'I': + input_trch_fd = fopen(optarg,"r"); + input_trch_file=1; + break; + + case 'L': + llr8_flag=1; + break; + + case 'l': + offset_mumimo_llr_drange_fix=atoi(optarg); + break; + + case 'm': + mcs1 = atoi(optarg); + break; + + case 'M': + mcs2 = atoi(optarg); + //i_mod = get_Qm(mcs2); /// think here again!!! + break; + + case 'O': + test_perf=atoi(optarg); + //print_perf =1; + break; + + case 't': + mcs_i = atoi(optarg); + i_mod = get_Qm(mcs_i); + break; + + case 'n': + n_frames = atoi(optarg); + break; + + case 'o': + rx_sample_offset = atoi(optarg); + break; + + case 'r': + DLSCH_RB_ALLOC = atoi(optarg); + rballocset = 1; + break; + + case 's': + snr0 = atof(optarg); + break; + + case 'w': + snr_int = atof(optarg); + break; + + case 'N': + n_ch_rlz= atof(optarg); + break; + + case 'p': + extended_prefix_flag=1; + break; + + case 'g': + memcpy(channel_model_input,optarg,17); + + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; + case 'B': + channel_model=SCM_B; + break; + case 'C': + channel_model=SCM_C; + break; + case 'D': + channel_model=SCM_D; + break; + case 'E': + channel_model=EPA; + break; + case 'F': + channel_model=EVA; + break; + case 'G': + channel_model=ETU; + break; + case 'H': + channel_model=Rayleigh8; + break; + case 'I': + channel_model=Rayleigh1; + break; + case 'J': + channel_model=Rayleigh1_corr; + break; + case 'K': + channel_model=Rayleigh1_anticorr; + break; + case 'L': + channel_model=Rice8; + break; + case 'M': + channel_model=Rice1; + break; + case 'N': + channel_model=AWGN; + break; + case 'P': + channel_model=Rayleigh1_orthogonal; + break; + case 'Q': + channel_model=Rayleigh1_orth_eff_ch_TM4_prec_real; // for DUALSTREAM_UNIFORM_PRECODING1 when interf is precancelled + break; + case 'R': + channel_model=Rayleigh1_orth_eff_ch_TM4_prec_imag; // for DUALSTREAM_UNIFORM_PRECODINGj when interf is precancelled + break; + case 'S': + channel_model=Rayleigh8_orth_eff_ch_TM4_prec_real;//when interf is precancelled + break; + case 'T': + channel_model=Rayleigh8_orth_eff_ch_TM4_prec_imag;//when interf is precancelled + break; + case 'U': + channel_model = TS_SHIFT; + break; + case 'V': + channel_model=EPA_low; + break; + case 'W': + channel_model=EPA_medium; + break; + case 'X': + channel_model=EPA_high; + break; + default: + msg("Unsupported channel model!\n"); + exit(-1); + } + break; + case 'x': + transmission_mode=atoi(optarg); + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=3) && + (transmission_mode!=4) && + (transmission_mode!=5) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } + if (transmission_mode>1) { + n_tx = 2; + } + break; + case 'y': + n_tx=atoi(optarg); + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } + break; + case 'z': + n_rx=atoi(optarg); + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } + break; + + case 'R': + num_rounds=atoi(optarg); + break; + case 'S': + subframe=atoi(optarg); + break; + case 'T': + n_rnti=atoi(optarg); + break; + case 'u': + rx_type = (RX_type_t) atoi(optarg); + if (rx_typerx_SIC_dual_stream) { + printf("Unsupported rx type %d\n",rx_type); + exit(-1); + } + break; + case 'v': + i_mod = atoi(optarg); + if (i_mod!=2 && i_mod!=4 && i_mod!=6) { + msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + exit(-1); + } + break; + case 'P': + print_perf=1; + break; + case 'X': + xforms = 1; + break; + case 'Z': + dump_table=1; + break; + case 'Y': + perfect_ce=1; + break; + case 'V': + interf_unaw_shift0=atoi(optarg); + break; + case 'W': + interf_unaw_shift1=atoi(optarg); + break; + case 'J': + interf_unaw_shift=atoi(optarg); + break; + case 'K': + tpmi_retr = atoi(optarg); + //i_mod = get_Qm(mcs2); /// think here again!!! + break; + case 'U': + updated_csi=1; + break; + case 'h': + default: + printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]); + printf("-h This message\n"); + printf("-a Use AWGN channel and not multipath\n"); + printf("-c Number of PDCCH symbols\n"); + printf("-m MCS1 for TB 1\n"); + printf("-M MCS2 for TB 2\n"); + printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n"); + printf("-p Use extended prefix mode\n"); + printf("-n Number of frames to simulate\n"); + printf("-o Sample offset for receiver\n"); + printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); + printf("-f step size of SNR, default value is 1.\n"); + printf("-r resource block allocation (see section 7.1.6.3 in 36.213\n"); + printf("-g Channel model, possible values are 3GPP 25.814 SCM-A/B/C/D('A','B','C','D'), 36-101 EPA('E'), EVA ('F'),ETU('G'), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr('K'), Rice8('L'), Rice1('M'), AWGN('N'), Rayleigh1_orthogonal('P'), Rayleigh1_orth_eff_ch_TM4_prec_real ('Q'), Rayleigh1_orth_eff_ch_TM4_prec_imag ('R'), Rayleigh8_orth_eff_ch_TM4_prec_real ('S'),Rayleigh8_orth_eff_ch_TM4_prec_imag ('T'), EPA_low ('V'), EPA_medium ('W'), EPA_high ('X') \n"); + printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-t MCS of interfering UE\n"); + printf("-R Number of HARQ rounds (fixed)\n"); + printf("-A Turns on calibration mode for abstraction.\n"); + printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); + printf("-O Set the percentage of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); + printf("-I Input filename for TrCH data (binary)\n"); + printf("-u Receiver type: 0=standard, 1 = single stream IC (for TM3,4,5,6), 2 = dual stream IC (for TM3,4), 3 = SIC (for TM3,4) \n"); + exit(1); + break; + + } + } + + if (common_flag == 0) { + switch (N_RB_DL) { + case 6: + if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; + num_pdcch_symbols = 3; + break; + + case 25: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; + break; + + case 50: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; + break; + + case 100: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; + break; + } + + NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); + } else + NB_RB = 4; + + NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); + + if ((transmission_mode > 1) && (n_tx != 2)) { + + printf("n_tx must be >1 for transmission_mode %d\n",transmission_mode); + exit(-1); + } + + if (((transmission_mode==1) || (transmission_mode==2)) && (rx_type != rx_standard)) { + printf("only standard rx available for TM1 and TM2\n"); + exit(-1); + } + if (((transmission_mode==5) || (transmission_mode==6)) && (rx_type > rx_IC_single_stream)) { + printf("only standard rx or single stream IC available for TM5 and TM6\n"); + exit(-1); + } + + + if (xforms==1) { + fl_initialize (&argc, argv, NULL, 0, 0); + form_ue = create_lte_phy_scope_ue(); + sprintf (title, "LTE PHY SCOPE eNB"); + fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + /* + if (rx_type==rx_IC_single_stream) { + openair_daq_vars.use_ia_receiver = 1; + fl_set_button(form_ue->button_0,1); + fl_set_object_label(form_ue->button_0, "IA Receiver ON"); + fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN); + } + + */ + } + + if (transmission_mode==5) { + n_users = 2; + eNB_id_i = PHY_vars_UE->n_connected_eNB; + //eNB_id_i=1; + } + else + eNB_id_i = eNB_id; + + lte_param_init(n_tx, + n_rx, + transmission_mode, + extended_prefix_flag, + frame_type, + Nid_cell, + tdd_config, + N_RB_DL, + threequarter_fs, + osf, + perfect_ce); + + + printf("Setting mcs1 = %d\n",mcs1); + printf("Setting mcs2 = %d\n",mcs2); + printf("NPRB = %d\n",NB_RB); + printf("n_frames = %d\n",n_frames); + printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag); + printf("Using receiver type %d\n", rx_type); + printf("TM1 shift %d\n", interf_unaw_shift); + //printf("Using I_UA rec shift layer 1 %d\n", interf_unaw_shift0); + //printf("Using I_UA rec shift layer 2 %d\n", interf_unaw_shift1); + snr1 = snr0+snr_int; + printf("SNR0 %f, SNR1 %f\n",snr0,snr1); + + /* + txdataF = (int **)malloc16(2*sizeof(int*)); + txdataF[0] = (int *)malloc16(FRAME_LENGTH_BYTES); + txdataF[1] = (int *)malloc16(FRAME_LENGTH_BYTES); + + txdata = (int **)malloc16(2*sizeof(int*)); + txdata[0] = (int *)malloc16(FRAME_LENGTH_BYTES); + txdata[1] = (int *)malloc16(FRAME_LENGTH_BYTES); + */ + + frame_parms = &PHY_vars_eNB->lte_frame_parms; + + s_re = malloc(2*sizeof(double*)); //transmitted signal (Sent) + s_im = malloc(2*sizeof(double*)); + r_re = malloc(2*sizeof(double*)); //received signal + r_im = malloc(2*sizeof(double*)); + // r_re0 = malloc(2*sizeof(double*)); + // r_im0 = malloc(2*sizeof(double*)); + + nsymb = (PHY_vars_eNB->lte_frame_parms.Ncp == 0) ? 14 : 12; + + printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); + printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d, Rayleigh1_orthogonal=%d, Rayleigh1_orth_eff_ch_TM4_prec_real22=%d, Rayleigh1_orth_eff_ch_TM4_prec_imag=%d, Rayleigh8_orth_eff_ch_TM4_prec_real=%d, Rayleigh8_orth_eff_ch_TM4_prec_imag=%d , TS_SHIFT=%d\n", + SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8, Rayleigh1_orthogonal, Rayleigh1_orth_eff_ch_TM4_prec_real, Rayleigh1_orth_eff_ch_TM4_prec_imag, Rayleigh8_orth_eff_ch_TM4_prec_real, Rayleigh8_orth_eff_ch_TM4_prec_imag, TS_SHIFT); + if(transmission_mode==5) + sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); + else if (abstx == 1){ + if (perfect_ce==1) + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); + else + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); + } + else {//abstx=0 + if (perfect_ce==1){ + if (updated_csi==1){ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + else{ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + } + else{ + if (updated_csi==1){ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + else{ + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%d.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + } + } + } + + bler_fd = fopen(bler_fname,"w"); + if (bler_fd==NULL) { + fprintf(stderr,"Cannot create file %s!\n",bler_fname); + exit(-1); + } + if ((transmission_mode != 3) && (transmission_mode != 4)) + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n"); + else if (rx_type == rx_SIC_dual_stream) + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); + else + fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n"); + + + if (test_perf != 0) { + + char hostname[1024]; + + hostname[1023] = '\0'; + gethostname(hostname, 1023); + printf("Hostname: %s\n", hostname); + //char dirname[FILENAME_MAX]; + //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname ); + sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv", + N_RB_DL,mcs1,n_tx,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode); + //mkdir(dirname,0777); + time_meas_fd = fopen(time_meas_fname,"w"); + if (time_meas_fd==NULL) { + fprintf(stderr,"Cannot create file %s!\n",time_meas_fname); + exit(-1); + } + } + + if(abstx){ + // CSV file // add here second stream mcs + + if (transmission_mode == 5) + sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d_abstr.m",transmission_mode,rx_type,mcs1,channel_model,n_frames,num_rounds); + + else + if (perfect_ce==1) + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + else + sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + + csv_fd = fopen(csv_fname,"w"); + fprintf(csv_fd,"data_all%d=[",mcs1); + if (csv_fd==NULL) { + fprintf(stderr,"Cannot create file %s!\n",csv_fname); + exit(-1); + } + } + + for (i=0; i<2; i++) { + s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + // r_re0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + // bzero(r_re0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + // r_im0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + // bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); + } + + + PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = n_rnti; + PHY_vars_UE->transmission_mode[eNB_id]=transmission_mode; + if (PHY_vars_UE->transmission_mode[eNB_id] !=4) // add TM3 exception + PHY_vars_UE->PHY_measurements.rank[eNB_id]=0; + else + PHY_vars_UE->PHY_measurements.rank[eNB_id]=1; + // Fill in UL_alloc + UL_alloc_pdu.type = 0; + UL_alloc_pdu.hopping = 0; + UL_alloc_pdu.rballoc = UL_RB_ALLOC; + UL_alloc_pdu.mcs = 1; + UL_alloc_pdu.ndi = 1; + UL_alloc_pdu.TPC = 0; + UL_alloc_pdu.cqi_req = 1; + + CCCH_alloc_pdu.type = 0; + CCCH_alloc_pdu.vrb_type = 0; + CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; + CCCH_alloc_pdu.ndi = 1; + CCCH_alloc_pdu.mcs = 1; + CCCH_alloc_pdu.harq_pid = 0; + + DLSCH_alloc_pdu2_1E[0].rah = 0; + DLSCH_alloc_pdu2_1E[0].rballoc = DLSCH_RB_ALLOC; + DLSCH_alloc_pdu2_1E[0].TPC = 0; + DLSCH_alloc_pdu2_1E[0].dai = 0; + DLSCH_alloc_pdu2_1E[0].harq_pid = 0; + //DLSCH_alloc_pdu2_1E[0].tb_swap = 0; + DLSCH_alloc_pdu2_1E[0].mcs = mcs1; + DLSCH_alloc_pdu2_1E[0].ndi = 1; + DLSCH_alloc_pdu2_1E[0].rv = 0; + // Forget second codeword + DLSCH_alloc_pdu2_1E[0].tpmi = (transmission_mode>=5 ? 5 : 0); // precoding + DLSCH_alloc_pdu2_1E[0].dl_power_off = (transmission_mode==5 ? 0 : 1); + + DLSCH_alloc_pdu2_1E[1].rah = 0; + DLSCH_alloc_pdu2_1E[1].rballoc = DLSCH_RB_ALLOC; + DLSCH_alloc_pdu2_1E[1].TPC = 0; + DLSCH_alloc_pdu2_1E[1].dai = 0; + DLSCH_alloc_pdu2_1E[1].harq_pid = 0; + //DLSCH_alloc_pdu2_1E[1].tb_swap = 0; + DLSCH_alloc_pdu2_1E[1].mcs = mcs_i; + DLSCH_alloc_pdu2_1E[1].ndi = 1; + DLSCH_alloc_pdu2_1E[1].rv = 0; + // Forget second codeword + DLSCH_alloc_pdu2_1E[1].tpmi = (transmission_mode>=5 ? 5 : 0) ; // precoding + DLSCH_alloc_pdu2_1E[1].dl_power_off = (transmission_mode==5 ? 0 : 1); + + + eNB2UE[0] = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, + PHY_vars_UE->lte_frame_parms.nb_antennas_rx, + channel_model, + N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + forgetting_factor, + rx_sample_offset, + 0); + + if(num_rounds>1) { // 8 is because the round counters are independent across the CW + for(n=1; n<8; n++) + eNB2UE[n] = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, + PHY_vars_UE->lte_frame_parms.nb_antennas_rx, + channel_model, + N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + forgetting_factor, + rx_sample_offset, + 0); + } + + + + if (eNB2UE[0]==NULL) { + msg("Problem generating channel model. Exiting.\n"); + exit(-1); + } + + if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8)) + Kmimo=2; + else + Kmimo=1; + + switch (ue_category) { + case 1: + Nsoft = 250368; + break; + case 2: + case 3: + Nsoft = 1237248; + break; + case 4: + Nsoft = 1827072; + break; + default: + printf("Unsupported UE category %d\n",ue_category); + exit(-1); + break; + } + + for (k=0; kdlsch_eNB[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0); + + if (!PHY_vars_eNB->dlsch_eNB[k][i]) { + printf("Can't get eNB dlsch structures\n"); + exit(-1); + } + + PHY_vars_eNB->dlsch_eNB[k][i]->rnti = n_rnti+k; + } + } + + for (i=0; i<2; i++) { + PHY_vars_UE->dlsch_ue[0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + + if (!PHY_vars_UE->dlsch_ue[0][i]) { + printf("Can't get ue dlsch structures\n"); + exit(-1); + } + + PHY_vars_UE->dlsch_ue[0][i]->rnti = n_rnti; + } + + // structure for SIC at UE + PHY_vars_UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0); + + if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { + + PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); + + if (n_users>1) + PHY_vars_eNB->eNB_UE_stats[1].DL_pmi_single = (PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI + } else { + PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = 0; + + if (n_users>1) + PHY_vars_eNB->eNB_UE_stats[1].DL_pmi_single = 0; + } + + + sic_buffer = (int32_t **) malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t *) ); + for (i=0; inb_antennas_tx; i++) { + sic_buffer[i] = malloc16_clear(FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + } + + if (input_fd==NULL) { + + // UE specific DCI + for(k=0; klte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1_1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1_10MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1_20MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); + break; + } + } + else { //fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format1; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format1, + PHY_vars_eNB->dlsch_eNB[0], + &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); + num_dci++; + num_ue_spec_dci++; + } + else { //common flag =1 + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } + else { // fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_common_dci++; + num_dci++; + + } + break; + case 3: //LARGE CDD + if (common_flag == 0) { + + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) {// here DCI does not contain any precoder information. matrix is fixed as identity, but dont forget aboy cycling + + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 25: + dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 50: + dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 100: + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); + break; + } + } + + else { // fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 25: + dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 50: + dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + case 100: + dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + } + } + } + else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { //4 antenna, needs diff precoding codebook index depeneding on layers + + } + + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format2A; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_dci++; + num_ue_spec_dci++; + } + else { //commonn flag 1 + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { //tdd + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } + else { //fdd + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_common_dci++; + num_dci++; + + } + printf("Generated DCI format 2A (Transmission Mode 3)\n"); + break; + + case 4: // !!! this dci format contains precoder information + if (common_flag == 0) { + + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 2) { + + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 25: + dci_length = sizeof_DCI2_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + + break; + case 50: + dci_length = sizeof_DCI2_10MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + + break; + case 100: + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + dci_length = sizeof_DCI2_20MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); + break; + } + } + + else { + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 25: + dci_length = sizeof_DCI2_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 50: + dci_length = sizeof_DCI2_10MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + case 100: + dci_length = sizeof_DCI2_20MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tb_swap = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi = 2; + break; + } + } + } + else if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx == 4) { + + } + + printf ("TM4 with tpmi =%d\n", ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi); + if ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) || (((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) { + + PHY_vars_eNB->eNB_UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); + + } + + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format2; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_dci++; + num_ue_spec_dci++; + } + else { //common_flag==1 + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } + else { + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(PHY_vars_eNB->lte_frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + PHY_vars_eNB->dlsch_eNB[0], + &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); + + num_common_dci++; + num_dci++; + + } + break; + + case 5: + case 6: + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + dci_alloc[num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format1E_2A_M10PRB; + dci_alloc[num_dci].firstCCE = 4*k; + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu2_1E[k], + n_rnti+k, + format1E_2A_M10PRB, + PHY_vars_eNB->dlsch_eNB[k], + &PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + PHY_vars_eNB->eNB_UE_stats[k].DL_pmi_single); + + dump_dci(&PHY_vars_eNB->lte_frame_parms,&dci_alloc[num_dci]); + num_ue_spec_dci++; + num_dci++; + + break; + + default: + printf("Unsupported Transmission Mode!!!"); + exit(-1); + break; + } + + + + + /* + memcpy(&dci_alloc[1].dci_pdu[0],&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD0_t)); + dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_0_t; + dci_alloc[1].L = 2; + dci_alloc[1].rnti = n_rnti; + */ + } + + if (n_frames==1) + printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE); + + numCCE = get_nCCE(num_pdcch_symbols,&PHY_vars_eNB->lte_frame_parms,get_mi(&PHY_vars_eNB->lte_frame_parms,subframe)); + + if (n_frames==1) + printf("%d\n",numCCE); + + // apply RNTI-based nCCE allocation + memset(CCE_table,0,800*sizeof(int)); + + for (i=num_common_dci; idlsch_eNB[k][0]->harq_processes[0]->TBS/8; + input_buffer0[k] = (unsigned char *)malloc(input_buffer_length0+4); + memset(input_buffer0[k],0,input_buffer_length0+4); + input_buffer_length1 = PHY_vars_eNB->dlsch_eNB[k][1]->harq_processes[0]->TBS/8; + input_buffer1[k] = (unsigned char *)malloc(input_buffer_length1+4); + memset(input_buffer1[k],0,input_buffer_length1+4); + + if (input_trch_file==0) { + for (i=0; i>3]+=(1<<(7-(i&7))); + + if (i<16) + printf("input_trch_val %d : %c\n",i,input_trch_val[0]); + + i++; + + if (((i%8) == 0) && (i<17)) + printf("%x\n",input_buffer0[k][(i-1)>>3]); + } + + printf("Read in %d bits\n",i); + } + } + } + + snr_step = input_snr_step; + PHY_vars_UE->high_speed_flag = 1; + PHY_vars_UE->ch_est_alpha=0; + + for (ch_realization=0; ch_realizationframe_rx=0; + for (i=0; i<4; i++) { + errs[0][i]=0; //CW_0 + errs[1][i]=0; //CW_1 + decoded_in_sic[i]=0; + sic_attempt[i]=0; + resend_one[i]=0; + resend_both[i]=0; + + round_trials[0][i] = 0; // CW_0 + round_trials[1][i] = 0; // CW_1 + TB0_deact[i]=0; + TB1_deact[i]=0; + } + dci_errors=0; + + round = 0; + avg_iter[0] = 0; + avg_iter[1] = 0; + iter_trials[0]=0; + iter_trials[1]=0; + reset_meas(&PHY_vars_eNB->phy_proc_tx); // total eNB tx + reset_meas(&PHY_vars_eNB->dlsch_scrambling_stats); + reset_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + reset_meas(&PHY_vars_eNB->ofdm_mod_stats); + reset_meas(&PHY_vars_eNB->dlsch_modulation_stats); + reset_meas(&PHY_vars_eNB->dlsch_encoding_stats); + reset_meas(&PHY_vars_eNB->dlsch_interleaving_stats); + reset_meas(&PHY_vars_eNB->dlsch_rate_matching_stats); + reset_meas(&PHY_vars_eNB->dlsch_turbo_encoding_stats); + + reset_meas(&PHY_vars_UE->phy_proc_rx); // total UE rx + reset_meas(&PHY_vars_UE->ofdm_demod_stats); + reset_meas(&PHY_vars_UE->dlsch_channel_estimation_stats); + reset_meas(&PHY_vars_UE->dlsch_freq_offset_estimation_stats); + reset_meas(&PHY_vars_UE->rx_dft_stats); + reset_meas(&PHY_vars_UE->dlsch_decoding_stats); + reset_meas(&PHY_vars_UE->dlsch_turbo_decoding_stats); + reset_meas(&PHY_vars_UE->dlsch_deinterleaving_stats); + reset_meas(&PHY_vars_UE->dlsch_rate_unmatching_stats); + reset_meas(&PHY_vars_UE->dlsch_tc_init_stats); + reset_meas(&PHY_vars_UE->dlsch_tc_alpha_stats); + reset_meas(&PHY_vars_UE->dlsch_tc_beta_stats); + reset_meas(&PHY_vars_UE->dlsch_tc_gamma_stats); + reset_meas(&PHY_vars_UE->dlsch_tc_ext_stats); + reset_meas(&PHY_vars_UE->dlsch_tc_intl1_stats); + reset_meas(&PHY_vars_UE->dlsch_tc_intl2_stats); + // initialization + struct list time_vector_tx; + initialize(&time_vector_tx); + struct list time_vector_tx_ifft; + initialize(&time_vector_tx_ifft); + struct list time_vector_tx_mod; + initialize(&time_vector_tx_mod); + struct list time_vector_tx_enc; + initialize(&time_vector_tx_enc); + + struct list time_vector_rx; + initialize(&time_vector_rx); + struct list time_vector_rx_fft; + initialize(&time_vector_rx_fft); + struct list time_vector_rx_demod; + initialize(&time_vector_rx_demod); + struct list time_vector_rx_dec; + initialize(&time_vector_rx_dec); + + for (trials = 0;trialsnb_antennas_tx; i++) { + memset(sic_buffer[i], 0, FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + } + //PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + //memset(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[0], 0, (8*((3*8*6144)+12))*sizeof(int16_t)); + //memset(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1], 0, (8*((3*8*6144)+12))*sizeof(int16_t)); + //if (trials%100==0) + eNB2UE[0]->first_run = 1; + + ret[0] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; + ret[1] = PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations+1; + + resend_cw0_cw1=1; + resend_cw1=0; + TB0_active=1; + TB1_active=1; + + while (((transmission_mode == 3 || transmission_mode == 4) && + ((round < num_rounds) && ((ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) || + (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) || + ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && + (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)))) { +#ifdef DEBUG_HARQ + printf("\n [DLSIM] On top round is %d\n", round); +#endif + + + round_trials[0][round]++; + round_trials[1][round]++; + + //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); + + /*if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) { + round_trials[0][round]++; + round_trials[1][round]++; + } else if ((ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations) && (ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)) + round_trials[1][round]++;*/ + + +#ifdef DEBUG_HARQ + printf("[DLSIM] Just after while loop TB0 status %d TB1 status %d round %d\n", TB0_active, TB1_active, round); +#endif + + // printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials TB0 = %d, round_trials TB1 = %d \n",trials,round, ret[0], ret[1], round_trials[0][round], round_trials[1][round]); + + + /*printf("Trial %d, round cw0 = %d , round cw1 = %d, ret[0] = %d, ret[1] = %d, round_trials cw0 [%d]= %d, round_trials cw1 [%d]= %d\n",trials, round, round, \ + ret[0], ret[1], round, round_trials[0][round], round, round_trials[1][round]);*/ + + //printf("round_trials %d round %d\n", round_trials[round], round); + + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) + pmi_feedback=1; + else + pmi_feedback=0; + + if (abstx) { + if (trials==0 && round==0 && SNR==snr0) //generate a new channel + hold_channel = 0; + else + hold_channel = 1; + } + else + hold_channel = 0;//(round==0) ? 0 : 1; + + PMI_FEEDBACK: + + //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); + for (aa=0; aalte_frame_parms.nb_antennas_tx;aa++) { + memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + } + + if (input_fd==NULL) { + + start_meas(&PHY_vars_eNB->phy_proc_tx); + + // Simulate HARQ procedures!!! + if (common_flag == 0) { + + + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + if (transmission_mode == 3 || transmission_mode == 4) + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rvidx = round&3; + + //printf("TB0 status %d round %d \n ", TB0_active, round); + + if (round == 0) { // First round + TB0_active = 1; + TB1_active = 1; + + /* PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->rvidx = round&3; + if (transmission_mode == 3 || transmission_mode == 4) + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rvidx = round&3;*/ + + + + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); + break; + case 25: + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); + break; + case 50: + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); + break; + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); + break; + case 25: + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); + break; + case 50: + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); + break; + case 100: + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); + break; + case 25: + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); + break; + case 50: + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); + break; + case 100: + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); + break; + } + break; + + case 5: + case 6: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + } + else { // FDD + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); + break; + case 25: + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); + break; + case 50: + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); + break; + case 100: + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); + break; + case 25: + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); + break; + case 50: + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); + break; + case 100: + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); + break; + case 25: + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); + break; + case 50: + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); + break; + case 100: + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); + break; + } + break; + case 5: + case 6: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + + } + } + else { + + if (PHY_vars_eNB->lte_frame_parms.frame_type == TDD) { + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); + break; + case 25: + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); + break; + case 50: + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); + break; + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0) { // deactivate TB0 + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); + break; + case 25: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0) { // deactivate TB0 + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); + break; + case 50: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); + break; + case 100: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t)); + break; + case 25: + + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 +#ifdef DEBUG_HARQ + printf("\n[DLSIM] Requesting only TB1 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 +#ifdef DEBUG_HARQ + printf("\n[DLSIM] TDD Requesting only TB0 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t)); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2, + PHY_vars_eNB->dlsch_eNB[0], + &PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + PHY_vars_UE->dlsch_ue[0][1]->pmi_alloc + ); + break; + case 50: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t)); + break; + case 100: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t)); + break; + } + break; + + case 5: + case 6: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + } + else { + switch (transmission_mode) { + case 1: + case 2: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); + break; + case 25: + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); + break; + case 50: + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); + break; + case 100: + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); + break; + } + break; + case 3: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); + break; + case 25: + if (TB0_active==1) { + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); + break; + case 50: + if (TB0_active==1) { + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); + break; + case 100: + if (TB0_active==1) { + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB0 + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); + break; + } + break; + case 4: + switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { + case 6: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t)); + break; + case 25: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 +#ifdef DEBUG_HARQ + printf("\n [DLSIM] Requesting only TB1 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 +#ifdef DEBUG_HARQ + printf("\n[DLSIM] FDD Requesting only TB0 from temp DCI\n"); +#endif + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t)); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2, + PHY_vars_eNB->dlsch_eNB[0], + &PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + PHY_vars_UE->dlsch_ue[0][1]->pmi_alloc + ); + break; + case 50: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0) { // deactivate TB0 + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t)); + break; + case 100: + if (TB0_active == 1 && TB1_active == 1) { + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = 2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else if (TB0_active == 0){ // deactivate TB0 + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } + else { // deactivate TB1 + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi = tpmi_retr; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 1; + } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t)); + break; + } + break; + + + case 5: + case 6: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; + } + } + } + } + num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci, + num_common_dci, + dci_alloc, + 0, + AMP, + &PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + subframe); + + if (num_pdcch_symbols_2 > num_pdcch_symbols) { + msg("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols); + exit(-1); + } + + for (k=0;klte_frame_parms, + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0,subframe); + #ifdef TBS_FIX // This is for MESH operation!!! + tbs[TB] = (double)3*TBStable[get_I_TBS(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs)][PHY_vars_eNB->dlsch_eNB[k][TB]->nb_rb-1]/4; + #else + tbs[TB] = PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->TBS; + #endif + + rate[TB] = (double)tbs[TB]/(double)coded_bits_per_codeword[TB]; + + if ((SNR == snr0) && (trials == 0) && (round == 0) && (pmi_feedback == 0)) + printf("User %d, TB %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", + k,TB,rate[TB],rate[TB]*get_Qm(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs), + coded_bits_per_codeword[TB], + tbs[TB], + get_Qm(PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->mcs), + num_pdcch_symbols, + PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->round); + + // use the PMI from previous trial + if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + PHY_vars_UE->dlsch_ue[0][0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + if (n_users>1) + PHY_vars_eNB->dlsch_eNB[1][0]->harq_processes[0]->pmi_alloc = (PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); + /* + if ((trials<10) && (round==0)) { + printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[0][0]->pmi_alloc),pmi_feedback); + if (transmission_mode ==5) + printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(PHY_vars_eNB->dlsch_eNB[1][0]->pmi_alloc)); + } + */ + } + + //if standard case when both TBs are active + if (transmission_mode == 4) { + if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) && TB0_active == 1 && TB1_active == 1){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + else if (updated_csi == 0){ + + if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am calling from the eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + } else if (updated_csi == 1){ + + if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] Updating CSI\n"); + printf ("[DLSIM] I quantize from ENodeB 1\n"); +#endif + + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,5,PHY_vars_eNB->lte_frame_parms.N_RB_DL); + +#ifdef DEBUG_HARQ + printf ("[DLSIM] I quantize from ENodeB 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,5,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ +#ifdef DEBUG_HARQ + printf ("[DLSIM] Updating CSI\n"); + printf ("[DLSIM] I quantize from ENodeB 1\n"); +#endif + + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 1\n"); +#endif + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->pmi_alloc,6,PHY_vars_eNB->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I quantize from ENodeB 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = quantize_subband_pmi(&PHY_vars_UE->PHY_measurements,0,PHY_vars_UE->lte_frame_parms.N_RB_DL); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); +#endif + PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(PHY_vars_UE->dlsch_ue[0][TB]->pmi_alloc,6,PHY_vars_UE->lte_frame_parms.N_RB_DL); + } + + } + } + + start_meas(&PHY_vars_eNB->dlsch_encoding_stats); + if (dlsch_encoding(((TB==0) ? input_buffer0[k] : input_buffer1[k]), + &PHY_vars_eNB->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_eNB->dlsch_eNB[k][TB], + 0,subframe, + &PHY_vars_eNB->dlsch_rate_matching_stats, + &PHY_vars_eNB->dlsch_turbo_encoding_stats, + &PHY_vars_eNB->dlsch_interleaving_stats)<0) + exit(-1); + + stop_meas(&PHY_vars_eNB->dlsch_encoding_stats); + + PHY_vars_eNB->dlsch_eNB[k][TB]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; + start_meas(&PHY_vars_eNB->dlsch_scrambling_stats); + dlsch_scrambling(&PHY_vars_eNB->lte_frame_parms, + 0, + PHY_vars_eNB->dlsch_eNB[k][TB], + coded_bits_per_codeword[TB], + TB, + subframe<<1); + stop_meas(&PHY_vars_eNB->dlsch_scrambling_stats); + + if (n_frames==2) { + for (s=0;sdlsch_eNB[k][TB]->harq_processes[0]->C;s++) { + if (sdlsch_eNB[k][TB]->harq_processes[0]->Cminus) + Kr = PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_eNB->dlsch_eNB[k][TB]->harq_processes[0]->Kplus; + Kr_bytes = Kr>>3; + } + } + } + + start_meas(&PHY_vars_eNB->dlsch_modulation_stats); + re_allocated = dlsch_modulation(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + AMP, + subframe, + &PHY_vars_eNB->lte_frame_parms, + num_pdcch_symbols, + ((TB0_active == 1)? PHY_vars_eNB->dlsch_eNB[k][0]: NULL), + ((TB1_active == 1)? PHY_vars_eNB->dlsch_eNB[k][1]: NULL)); + stop_meas(&PHY_vars_eNB->dlsch_modulation_stats); + } //n_users + + + if (((transmission_mode == 3) || (transmission_mode == 4)) && (SNR == snr0) && (trials == 0) && (round == 0)){ + rate0_init = rate[0]; + rate1_init = rate[1]; + tbs0_init=tbs[0]; + tbs1_init=tbs[1]; + mod_order0_init=get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs); + mod_order1_init=get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs); + mcs0_init=PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs; + mcs1_init=PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs; + } + + generate_pilots(PHY_vars_eNB, + PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + AMP, + LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + + start_meas(&PHY_vars_eNB->ofdm_mod_stats); + + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], + (subframe*2), + &PHY_vars_eNB->lte_frame_parms); + + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], + (subframe*2)+1, + &PHY_vars_eNB->lte_frame_parms); + + stop_meas(&PHY_vars_eNB->ofdm_mod_stats); + stop_meas(&PHY_vars_eNB->phy_proc_tx); + + do_OFDM_mod_l(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id], + PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id], + (subframe*2)+2, + &PHY_vars_eNB->lte_frame_parms); + + if (n_frames==2) { + write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) + write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + } + + tx_lev = 0; + for (aa=0; aalte_frame_parms.nb_antennas_tx; aa++) { + tx_lev += signal_energy(&PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa] + [subframe*PHY_vars_eNB->lte_frame_parms.samples_per_tti], + PHY_vars_eNB->lte_frame_parms.samples_per_tti); + } + tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + + if (n_frames==2) { + write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) + write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1); + } + + tx_lev = 0; + for (aa=0; aalte_frame_parms.nb_antennas_tx; aa++) { + tx_lev += signal_energy(&PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa] + [subframe*PHY_vars_eNB->lte_frame_parms.samples_per_tti], + PHY_vars_eNB->lte_frame_parms.samples_per_tti); + } + tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + + if (n_frames==2) { + printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); + write_output("txsig0.m","txs0", &PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0][subframe* PHY_vars_eNB->lte_frame_parms.samples_per_tti], PHY_vars_eNB->lte_frame_parms.samples_per_tti,1,1); + } + } + /* + else { // Read signal from file + i=0; + while (!feof(input_fd)) { + fscanf(input_fd,"%s %s",input_val_str,input_val_str2); + + if ((i%4)==0) { + ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); + ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); + if ((i/4)<100) + printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); + } + i++; + if (i>(FRAME_LENGTH_SAMPLES)) + break; + } + printf("Read in %d samples\n",i/4); + write_output("txsig0.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1); + // write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); + tx_lev = signal_energy(&txdata[0][0], + OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); + tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + } + */ + + // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,awgn_flag); + for (i=0;i<2*frame_parms->samples_per_tti;i++) { + for (aa=0;aalte_frame_parms.nb_antennas_tx;aa++) { + if (awgn_flag == 0) { + s_re[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) + (i<<1)]); + s_im[aa][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + } + else { + if (transmission_mode==4) { + r_re[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[0][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])+((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + + r_re[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[1][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][0]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1])-((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][1]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + //printf("r_re0 = %d\n",r_re[0][i]); + //printf("r_im0 = %d\n",r_im[0][i]); + //printf("r_re1 = %d\n",r_re[1][i]); + //printf("r_im1 = %d\n",r_im[1][i]); + + } + else { + for (aarx=0;aarxlte_frame_parms.nb_antennas_rx;aarx++) { + if (aa==0) { + r_re[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] = ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + } + else { + r_re[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] += ((double)(((short *)PHY_vars_eNB->lte_eNB_common_vars.txdata[eNB_id][aa]))[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti) +(i<<1)+1]); + } + } + } + } + } + } + + // Multipath channel + if (awgn_flag == 0) { + multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, + 2*frame_parms->samples_per_tti,hold_channel); + // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); + if(abstx==1 && num_rounds>1) + if(round==0 && hold_channel==0){ + random_channel(eNB2UE[1],0); + random_channel(eNB2UE[2],0); + random_channel(eNB2UE[3],0); + } + if (PHY_vars_UE->perfect_ce==1){ + freq_channel(eNB2UE[round],PHY_vars_UE->lte_frame_parms.N_RB_DL,12*PHY_vars_UE->lte_frame_parms.N_RB_DL + 1); + // write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + // write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*PHY_vars_UE->lte_frame_parms.N_RB_DL +1,1,8); + } + } + + if(abstx){ // TODO: check the rounds here!! + if (trials==0 && round==0) { + // calculate freq domain representation to compute SINR + freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1); + // snr=pow(10.0,.1*SNR); + fprintf(csv_fd,"%f,",SNR); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; + channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + if(num_rounds>1){ + freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; + channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; + channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1); + + for (u=0;u<2*NB_RB;u++){ + for (aarx=0;aarxnb_rx;aarx++) { + for (aatx=0;aatxnb_tx;aatx++) { + channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; + channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + } + } + } + + //AWGN + // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated); + sigma2 = pow(10,sigma2_dB/10); + if (n_frames==2) + printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(PHY_vars_eNB->pdsch_config_dedicated)); + + for (i=0; i<2*frame_parms->samples_per_tti; i++) { + for (aa=0;aalte_frame_parms.nb_antennas_rx;aa++) { + //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); + ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i] = + (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[(2*subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti)+2*i+1] = + (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + } + } + + // lte_sync_time_init(PHY_vars_eNB->lte_frame_parms,lte_ue_common_vars); + // lte_sync_time(lte_ue_common_vars->rxdata, PHY_vars_eNB->lte_frame_parms); + // lte_sync_time_free(); + + /* + // optional: read rx_frame from file + if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL) + { + printf("Cannot open rx_frame.m data file\n"); + exit(0); + } + + result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); + printf("Read %d bytes\n",result); + result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file); + printf("Read %d bytes\n",result); + + fclose(rx_frame_file); + */ + + if (n_frames==2) { + printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); + printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)))); + } + + if (PHY_vars_eNB->lte_frame_parms.Ncp == 0) { // normal prefix + pilot1 = 4; + pilot2 = 7; + pilot3 = 11; + } + else { // extended prefix + pilot1 = 3; + pilot2 = 6; + pilot3 = 9; + } + + start_meas(&PHY_vars_UE->phy_proc_rx); + // Inner receiver scheduling for 3 slots + for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) { + for (l=0;lofdm_demod_stats); + slot_fep(PHY_vars_UE, + l, + Ns%20, + 0, + 0, + 0); + stop_meas(&PHY_vars_UE->ofdm_demod_stats); + + if (PHY_vars_UE->perfect_ce==1) { + if (awgn_flag==0) { + for(k=0; knb_antennas_tx; aa++) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (i=0; iN_RB_DL*12; i++) { + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= + (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]= + (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + } + } + } + } + }else { + if (transmission_mode==4) { + for (i=0; iN_RB_DL*12; i++) { + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0; + } + } else { + for(aa=0; aanb_antennas_tx; aa++) { + for (aarx=0; aarxnb_antennas_rx; aarx++) { + for (i=0; iN_RB_DL*12; i++) { + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; + } + } + } + } + } + } + + if ((Ns==((2*subframe))) && (l==0)) { +#ifdef DEBUG_HARQ + +#endif + lte_ue_measurements(PHY_vars_UE, + subframe*PHY_vars_UE->lte_frame_parms.samples_per_tti, + 1, + 0); + //printf ("Trial %d, Measurements are done \n", trials); + /* + debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n", + PHY_vars_UE->PHY_measurements.rx_rssi_dBm[0] - ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx==2) ? 3 : 0), + PHY_vars_UE->PHY_measurements.wideband_cqi_dB[0][0], + PHY_vars_UE->PHY_measurements.wideband_cqi_dB[0][1], + PHY_vars_UE->PHY_measurements.wideband_cqi[0][0], + PHY_vars_UE->PHY_measurements.wideband_cqi[0][1], + PHY_vars_UE->PHY_measurements.rx_power_avg_dB[0], + PHY_vars_UE->PHY_measurements.rx_power_avg[0], + PHY_vars_UE->rx_total_gain_dB); + debug_msg("N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n", + PHY_vars_UE->PHY_measurements.n0_power_tot_dBm, + PHY_vars_UE->PHY_measurements.n0_power_dB[0], + PHY_vars_UE->PHY_measurements.n0_power_dB[1], + PHY_vars_UE->PHY_measurements.n0_power[0], + PHY_vars_UE->PHY_measurements.n0_power[1], + PHY_vars_UE->PHY_measurements.n0_power_avg_dB, + PHY_vars_UE->PHY_measurements.n0_power_avg); + debug_msg("Wideband CQI tot %d dB, wideband cqi avg %d dB\n", + PHY_vars_UE->PHY_measurements.wideband_cqi_tot[0], + PHY_vars_UE->PHY_measurements.wideband_cqi_avg[0]); + */ + + if (transmission_mode == 4 || transmission_mode == 5 || transmission_mode == 6) { + if (pmi_feedback == 1) { + pmi_feedback = 0; + hold_channel = 1; + + if (updated_csi==0) { + if (hold_rank1_precoder == 0) + hold_rank1_precoder = 1; + } + //printf ("trial %d pmi_feedback %d \n", trials, pmi_feedback); + //printf ("go to PMI feedback\n"); +#ifdef DEBUG_HARQ + printf ("[DLSIM] I am doing measurements and coming back to reencoding\n"); +#endif + goto PMI_FEEDBACK; + } + } + + } + + + if ((Ns==(2*subframe)) && (l==pilot1)) {// process symbols 0,1,2 + if (dci_flag == 1) { + PHY_vars_UE->UE_mode[0] = PUSCH; + start_meas(&PHY_vars_UE->dlsch_rx_pdcch_stats); + + rx_pdcch(&PHY_vars_UE->lte_ue_common_vars, + PHY_vars_UE->lte_ue_pdcch_vars, + &PHY_vars_UE->lte_frame_parms, + subframe, + 0, + (PHY_vars_UE->lte_frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI, + PHY_vars_UE->high_speed_flag, + 0); + + stop_meas(&PHY_vars_UE->dlsch_rx_pdcch_stats); + // overwrite number of pdcch symbols + PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; + + dci_cnt = dci_decoding_procedure(PHY_vars_UE, + dci_alloc_rx,1, + eNB_id, + subframe); + printf("dci_cnt %d\n",dci_cnt); + + if (dci_cnt==0) { + dlsch_active = 0; + if (round==0) { + dci_errors++; + round=5; // this is meant to stop the "while" loop if DCI is wrong; + errs[0][0]++; + + if (n_frames==2) + printf("DCI error trial %d errs[0][0] %d\n",trials,errs[0][0]); + } + } + + for (i=0;idlsch_ue[0][0]->harq_processes[0]->first_tx=1; + } + if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) { + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->first_tx=1; + } + if ((dci_alloc_rx[i].rnti == n_rnti) && + (generate_ue_dlsch_params_from_dci(0, + subframe, + dci_alloc_rx[i].dci_pdu, + dci_alloc_rx[i].rnti, + dci_alloc_rx[i].format, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI)==0)) { + dump_dci(&PHY_vars_UE->lte_frame_parms,&dci_alloc_rx[i]); + coded_bits_per_codeword[0]= get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl, + PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols, + 0, + subframe); + if (transmission_mode == 3 || transmission_mode == 4) { + coded_bits_per_codeword[1]= get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl, + PHY_vars_UE->lte_ue_pdcch_vars[1]->num_pdcch_symbols, + 0, + subframe); + } + /* + rate = (double)dlsch_tbs25[get_I_TBS(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs)][PHY_vars_UE->dlsch_ue[0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs); + */ + printf("num_pdcch_symbols %d, G %d, TBS %d\n",PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword [0],PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->TBS); + + dlsch_active = 1; // what does it indicates??? + } else { + dlsch_active = 0; + if (round==0) { + dci_errors++; + errs[0][0]++; + round=5; + + if (n_frames==2) + printf("DCI misdetection trial %d\n",trials); + + } + } + } + } else { //dci_flag == 0 + PHY_vars_UE->lte_ue_pdcch_vars[0]->crnti = n_rnti; + PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; + if (round == 0) { + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx=1; + } + if (round == 0) { + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->first_tx=1; + } + + switch (transmission_mode) { + case 1: + case 2: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format1 : format1A, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); + break; + case 3: + //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx); + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format2A : format1A, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); + //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx); + break; + case 4: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format2 : format1A,//format1A only for a codeblock + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); + + break; + case 5: + case 6: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu2_1E[0], + C_RNTI, + format1E_2A_M10PRB, + PHY_vars_UE->dlsch_ue[0], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI); + break; + } + dlsch_active = 1; + } // if dci_flag == 1 + } + + if (dlsch_active == 1) { + if (TB0_active==1) + cur_harq_pid =PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid; + else + cur_harq_pid =PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid; + + if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix + if (transmission_mode == 5) { + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && + (openair_daq_vars.use_ia_receiver ==1)) { + rx_type = rx_IC_single_stream; + } else { + rx_type = rx_standard; + } + } + + + start_meas(&PHY_vars_UE->dlsch_llr_stats); + + for (m=PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols; mlte_ue_pdcch_vars[0]->num_pdcch_symbols)?1:0, + rx_type, + i_mod, + cur_harq_pid)==-1){ + dlsch_active = 0; + break; + } + } + stop_meas(&PHY_vars_UE->dlsch_llr_stats); + } + + if ((Ns==(1+(2*subframe))) && (l==pilot1)){// process symbols (6 Extended Prefix),7,8,9 + start_meas(&PHY_vars_UE->dlsch_llr_stats); + for (m=pilot2;mdlsch_llr_stats); + } + + if ((Ns==(2+(2*subframe))) && (l==0)) { // process symbols 10,11,(12,13 Normal Prefix) do deinterleaving for TTI + start_meas(&PHY_vars_UE->dlsch_llr_stats); + for (m=pilot3; mlte_frame_parms.symbols_per_tti; m++) { + if (rx_pdsch(PHY_vars_UE, + PDSCH, + eNB_id, + eNB_id_i, + subframe, + m, + 0, + rx_type, + i_mod, + cur_harq_pid)==-1) { + dlsch_active=0; + break; + } + } + stop_meas(&PHY_vars_UE->dlsch_llr_stats); + } + } + } + } + + //saving PMI in case of Transmission Mode > 5 + + if(abstx){ + if (trials==0 && round==0 && transmission_mode>=4){ + for (iii=0; iiilte_ue_pdsch_vars[eNB_id]->pmi_ext[iii]),(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id_i]->pmi_ext[iii])); + fprintf(csv_fd,"%x,",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + //printf("%x ",(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->pmi_ext[iii])); + } + } + } + + /*if (rx_type==rx_SIC_dual_stream){ + cw_to_decode_interf=1; + cw_to_decode_interf_free=1; + } + else { + cw_to_decode_interf=Kmimo; + }*/ + + for (TB=0; TBdlsch_ue[0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword[TB] = get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0,subframe); + + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs); + + if (n_frames==2) { + printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->TBS); + + // calculate uncoded BER + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]); + + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); + sprintf(fname,"dlsch_cw%d_e.m", TB); + sprintf(vname,"dlschcw%d_e", TB); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4); + uncoded_ber=0; + printf("trials=%d\n", trials); + + for (i=0;idlsch_eNB[0][TB]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } + else + uncoded_ber_bit[i] = 0; + + uncoded_ber/=coded_bits_per_codeword[TB]; + avg_ber += uncoded_ber; + sprintf(fname,"cw%d_uncoded_ber_bit.m", TB); + sprintf(vname,"uncoded_ber_bit_cw%d", TB); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[TB],1,0); + printf("cw %d, uncoded ber %f\n",TB,uncoded_ber); + + + free(uncoded_ber_bit); + uncoded_ber_bit = NULL; + + } + + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_ue[0][TB], + coded_bits_per_codeword[TB], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword], + TB, + subframe<<1); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + + start_meas(&PHY_vars_UE->dlsch_decoding_stats); + ret[TB] = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid]->codeword], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][TB], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][TB]->current_harq_pid, + 1,llr8_flag); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); +#ifdef DEBUG_HARQ + printf("[DLSIM] ret[%d] = %d\n", TB, ret[TB]); +#endif + + //printf("retr cw 0 = %d\n", ret[0]); + //printf("current round = %d\n", PHY_vars_UE->dlsch_ue[0][cw_non_sic]->harq_processes[PHY_vars_UE->dlsch_ue[0][cw_non_sic]->current_harq_pid]->round); + + + + if (ret[TB] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 +#ifdef DEBUG_HARQ + printf("[DLSIM] TB%d is decoded\n", TB); +#endif + + /*avg_iter[TB] += ret[TB]; + iter_trials[TB]++;*/ + + if (n_frames==2) { + printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][TB]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][TB]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][TB]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->c[s][i]); + } +#endif + } + + PHY_vars_UE->total_TBS[eNB_id] = PHY_vars_UE->total_TBS[eNB_id] + PHY_vars_UE->dlsch_ue[eNB_id][TB]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][TB]->current_harq_pid]->TBS; + + // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER + //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) + if (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + /* + //for (round = 0 ; round < PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round ; round++) { + // we assume here that the second stream has a lower MCS and is thus more likely to be decoded + // re-encoding of second stream + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq->mimo_mode = LARGE_CDD; + dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; + dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; + dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; + dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; + dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; + dlsch0_eNB_harq->round = dlsch0_ue_harq->round; + + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; + dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; + dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; + + dlsch_encoding(PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0,subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats + ); + + coded_bits_per_codeword = get_G(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0,subframe); + + + //scrambling + dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword, + 0, + subframe<<1); + + + //modulation + re_allocated = dlsch_modulation(sic_buffer, + AMP, + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL); + // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding + // precoding is contained in effective channel estimate + // compute the norm of the effective channel for both receive antennas -> alphha[0], alphha[2] + // multiply with the norm of the effective channnel + */ + + //stripping (from matched filter output of first stream = rxdataF_comp0) + // this is pseudocode + /* + for (i=0; inb_antennas_rx; i++) { + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext[i] -= alpha[i].*sic_buffer[i]; + } + */ + + //apply rho to output + /* + dlsch_channel_compensation(PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].rxdataF_ext, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id].dl_ch_rho_ext[harq_pid][round], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1, + NULL, + frame_parms, + symbol, + first_symbol_flag, + i_mod, + nb_rb, + lte_ue_pdsch_vars[eNB_id]->log2_maxh, + phy_measurements); // log2_maxh+I0_shift + */ + + + //detection of second stream + //} + + } + + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && + (rx_type==rx_SIC_dual_stream)) { +#ifdef DEBUG_HARQ + printf("[DLSIM] Starting SIC procedure\n"); +#endif + // printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round); + + + //printf("\n CW 0 is decoded, i go for , round %d\n", round); + //printf("\n ret[TB0] = %d round %d\n", ret[TB], round); + sic_attempt[round]++; + + for (round_sic = 0 ; round_sic < (round +1); round_sic++) { + +#ifdef DEBUG_HARQ + printf("[DLSIM] 0 Round sic = %d\n", round_sic); +#endif + //printf("I enter round_sic loop \n"); + //printf("round_sic= %d\n", round_sic); + dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]; + dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]; + + dlsch0_eNB_harq->mimo_mode = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode; + dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; + dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; + dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; + dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx; + dlsch0_eNB_harq->Nl = dlsch0_ue_harq->Nl; + dlsch0_eNB_harq->round = dlsch0_ue_harq->round; + dlsch0_eNB_harq->TBS = dlsch0_ue_harq->TBS; + dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; + dlsch0_eNB_harq->status = dlsch0_ue_harq->status; + if (round_sic == 0){ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 0; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=0; + } + else if (round_sic == 1){ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 1; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=1; + } + else if (round_sic == 2){ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 2; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=2; + } + else{ + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][1]->current_harq_pid]->rvidx = 3; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->rvidx=3; + } + + PHY_vars_UE->dlsch_eNB[eNB_id]->active = PHY_vars_UE->dlsch_ue[eNB_id][0]->active; + PHY_vars_UE->dlsch_eNB[eNB_id]->rnti = PHY_vars_UE->dlsch_ue[eNB_id][0]->rnti; + PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid = PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid; + + dlsch_encoding(input_buffer0[0], //PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + PHY_vars_UE->dlsch_eNB[eNB_id], + 0, + subframe, + &PHY_vars_UE->dlsch_rate_matching_stats, + &PHY_vars_UE->dlsch_turbo_encoding_stats, + &PHY_vars_UE->dlsch_interleaving_stats); + + + coded_bits_per_codeword[0]= get_G(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->nb_rb, + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->mcs), + PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_eNB[eNB_id]->current_harq_pid]->Nl, + num_pdcch_symbols, + 0, + subframe); + + dlsch_scrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_eNB[eNB_id], + coded_bits_per_codeword[0], + 0, + subframe<<1); + + re_allocated = dlsch_modulation_SIC(sic_buffer, + subframe, + &PHY_vars_UE->lte_frame_parms, + num_pdcch_symbols, + &PHY_vars_UE->dlsch_eNB[0][0], + NULL, + coded_bits_per_codeword[0]); + + // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); + // write_output("rxdataF_comp1.m","rxF_comp1", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_rho.m","rho", *PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round],14*12*25,1,1); + + switch (get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)){ + + + case 2: + + dlsch_qpsk_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + num_pdcch_symbols, + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + + case 4: + + dlsch_16qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][0]); + break; + case 6: + dlsch_64qam_llr_SIC(&PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->rxdataF_comp1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + sic_buffer, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + num_pdcch_symbols, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_mag1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->dl_ch_magb1[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid][round_sic], + dlsch0_eNB_harq->nb_rb, + subframe, + dlsch0_eNB_harq->rb_alloc[0], + get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs), + PHY_vars_UE->dlsch_ue[eNB_id][TB]); + break; + } + //}// rouns sic +#ifdef DEBUG_HARQ + printf("[DLSIM] TB1 is mapped into CW%d\n", PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword); +#endif + + // write_output("rxdata_llr1.m","llr1", PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); + + // replace cw_sic with TB+1 + PHY_vars_UE->dlsch_ue[0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + coded_bits_per_codeword[1]= get_G(&PHY_vars_eNB->lte_frame_parms, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->nb_rb, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->rb_alloc, + get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs), + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe); + + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->Qm = get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs); + + if (n_frames==2) { + printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->TBS); + + // calculate uncoded BER + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]); + AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL"); + sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round,1); + sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, 1); + write_output(fname,vname, PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[1],coded_bits_per_codeword[1],1,0); + sprintf(fname,"dlsch_cw%d_e.m", 1); + sprintf(vname,"dlschcw%d_e", 1); + write_output(fname, vname,PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->e,coded_bits_per_codeword[1],1,4); + uncoded_ber=0; + printf("trials=%d\n", trials); + for (i=0;idlsch_eNB[0][1]->harq_processes[0]->e[i] != (PHY_vars_UE->lte_ue_pdsch_vars[0]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword][i]<0)) { + uncoded_ber_bit[i] = 1; + uncoded_ber++; + } + else + uncoded_ber_bit[i] = 0; + + uncoded_ber/=coded_bits_per_codeword[1]; + avg_ber += uncoded_ber; + sprintf(fname,"cw%d_uncoded_ber_bit.m", 1); + sprintf(vname,"uncoded_ber_bit_cw%d", 1); + write_output(fname, vname,uncoded_ber_bit,coded_bits_per_codeword[1],1,0); + printf("cw %d, uncoded ber %f\n",1,uncoded_ber); + free(uncoded_ber_bit); + uncoded_ber_bit = NULL; + } + + start_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms, + 0, + PHY_vars_UE->dlsch_ue[0][1], + coded_bits_per_codeword[1], + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + 1, + subframe<<1); + stop_meas(&PHY_vars_UE->dlsch_unscrambling_stats); + + start_meas(&PHY_vars_UE->dlsch_decoding_stats); + + ret[1] = dlsch_decoding(PHY_vars_UE, + PHY_vars_UE->lte_ue_pdsch_vars[eNB_id]->llr[PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid]->codeword], + &PHY_vars_UE->lte_frame_parms, + PHY_vars_UE->dlsch_ue[0][1], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid], + subframe, + PHY_vars_UE->dlsch_ue[0][1]->current_harq_pid, + 1,llr8_flag); + stop_meas(&PHY_vars_UE->dlsch_decoding_stats); + +#ifdef DEBUG_HARQ + printf("[DLSIM] Decoding TB1 in SIC: ret[1] = %d, round sic %d\n", ret[1], round_sic); +#endif + + //printf("ret TB 1 = %d round %d \n", ret[1], round); + + if (ret[1] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ) { + decoded_in_sic[round]++; + round_sic = round+1; // to exit round_sic +#ifdef DEBUG_HARQ + printf("[DLSIM] TB1 is decoded in SIC loop\n"); +#endif + avg_iter[1] += ret[1]; + iter_trials[1]++; + + + if (n_frames==2) { + printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); + + #ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][1]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][1]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + + for (i=0;idlsch_ue[0][1]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->c[s][i]); + } + #endif + } + } + } //round_sic + + + if (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations ){ + errs[1][round]++; +#ifdef DEBUG_HARQ + printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]); +#endif + + // exit(0); + + avg_iter[1] += ret[1]-1; + iter_trials[1]++; + + if (n_frames==2) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][1]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][1]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][1]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][1]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->c[s][i]); + } +#endif + } //n_frames==1 + // exit(0); + } //if (ret > PHY_vars_UE->dlsch_ue[0][1]->max_turbo_iterations ) + }//if SIC + } else { + + errs[TB][round]++; +#ifdef DEBUG_HARQ + printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", TB, TB, round, errs[TB][round]); +#endif + + + /*if (cw_non_sic==0) { + avg_iter[0] += ret[0]-1; + iter_trials[0]++; + }*/ + + if ((PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) { + errs[1][round]++; +#ifdef DEBUG_HARQ + printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", 1, 1, round, errs[1][round]); +#endif + } + + + /*if (cw_non_sic==1) { + avg_iter[1] += ret[1]-1; + iter_trials[1]++; + }*/ + + + if (n_frames==2) { + //if ((n_frames==1) || (SNR>=30)) { + printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); +#ifdef PRINT_BYTES + for (s=0;sdlsch_ue[0][TB]->harq_processes[0]->C;s++) { + if (sdlsch_ue[0][TB]->harq_processes[0]->Cminus) + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kminus; + else + Kr = PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->Kplus; + + Kr_bytes = Kr>>3; + + printf("Decoded_output (Segment %d):\n",s); + for (i=0;idlsch_ue[0][TB]->harq_processes[0]->c[s][i], + PHY_vars_UE->dlsch_ue[0][TB]->harq_processes[0]->c[s][i]^PHY_vars_eNB->dlsch_eNB[0][TB]->harq_processes[0]->c[s][i]); + } +#endif + } + } + if (rx_type==rx_SIC_dual_stream) + TB++; // to terminate the loop over TB + } + + stop_meas(&PHY_vars_UE->phy_proc_rx); + + if (n_frames==2) { + + //rxsig + sprintf(fname,"rxsig0_r%d.m",round); + sprintf(vname,"rxs0_r%d",round); + write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdata[0][0],10*PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsigF0_r%d.m",round); + sprintf(vname,"rxs0F_r%d",round); + write_output(fname,vname, &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); + if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { + sprintf(fname,"rxsig1_r%d.m",round); + sprintf(vname,"rxs1_r%d",round); + write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdata[1],PHY_vars_UE->lte_frame_parms.samples_per_tti,1,1); + sprintf(fname,"rxsig1F_r%d.m",round); + sprintf(vname,"rxs1F_r%d",round); + write_output(fname,vname, PHY_vars_UE->lte_ue_common_vars.rxdataF[1],2*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,2,1); + } + + //channel + write_output("chanF11.m","chF11",eNB2UE[0]->chF[0],12*NB_RB,1,8); + write_output("chan11.m","ch11",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx==2 && PHY_vars_eNB->lte_frame_parms.nb_antennas_tx==1 ){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + } + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1){ + write_output("chan12.m","ch12",eNB2UE[0]->ch[1],eNB2UE[0]->channel_length,1,8); + if ( PHY_vars_eNB->lte_frame_parms.nb_antennas_rx>1){ + write_output("chan21.m","ch21",eNB2UE[0]->ch[2],eNB2UE[0]->channel_length,1,8); + write_output("chan22.m","ch22",eNB2UE[0]->ch[3],eNB2UE[0]->channel_length,1,8); + } + } + + //channel estimates + sprintf(fname,"dlsch00_r%d.m",round); + sprintf(vname,"dl00_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][0][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + if (PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) { + sprintf(fname,"dlsch01_r%d.m",round); + sprintf(vname,"dl01_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][1][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + } + if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) { + sprintf(fname,"dlsch10_r%d.m",round); + sprintf(vname,"dl10_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][2][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + } + if ((PHY_vars_UE->lte_frame_parms.nb_antennas_rx>1) && (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)) { + sprintf(fname,"dlsch11_r%d.m",round); + sprintf(vname,"dl11_r%d",round); + write_output(fname,vname, + &(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[eNB_id][3][0]), + PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1); + } + //pdsch_vars + dump_dlsch2(PHY_vars_UE,eNB_id,coded_bits_per_codeword[0],round,PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid); + /* + write_output("dlsch_e.m","e",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); + write_output("dlsch_eNB_w.m","w",PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); + write_output("dlsch_UE_w.m","w",PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + */ + + //pdcch_vars + write_output("pdcchF0_ext.m","pdcchF_ext", PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*PHY_vars_UE->lte_frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",PHY_vars_UE->lte_ue_pdcch_vars[eNB_id]->llr,2400,1,4); + + + if (round == 3) exit(-1); + } + + if (xforms==1) { + phy_scope_UE(form_ue, + PHY_vars_UE, + eNB_id, + 0,// UE_id + subframe); + } +#ifdef DEBUG_HARQ + printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]); +#endif + + if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations)){ + //printf("flag 1 \n"); + round++; + } + + + if (transmission_mode == 3 || transmission_mode == 4 ) { + if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations && + ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + resend_both[round]++; + round++; + resend_cw0_cw1=1; //resend both cws + resend_cw1=0; + TB0_active=1; + TB1_active=1; + } + else if (ret[1] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations && + ret[0] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + resend_one[round]++; + resend_cw0_cw1=0; + TB0_active=0; + TB1_active=1; + if (rx_type == rx_IC_dual_stream) + TB0_deact[round]++; + if(is_first_time) { + hold_rank1_precoder = 0; + is_first_time = false; + } + else + hold_rank1_precoder = 1; + +#ifdef DEBUG_HARQ + printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials); + printf("[DLSIM] TB0 deactivated\n"); +#endif + round++; + } + else if (ret[0] > PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations && + ret[1] <= PHY_vars_UE->dlsch_ue[0][0]->max_turbo_iterations){ + resend_one[round]++; + resend_cw0_cw1=0; + TB0_active=1; + TB1_active=0; + if (rx_type == rx_IC_dual_stream) + TB1_deact[round]++; + if(is_first_time) { + hold_rank1_precoder = 0; + is_first_time = false; + } + else + hold_rank1_precoder = 1; + +#ifdef DEBUG_HARQ + printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials); + printf("[DLSIM] TB1 deactivated\n"); +#endif + round++; + } + } + +#ifdef DEBUG_HARQ + printf("[DLSIM] Now round is %d, trial %d\n" , round, trials); +#endif + } + + + if(transmission_mode != 3 && transmission_mode !=4 ){ + if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) ) + break; + } + + //len = chbch_stats_read(stats_buffer,NULL,0,4096); + //printf("%s\n\n",stats_buffer); + + if (PHY_vars_UE->frame_rx % 10 == 0) { + PHY_vars_UE->bitrate[eNB_id] = (PHY_vars_UE->total_TBS[eNB_id] - PHY_vars_UE->total_TBS_last[eNB_id])*10; + LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",PHY_vars_UE->Mod_id,PHY_vars_UE->total_TBS[eNB_id],PHY_vars_UE->total_TBS_last[eNB_id],PHY_vars_UE->bitrate[eNB_id]/1000); + PHY_vars_UE->total_TBS_last[eNB_id] = PHY_vars_UE->total_TBS[eNB_id]; + } + + + PHY_vars_UE->frame_rx++; + + /* calculate the total processing time for each packet, + * get the max, min, and number of packets that exceed t>2000us + */ + double t_tx = (double)PHY_vars_eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; + double t_tx_ifft = (double)PHY_vars_eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_mod = (double)PHY_vars_eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx_enc = (double)PHY_vars_eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; + + + double t_rx = (double)PHY_vars_UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)PHY_vars_UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_demod = (double)PHY_vars_UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_dec = (double)PHY_vars_UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + + if (t_tx > t_tx_max) + t_tx_max = t_tx; + if (t_tx < t_tx_min) + t_tx_min = t_tx; + if (t_rx > t_rx_max) + t_rx_max = t_rx; + if (t_rx < t_rx_min) + t_rx_min = t_rx; + if (t_tx > 2000) + n_tx_dropped++; + if (t_rx > 2000) + n_rx_dropped++; + + + push_front(&time_vector_tx, t_tx); + push_front(&time_vector_tx_ifft, t_tx_ifft); + push_front(&time_vector_tx_mod, t_tx_mod); + push_front(&time_vector_tx_enc, t_tx_enc); + + push_front(&time_vector_rx, t_rx); + push_front(&time_vector_rx_fft, t_rx_fft); + push_front(&time_vector_rx_demod, t_rx_demod); + push_front(&time_vector_rx_dec, t_rx_dec); + + + } //trials +#ifdef DEBUG_HARQ + printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]); + printf(" only one failed round 0 = %d, only one failed round 1 = %d, only one failed round 2 = %d, only one failed round 3 = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]); + if (rx_type == rx_SIC_dual_stream){ + printf(" sic attempt round 0 = %d, sic attempt round 1 = %d, sic attempt round 2 = %d, sic attempt round 3 = %d\n", sic_attempt[0], sic_attempt[1], sic_attempt[2], sic_attempt[3]); + printf(" decoded in sic round 0 = %d, decoded in sic round 1 = %d, decoded in sic round 2 = %d, decoded in sic round 3 = %d\n", decoded_in_sic[0], decoded_in_sic[1], decoded_in_sic[2], decoded_in_sic[3]); + } + else if (rx_type == rx_IC_dual_stream){ + printf(" TB0 deactiv round 0 = %d, TB0 deactiv round 1 = %d, TB0 deactiv round 2 = %d, TB0 deactiv round 3 = %d\n", TB0_deact[0], TB0_deact[1], TB0_deact[2], TB0_deact[3]); + printf(" TB1 deactiv round 0 = %d, TB1 deactiv round 1 = %d, TB1 deactiv round 2 = %d, TB1 deactiv round 3 = %d\n", TB1_deact[0], TB1_deact[1], TB1_deact[2], TB1_deact[3]); + } +#endif + // round_trials[0]: number of code word : goodput the protocol + double table_tx[time_vector_tx.size]; + totable(table_tx, &time_vector_tx); + double table_tx_ifft[time_vector_tx_ifft.size]; + totable(table_tx_ifft, &time_vector_tx_ifft); + double table_tx_mod[time_vector_tx_mod.size]; + totable(table_tx_mod, &time_vector_tx_mod); + double table_tx_enc[time_vector_tx_enc.size]; + totable(table_tx_enc, &time_vector_tx_enc); + + double table_rx[time_vector_rx.size]; + totable(table_rx, &time_vector_rx); + double table_rx_fft[time_vector_rx_fft.size]; + totable(table_rx_fft, &time_vector_rx_fft); + double table_rx_demod[time_vector_rx_demod.size]; + totable(table_rx_demod, &time_vector_rx_demod); + double table_rx_dec[time_vector_rx_dec.size]; + totable(table_rx_dec, &time_vector_rx_dec); + + + // sort table + qsort (table_tx, time_vector_tx.size, sizeof(double), &compare); + qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); + + if (dump_table == 1 ) { + set_component_filelog(USIM); // file located in /tmp/usim.txt + int n; + LOG_F(USIM,"The transmitter raw data: \n"); + + for (n=0; n< time_vector_tx.size; n++) { + printf("%f ", table_tx[n]); + LOG_F(USIM,"%f ", table_tx[n]); + } + + LOG_F(USIM,"\n"); + LOG_F(USIM,"The receiver raw data: \n"); + + for (n=0; n< time_vector_rx.size; n++) { + // printf("%f ", table_rx[n]); + LOG_F(USIM,"%f ", table_rx[n]); + } + + LOG_F(USIM,"\n"); + } + + double tx_median = table_tx[time_vector_tx.size/2]; + double tx_q1 = table_tx[time_vector_tx.size/4]; + double tx_q3 = table_tx[3*time_vector_tx.size/4]; + + double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2]; + double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4]; + double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4]; + + double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2]; + double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4]; + double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4]; + + double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2]; + double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4]; + double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4]; + + double rx_median = table_rx[time_vector_rx.size/2]; + double rx_q1 = table_rx[time_vector_rx.size/4]; + double rx_q3 = table_rx[3*time_vector_rx.size/4]; + + double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2]; + double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4]; + double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4]; + + double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2]; + double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4]; + double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4]; + + double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2]; + double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4]; + double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4]; + + double std_phy_proc_tx=0; + double std_phy_proc_tx_ifft=0; + double std_phy_proc_tx_mod=0; + double std_phy_proc_tx_enc=0; + + double std_phy_proc_rx=0; + double std_phy_proc_rx_fft=0; + double std_phy_proc_rx_demod=0; + double std_phy_proc_rx_dec=0; + + if (transmission_mode != 3 && transmission_mode !=4) { + effective_rate = ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3])); + } + else { + effective_rate = ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3]))+ + ((double)(round_trials[1][0])/((double)round_trials[1][0] + round_trials[1][1] + round_trials[1][2] + round_trials[1][3])); + } + + /* + Here we compute throughput per cw based on the formula + T=P_suc[r1]R(mcs) + sum[r=2 ..r=4] (P_(suc r, fail r-1)*R/r). + The non-constr formula should not be used, when there are some errors on the last round, + meaning when not all the packages are finally decoded. + */ + + if (transmission_mode == 3 || transmission_mode == 4) { + // FOR CW0 + thr_cw0[0] = rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])); + thr_cw0[1] = (rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/2)*(((double)errs[0][0] - (double)errs[0][1])/(double)round_trials[0][0]); + thr_cw0[2] = (rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/3)*(((double)errs[0][1] - (double)errs[0][2])/(double)round_trials[0][0]); + thr_cw0[3] = (rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/4)*(((double)errs[0][2] - (double)errs[0][3])/(double)round_trials[0][0]); + thr_cw0_tot = (double)thr_cw0[0]+(double)thr_cw0[1]+(double)thr_cw0[2]+(double)thr_cw0[3]; +#ifdef PRINT_THROUGHPUT + printf("rate %f \n", rate0_init); + printf("rate*mod_order %f \n", rate0_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)); + printf("Probability %f \n", (1-((double)errs[0][0]/(double)round_trials[0][0]))); + printf("Throughput cw0 sum = %f \n", thr_cw0_tot); + printf("Throughput cw0 round 0 = %f \n", thr_cw0[0]); + printf("Throughput cw0 round 1 = %f \n", thr_cw0[1]); + printf("Throughput cw0 round 2 = %f \n", thr_cw0[2]); + printf("Throughput cw0 round 3 = %f \n", thr_cw0[3]); + printf("round_trials = %d, errs[0][0] = %d, round_trials[0][1] = %d, errs[0][1] = %d, round_trials[0][2] = %d, errs[0][2] = %d, \ + round_trials[0][3] = %d, errs[0][3] = %d \n", round_trials[0][0], errs[0][0],round_trials[0][1], errs[0][1], round_trials[0][2], \ + errs[0][2], round_trials[0][3], errs[0][3]); +#endif + + thr_cw1[0] = rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])); + thr_cw1[1] = (rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]); + thr_cw1[2] = (rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/3)*(((double)errs[1][1] - (double)errs[1][2])/(double)round_trials[1][0]); + thr_cw1[3] = (rate1_init*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/4)*(((double)errs[1][2] - (double)errs[1][3])/(double)round_trials[1][0]); + thr_cw1_tot = (double)thr_cw1[0]+(double)thr_cw1[1]+(double)thr_cw1[2]+(double)thr_cw1[3]; +#ifdef PRINT_THROUGHPUT + printf("Throughput cw1 sum = %f \n", thr_cw1_tot); + printf("Throughput cw1 round 0 = %f \n", thr_cw1[0]); + printf("Throughput cw1 round 1 = %f \n", thr_cw1[1]); + printf("Throughput cw1 round 2 = %f \n", thr_cw1[2]); + printf("Throughput cw1 round 3 = %f \n", thr_cw1[3]); + printf("round_trials[1][0] = %d, errs[1][0] = %d, round_trials[1][1] = %d, errs[1][1] = %d, round_trials[1][2] = %d, errs[1][2] = %d, \ + round_trials[1][3] = %d, errs[1][3] = %d \n", round_trials[1][0], errs[1][0], round_trials[1][1], errs[1][1], round_trials[1][2], \ + errs[1][2], round_trials[1][3], errs[1][3]); +#endif + } + +#if 0 + thr_cw0_tm4_nonconst = rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)* \ + ((double)(round_trials[0][0]-dci_errors)/((double)round_trials[0][0] + round_trials[0][1] + round_trials[0][2] + round_trials[0][3])); + printf("Throughput cw0 noncnstr = %f \n", thr_cw0_tm4_nonconst); +#endif + //FOR CW1 + /*thr_cw1[0] = rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])) \ + *(1-((double)errs[1][0]/(double)round_trials[1][0])); + printf("thr cw1 round 0 = %f\n", thr_cw1[0]); + thr_cw1[1]=(rate[1]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->mcs)/2)*\ + (((double)errs[1][0]-(double)errs[1][1])*((double)round_trials[0][0] - (double)errs[0][1])/((double)round_trials[0][0]*(double)round_trials[1][0])); + printf("thr cw1 round 1 = %f\n", thr_cw1[1]); + thr_cw1[2] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/3)*\ + ((double)errs[1][1]-(double)errs[1][2])*((double)round_trials[0][0]-(double)errs[0][2])/((double)round_trials[0][0]*(double)round_trials[1][0]); + printf("thr cw1 round 2 = %f\n", thr_cw1[2]); + thr_cw1[3] = (rate[0]*get_Qm(PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->mcs)/4)*\ + ((double)errs[1][2]-(double)errs[1][3])*((double)round_trials[0][0] - (double)errs[0][3])/((double)round_trials[0][0]*(double)round_trials[1][0]); + resid_errs= + printf("thr cw1 round 3 = %f\n", thr_cw1[3]); + thr_cw1_tot =thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+thr_cw1[3]; + printf("Throughput cw1 sum = %f \n", thr_cw1_tot); + printf("round_trials = %d, errs[1][0] = %d, round_trials[1][1] = %d, errs[1][1] = %d, round_trials[1][2] = %d, errs[1][2] = %d, \ + round_trials[1][3] = %d, errs[1][3] = %d \n", round_trials[1][0], errs[1][0],round_trials[1][1], errs[1][1], round_trials[1][2], \ + errs[1][2], round_trials[1][3], errs[1][3]); + }*/ + + + printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n", + SNR, + (double)tx_lev_dB+10*log10(PHY_vars_UE->lte_frame_parms.ofdm_symbol_size/(NB_RB*12)), + sigma2_dB); + if ((transmission_mode != 3) && (transmission_mode != 4)){ + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d), Pe = (%e(%e),%e(%e),%e(%e),%e(%e))," + "dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f), " + "throughput stream 0 = %f , throughput stream 1 = %f, system throughput = %f , rate 0 = %f , rate 1 = %f \n", + errs[0][0], + errs[1][0], + round_trials[0][0], + errs[0][1], + errs[1][1], + round_trials[0][0], + errs[0][2], + errs[1][2], + round_trials[0][0], + errs[0][3], + errs[1][3], + round_trials[0][0], + (double)errs[0][0]/(round_trials[0][0]), + (double)errs[1][0]/(round_trials[0][0]), + (double)errs[0][1]/(round_trials[0][0]), + (double)errs[1][1]/(round_trials[0][0]), + (double)errs[0][2]/(round_trials[0][0]), + (double)errs[1][2]/(round_trials[0][0]), + (double)errs[0][3]/(round_trials[0][0]), + (double)errs[1][3]/(round_trials[0][0]), + dci_errors, + round_trials[0][0], + (double)dci_errors/(round_trials[0][0]), + rate[0]*effective_rate, + 100*effective_rate, + rate[0], + rate[0]*get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs), + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+ + 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) + +4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0]), + thr_cw0_tot, + thr_cw1_tot, + thr_cw0_tot + thr_cw1_tot, + rate[0], + rate[1]); + }else{ + printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d)," + "dci_errors %d/%d, thr TB0 = %f , thr TB1 = %f, overall thr = %f , rate 0 = %f , rate 1 = %f \n", + errs[0][0], + errs[1][0], + round_trials[0][0], + errs[0][1], + errs[1][1], + round_trials[0][0], + errs[0][2], + errs[1][2], + round_trials[0][0], + errs[0][3], + errs[1][3], + round_trials[0][0], + dci_errors, + round_trials[0][0], + thr_cw0_tot, + thr_cw1_tot, + thr_cw0_tot + thr_cw1_tot, + rate0_init, + rate1_init); + } + + if (print_perf==1) { + printf("eNB TX function statistics (per 1ms subframe)\n\n"); + std_phy_proc_tx = sqrt((double)PHY_vars_eNB->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_eNB->phy_proc_tx.trials - pow((double)PHY_vars_eNB->phy_proc_tx.diff/PHY_vars_eNB->phy_proc_tx.trials/cpu_freq_GHz/1000,2)); + printf("Total PHY proc tx :%f us (%d trials)\n",(double)PHY_vars_eNB->phy_proc_tx.diff/PHY_vars_eNB->phy_proc_tx.trials/cpu_freq_GHz/1000.0,PHY_vars_eNB->phy_proc_tx.trials); + printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n",std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, + n_tx_dropped); + std_phy_proc_tx_ifft = sqrt((double)PHY_vars_eNB->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_eNB->ofdm_mod_stats.trials - pow((double)PHY_vars_eNB->ofdm_mod_stats.diff/PHY_vars_eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2)); + printf("OFDM_mod time :%f us (%d trials)\n",(double)PHY_vars_eNB->ofdm_mod_stats.diff/PHY_vars_eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_eNB->ofdm_mod_stats.trials); + printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); + std_phy_proc_tx_mod = sqrt((double)PHY_vars_eNB->dlsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_eNB->dlsch_modulation_stats.trials - pow((double)PHY_vars_eNB->dlsch_modulation_stats.diff/PHY_vars_eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000,2)); + printf("DLSCH modulation time :%f us (%d trials)\n",(double)PHY_vars_eNB->dlsch_modulation_stats.diff/PHY_vars_eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_eNB->dlsch_modulation_stats.trials); + printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); + printf("DLSCH scrambling time :%f us (%d trials)\n",(double)PHY_vars_eNB->dlsch_scrambling_stats.diff/PHY_vars_eNB->dlsch_scrambling_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_eNB->dlsch_scrambling_stats.trials); + std_phy_proc_tx_enc = sqrt((double)PHY_vars_eNB->dlsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_eNB->dlsch_encoding_stats.trials - pow((double)PHY_vars_eNB->dlsch_encoding_stats.diff/PHY_vars_eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000,2)); + printf("DLSCH encoding time :%f us (%d trials)\n",(double)PHY_vars_eNB->dlsch_encoding_stats.diff/PHY_vars_eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_eNB->dlsch_modulation_stats.trials); + printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); + printf("|__ DLSCH turbo encoding time :%f us (%d trials)\n", + ((double)PHY_vars_eNB->dlsch_turbo_encoding_stats.trials/PHY_vars_eNB->dlsch_encoding_stats.trials)*(double) + PHY_vars_eNB->dlsch_turbo_encoding_stats.diff/PHY_vars_eNB->dlsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_eNB->dlsch_turbo_encoding_stats.trials); + printf("|__ DLSCH rate-matching time :%f us (%d trials)\n", + ((double)PHY_vars_eNB->dlsch_rate_matching_stats.trials/PHY_vars_eNB->dlsch_encoding_stats.trials)*(double) + PHY_vars_eNB->dlsch_rate_matching_stats.diff/PHY_vars_eNB->dlsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_eNB->dlsch_rate_matching_stats.trials); + printf("|__ DLSCH sub-block interleaving time :%f us (%d trials)\n", + ((double)PHY_vars_eNB->dlsch_interleaving_stats.trials/PHY_vars_eNB->dlsch_encoding_stats.trials)*(double) + PHY_vars_eNB->dlsch_interleaving_stats.diff/PHY_vars_eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_eNB->dlsch_interleaving_stats.trials); + + printf("\n\nUE RX function statistics (per 1ms subframe)\n\n"); + std_phy_proc_rx = sqrt((double)PHY_vars_UE->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_UE->phy_proc_rx.trials - pow((double)PHY_vars_UE->phy_proc_rx.diff/PHY_vars_UE->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); + printf("Total PHY proc rx :%f us (%d trials)\n",(double)PHY_vars_UE->phy_proc_rx.diff/PHY_vars_UE->phy_proc_rx.trials/cpu_freq_GHz/1000.0, + PHY_vars_UE->phy_proc_rx.trials*2/3); + printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, + rx_q1, rx_q3, n_rx_dropped); + std_phy_proc_rx_fft = sqrt((double)PHY_vars_UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_UE->ofdm_demod_stats.trials - pow((double)PHY_vars_UE->ofdm_demod_stats.diff/PHY_vars_UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); + printf("DLSCH OFDM demodulation and channel_estimation time :%f us (%d trials)\n",(nsymb)*(double)PHY_vars_UE->ofdm_demod_stats.diff/PHY_vars_UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_UE->ofdm_demod_stats.trials*2/3); + printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); + printf("|__ DLSCH rx dft :%f us (%d trials)\n", + (nsymb*PHY_vars_UE->lte_frame_parms.nb_antennas_rx)*(double)PHY_vars_UE->rx_dft_stats.diff/PHY_vars_UE->rx_dft_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_UE->rx_dft_stats.trials*2/3); + printf("|__ DLSCH channel estimation time :%f us (%d trials)\n", + (4.0)*(double)PHY_vars_UE->dlsch_channel_estimation_stats.diff/PHY_vars_UE->dlsch_channel_estimation_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_UE->dlsch_channel_estimation_stats.trials*2/3); + printf("|__ DLSCH frequency offset estimation time :%f us (%d trials)\n", + (4.0)*(double)PHY_vars_UE->dlsch_freq_offset_estimation_stats.diff/PHY_vars_UE->dlsch_freq_offset_estimation_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_UE->dlsch_freq_offset_estimation_stats.trials*2/3); + printf("DLSCH rx pdcch :%f us (%d trials)\n",(double)PHY_vars_UE->dlsch_rx_pdcch_stats.diff/PHY_vars_UE->dlsch_rx_pdcch_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_UE->dlsch_rx_pdcch_stats.trials); + std_phy_proc_rx_demod = sqrt((double)PHY_vars_UE->dlsch_llr_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_UE->dlsch_llr_stats.trials - pow((double)PHY_vars_UE->dlsch_llr_stats.diff/PHY_vars_UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000,2)); + printf("DLSCH Channel Compensation and LLR generation time :%f us (%d trials)\n",(3)*(double)PHY_vars_UE->dlsch_llr_stats.diff/PHY_vars_UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_UE->dlsch_llr_stats.trials/3); + printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3); + printf("DLSCH unscrambling time :%f us (%d trials)\n",(double)PHY_vars_UE->dlsch_unscrambling_stats.diff/PHY_vars_UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0, + PHY_vars_UE->dlsch_unscrambling_stats.trials); + std_phy_proc_rx_dec = sqrt((double)PHY_vars_UE->dlsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/PHY_vars_UE->dlsch_decoding_stats.trials - pow((double)PHY_vars_UE->dlsch_decoding_stats.diff/PHY_vars_UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000,2)); + printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f) :%f us (%d trials, max %f)\n", + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter[0]/iter_trials[0], + (double)PHY_vars_UE->dlsch_decoding_stats.diff/PHY_vars_UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_UE->dlsch_decoding_stats.trials, + (double)PHY_vars_UE->dlsch_decoding_stats.max/cpu_freq_GHz/1000.0); + printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); + printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", + (double)PHY_vars_UE->dlsch_rate_unmatching_stats.diff/PHY_vars_UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_UE->dlsch_rate_unmatching_stats.trials); + printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", + PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->Cminus ? PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->Kminus : PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->Kplus, + (double)PHY_vars_UE->dlsch_turbo_decoding_stats.diff/PHY_vars_UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,PHY_vars_UE->dlsch_turbo_decoding_stats.trials); + printf(" |__ init %f us (cycles/iter %f, %d trials)\n", + (double)PHY_vars_UE->dlsch_tc_init_stats.diff/PHY_vars_UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, + (double)PHY_vars_UE->dlsch_tc_init_stats.diff/PHY_vars_UE->dlsch_tc_init_stats.trials/((double)avg_iter[0]/iter_trials[0]), + PHY_vars_UE->dlsch_tc_init_stats.trials); + printf(" |__ alpha %f us (cycles/iter %f, %d trials)\n", + (double)PHY_vars_UE->dlsch_tc_alpha_stats.diff/PHY_vars_UE->dlsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0, + (double)PHY_vars_UE->dlsch_tc_alpha_stats.diff/PHY_vars_UE->dlsch_tc_alpha_stats.trials*2, + PHY_vars_UE->dlsch_tc_alpha_stats.trials); + printf(" |__ beta %f us (cycles/iter %f,%d trials)\n", + (double)PHY_vars_UE->dlsch_tc_beta_stats.diff/PHY_vars_UE->dlsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0, + (double)PHY_vars_UE->dlsch_tc_beta_stats.diff/PHY_vars_UE->dlsch_tc_beta_stats.trials*2, + PHY_vars_UE->dlsch_tc_beta_stats.trials); + printf(" |__ gamma %f us (cycles/iter %f,%d trials)\n", + (double)PHY_vars_UE->dlsch_tc_gamma_stats.diff/PHY_vars_UE->dlsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0, + (double)PHY_vars_UE->dlsch_tc_gamma_stats.diff/PHY_vars_UE->dlsch_tc_gamma_stats.trials*2, + PHY_vars_UE->dlsch_tc_gamma_stats.trials); + printf(" |__ ext %f us (cycles/iter %f,%d trials)\n", + (double)PHY_vars_UE->dlsch_tc_ext_stats.diff/PHY_vars_UE->dlsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0, + (double)PHY_vars_UE->dlsch_tc_ext_stats.diff/PHY_vars_UE->dlsch_tc_ext_stats.trials*2, + PHY_vars_UE->dlsch_tc_ext_stats.trials); + printf(" |__ intl1 %f us (cycles/iter %f,%d trials)\n", + (double)PHY_vars_UE->dlsch_tc_intl1_stats.diff/PHY_vars_UE->dlsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0, + (double)PHY_vars_UE->dlsch_tc_intl1_stats.diff/PHY_vars_UE->dlsch_tc_intl1_stats.trials, + PHY_vars_UE->dlsch_tc_intl1_stats.trials); + printf(" |__ intl2+HD+CRC %f us (cycles/iter %f,%d trials)\n", + (double)PHY_vars_UE->dlsch_tc_intl2_stats.diff/PHY_vars_UE->dlsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0, + (double)PHY_vars_UE->dlsch_tc_intl2_stats.diff/PHY_vars_UE->dlsch_tc_intl2_stats.trials, + PHY_vars_UE->dlsch_tc_intl2_stats.trials); + } + + if ((transmission_mode != 3) && (transmission_mode != 4)) { + fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + SNR, + mcs1, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + rate[0], + errs[0][0], + round_trials[0][0], + errs[0][1], + round_trials[0][1], + errs[0][2], + round_trials[0][2], + errs[0][3], + round_trials[0][3], + dci_errors); + } + else if ( rx_type== rx_SIC_dual_stream) { + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", + SNR, + mcs1, + mcs2, + tbs0_init, + tbs1_init, + rate0_init, + rate1_init, + errs[0][0], + errs[1][0], + round_trials[0][0], + round_trials[1][0], + sic_attempt[0], + decoded_in_sic[0], + resend_both[0], + resend_one[0], + errs[0][1], + errs[1][1], + round_trials[0][1], + round_trials[1][1], + sic_attempt[1], + decoded_in_sic[1], + resend_both[1], + resend_one[1], + errs[0][2], + errs[1][2], + round_trials[0][2], + round_trials[1][2], + sic_attempt[2], + decoded_in_sic[2], + resend_both[2], + resend_one[2], + errs[0][3], + errs[1][3], + round_trials[0][3], + round_trials[1][3], + sic_attempt[3], + decoded_in_sic[3], + thr_cw0[0], + thr_cw1[0], + thr_cw0[0]+thr_cw1[0], + thr_cw0[1], + thr_cw1[1], + thr_cw0[1]+thr_cw1[1], + thr_cw0[2], + thr_cw1[2], + thr_cw0[2]+thr_cw1[2], + thr_cw0[3], + thr_cw1[3], + thr_cw0[3]+thr_cw1[3], + thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); + } + else{ + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n", + SNR, + mcs1, + mcs2, + tbs0_init, + tbs1_init, + rate0_init, + rate1_init, + errs[0][0], + errs[1][0], + round_trials[0][0], + round_trials[1][0], + TB0_deact[0], + TB1_deact[0], + resend_both[0], + resend_one[0], + errs[0][1], + errs[1][1], + round_trials[0][1], + round_trials[1][1], + TB0_deact[1], + TB1_deact[1], + resend_both[1], + resend_one[1], + errs[0][2], + errs[1][2], + round_trials[0][2], + round_trials[1][2], + TB0_deact[2], + TB1_deact[2], + resend_both[2], + resend_one[2], + errs[0][3], + errs[1][3], + round_trials[0][3], + round_trials[1][3], + thr_cw0[0], + thr_cw1[0], + thr_cw0[0]+thr_cw1[0], + thr_cw0[1], + thr_cw1[1], + thr_cw0[1]+thr_cw1[1], + thr_cw0[2], + thr_cw1[2], + thr_cw0[2]+thr_cw1[2], + thr_cw0[3], + thr_cw1[3], + thr_cw0[3]+thr_cw1[3], + thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]); + } + + + if(abstx){ //ABSTRACTION + if ((transmission_mode != 3)&& (transmission_mode != 4)) { + blerr[0][0] = (double)errs[0][0]/(round_trials[0][0]); + + if(num_rounds>1){ + blerr[0][1] = (double)errs[0][1]/(round_trials[0][1]); + + blerr[0][2] = (double)errs[0][2]/(round_trials[0][2]); + + blerr[0][3] = (double)errs[0][3]/(round_trials[0][3]); + + fprintf(csv_fd,"%e;%e;%e;%e;\n",blerr[0][0],blerr[0][1],blerr[0][2],blerr[0][3]); + } + else { + fprintf(csv_fd,"%e;\n",blerr[0][0]); + } + } + else { + blerr[0][0] = (double)errs[0][0]/(round_trials[0][0]); + blerr[1][0] = (double)errs[1][0]/(round_trials[0][0]); + if(num_rounds>1){ + blerr[0][1] = (double)errs[0][1]/(round_trials[0][1]); + blerr[1][1] = (double)errs[1][1]/(round_trials[1][1]); + blerr[0][2] = (double)errs[0][2]/(round_trials[0][2]); + blerr[1][2] = (double)errs[1][2]/(round_trials[1][2]); + blerr[0][3] = (double)errs[0][3]/(round_trials[0][3]); + blerr[1][3] = (double)errs[1][3]/(round_trials[1][3]); + fprintf(csv_fd,"%e;%e;%e;%e;%e;%e;%e;%e;\n",blerr[0][0],blerr[1][0],blerr[0][1],blerr[1][1],blerr[0][2],blerr[1][2], blerr[0][3], blerr[1][3]); + } + else { + fprintf(csv_fd,"%e,%e;\n",blerr[0][0], blerr[1][0]); + } + } + } + + if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); + if ((transmission_mode != 3) && (transmission_mode != 4)) { + fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + SNR, + mcs1, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + rate[0], + errs[0][0], + round_trials[0][0], + errs[0][1], + round_trials[0][1], + errs[0][2], + round_trials[0][2], + errs[0][3], + round_trials[0][3], + dci_errors); + + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); + fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + SNR, + mcs1, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + rate[0]*effective_rate, + 100*effective_rate, + rate[0], + (double)avg_iter[0]/iter_trials[0], + errs[0][0], + round_trials[0], + errs[0][1], + round_trials[1], + errs[0][2], + round_trials[2], + errs[0][3], + round_trials[3], + (double)errs[0][0]/(round_trials[0][0]), + (double)errs[0][1]/(round_trials[0][0]), + (double)errs[0][2]/(round_trials[0][0]), + (double)errs[0][3]/(round_trials[0][0]), + dci_errors, + round_trials[0], + (double)dci_errors/(round_trials[0][0]), + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])); + } + else { + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + SNR, + mcs1,mcs2, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, + rate[0], + errs[0][0], + round_trials[0][0], + errs[0][1], + round_trials[0][1], + errs[0][2], + round_trials[0][2], + errs[0][3], + round_trials[0][3], + dci_errors); + + //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + SNR, + mcs1,mcs2, + PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + PHY_vars_eNB->dlsch_eNB[0][1]->harq_processes[0]->TBS, + rate[0]*effective_rate, + 100*effective_rate, + rate[0], + (double)avg_iter[0]/iter_trials[0], + errs[0][0], + round_trials[0][0], + errs[0][1], + round_trials[0][1], + errs[0][2], + round_trials[0][2], + errs[0][3], + round_trials[3], + (double)errs[0][0]/(round_trials[0][0]), + (double)errs[0][1]/(round_trials[0][0]), + (double)errs[0][2]/(round_trials[0][0]), + (double)errs[0][3]/(round_trials[0][0]), + dci_errors, + round_trials[0][0], + (double)dci_errors/(round_trials[0][0]), + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)PHY_vars_eNB->dlsch_eNB[0][0]->harq_processes[0]->TBS, + (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])); + } + //fprintf(time_meas_fd,"eNB_PROC_TX(%d); OFDM_MOD(%d); DL_MOD(%d); DL_SCR(%d); DL_ENC(%d); UE_PROC_RX(%d); OFDM_DEMOD_CH_EST(%d); RX_PDCCH(%d); CH_COMP_LLR(%d); DL_USCR(%d); DL_DECOD(%d);\n", + fprintf(time_meas_fd,"%d; %d; %d; %d; %d; %d; %d; %d; %d; %d; %d;", + PHY_vars_eNB->phy_proc_tx.trials, + PHY_vars_eNB->ofdm_mod_stats.trials, + PHY_vars_eNB->dlsch_modulation_stats.trials, + PHY_vars_eNB->dlsch_scrambling_stats.trials, + PHY_vars_eNB->dlsch_encoding_stats.trials, + PHY_vars_UE->phy_proc_rx.trials, + PHY_vars_UE->ofdm_demod_stats.trials, + PHY_vars_UE->dlsch_rx_pdcch_stats.trials, + PHY_vars_UE->dlsch_llr_stats.trials, + PHY_vars_UE->dlsch_unscrambling_stats.trials, + PHY_vars_UE->dlsch_decoding_stats.trials + ); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;", + get_time_meas_us(&PHY_vars_eNB->phy_proc_tx), + get_time_meas_us(&PHY_vars_eNB->ofdm_mod_stats), + get_time_meas_us(&PHY_vars_eNB->dlsch_modulation_stats), + get_time_meas_us(&PHY_vars_eNB->dlsch_scrambling_stats), + get_time_meas_us(&PHY_vars_eNB->dlsch_encoding_stats), + get_time_meas_us(&PHY_vars_UE->phy_proc_rx), + nsymb*get_time_meas_us(&PHY_vars_UE->ofdm_demod_stats), + get_time_meas_us(&PHY_vars_UE->dlsch_rx_pdcch_stats), + 3*get_time_meas_us(&PHY_vars_UE->dlsch_llr_stats), + get_time_meas_us(&PHY_vars_UE->dlsch_unscrambling_stats), + get_time_meas_us(&PHY_vars_UE->dlsch_decoding_stats) + ); + //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); + + //fprintf(time_meas_fd,"IFFT;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); + + //fprintf(time_meas_fd,"MOD;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); + + //fprintf(time_meas_fd,"ENC;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); + + + //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); + + //fprintf(time_meas_fd,"FFT;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); + + //fprintf(time_meas_fd,"DEMOD;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); + + //fprintf(time_meas_fd,"DEC;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); + + + /* + fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + PHY_vars_eNB->phy_proc_tx.trials, + PHY_vars_eNB->ofdm_mod_stats.trials, + PHY_vars_eNB->dlsch_modulation_stats.trials, + PHY_vars_eNB->dlsch_scrambling_stats.trials, + PHY_vars_eNB->dlsch_encoding_stats.trials, + PHY_vars_UE->phy_proc_rx.trials, + PHY_vars_UE->ofdm_demod_stats.trials, + PHY_vars_UE->dlsch_rx_pdcch_stats.trials, + PHY_vars_UE->dlsch_llr_stats.trials, + PHY_vars_UE->dlsch_unscrambling_stats.trials, + PHY_vars_UE->dlsch_decoding_stats.trials); + */ + printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate[0]); + break; + } else if (test_perf !=0 ){ + printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate[0]*effective_rate, 100*effective_rate, rate[0]); + } + if (abstx == 1) { + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { + if (((double)errs[0][0]/(round_trials[0][0]))<1e-2 && ((double)errs[1][0]/(round_trials[1][0]))<1e-2) + if (((double)errs[0][0]/(round_trials[0][0]))<1e-2 && ((double)errs[1][0]/(round_trials[1][0]))<1e-2) + break; + } + else{ + if (((double)errs[0][0]/(round_trials[0][0]))<1e-2) + break; + + } + } + else { + + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { + if (((double)errs[0][0]/(round_trials[0][0]))<1e-3 && ((double)errs[1][0]/(round_trials[1][0]))<1e-3) + break; + } + else{ + if (((double)errs[0][0]/(round_trials[0][0]))<1e-3) + break; + + } + + } + + + if (n_frames==2) + break; + + }// SNR + + } //ch_realization + + fclose(bler_fd); + + if (test_perf !=0) + fclose (time_meas_fd); + + //fprintf(tikz_fd,"};\n"); + //fclose(tikz_fd); + + if (input_trch_file==1) + fclose(input_trch_fd); + + if (input_file==1) + fclose(input_fd); + + if(abstx) { // ABSTRACTION + fprintf(csv_fd,"];"); + fclose(csv_fd); + } + + if (uncoded_ber_bit) + free(uncoded_ber_bit); + + uncoded_ber_bit = NULL; + + for (k=0; kdlsch_eNB[0][i]); + printf("UE %d\n",i); + free_ue_dlsch(PHY_vars_UE->dlsch_ue[0][i]); + } + + + printf("Freeing channel I/O\n"); + + for (i=0; i<2; i++) { + free(s_re[i]); + free(s_im[i]); + free(r_re[i]); + free(r_im[i]); + } + + free(s_re); + free(s_im); + free(r_re); + free(r_im); + + // lte_sync_time_free(); + + // printf("[MUMIMO] mcs %d, mcsi %d, offset %d, bler %f\n",mcs,mcs_i,offset_mumimo_llr_drange_fix,((double)errs[0])/((double)round_trials[0])); + + return(0); +} + + From b9407c40cfdd8c3398ce35b60e0bdf0dfc9e3aec Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 27 Jan 2017 15:31:39 +0100 Subject: [PATCH 228/571] adding missing file --- openair1/PHY/TOOLS/lte_phy_scope_tm4.c | 943 +++++++++++++++++++++++++ 1 file changed, 943 insertions(+) create mode 100644 openair1/PHY/TOOLS/lte_phy_scope_tm4.c diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c new file mode 100644 index 0000000000..2d723cd6bb --- /dev/null +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -0,0 +1,943 @@ +/******************************************************************************* + 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 . + + 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 + + *******************************************************************************/ +/* Form definition file generated by fdesign */ + +#include +#include "lte_phy_scope.h" + +#define TPUT_WINDOW_LENGTH 100 +int otg_enabled; + +FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW}; + +float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; +float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; +float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; +float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; +float tput_ue_max[NUMBER_OF_UE_MAX] = {0}; + +static void ia_receiver_on_off( FL_OBJECT *button, long arg) +{ + + if (fl_get_button(button)) { + fl_set_object_label(button, "IA Receiver ON"); + // PHY_vars_UE_g[0][0]->use_ia_receiver = 1; + fl_set_object_color(button, FL_GREEN, FL_GREEN); + } else { + fl_set_object_label(button, "IA Receiver OFF"); + // PHY_vars_UE_g[0][0]->use_ia_receiver = 0; + fl_set_object_color(button, FL_RED, FL_RED); + } +} + +static void dl_traffic_on_off( FL_OBJECT *button, long arg) +{ + + if (fl_get_button(button)) { + fl_set_object_label(button, "DL Traffic ON"); + otg_enabled = 1; + fl_set_object_color(button, FL_GREEN, FL_GREEN); + } else { + fl_set_object_label(button, "DL Traffic OFF"); + otg_enabled = 0; + fl_set_object_color(button, FL_RED, FL_RED); + } +} + +FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) +{ + + FL_OBJECT *obj; + FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui ); + + // Define form + fdui->lte_phy_scope_enb = fl_bgn_form( FL_NO_BOX, 800, 800 ); + + // This the whole UI box + obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" ); + fl_set_object_color( obj, FL_BLACK, FL_BLACK ); + + // Received signal + fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); + fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color + fl_set_xyplot_ybounds(fdui->rxsig_t,10,70); + + // Time-domain channel response + fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" ); + fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color + + // Frequency-domain channel response + fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); + fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color + fl_set_xyplot_ybounds( fdui->chest_f,30,70); + + // LLR of PUSCH + fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pusch_llr,2); + + // I/Q PUSCH comp + fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pusch_comp, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pusch_comp,2); + fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); + + // I/Q PUCCH comp (format 1) + fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" ); + fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pucch_comp1, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pucch_comp1,2); + // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); + + // I/Q PUCCH comp (fromat 1a/b) + fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pucch_comp, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pucch_comp,2); + // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); + + // Throughput on PUSCH + fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" ); + fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE ); + fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color + + // Generic eNB Button + fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" ); + fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); + fl_set_button(fdui->button_0,0); + otg_enabled = 0; + fl_set_object_label(fdui->button_0, "DL Traffic OFF"); + fl_set_object_color(fdui->button_0, FL_RED, FL_RED); + fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 ); + + fl_end_form( ); + fdui->lte_phy_scope_enb->fdui = fdui; + + return fdui; +} + +void phy_scope_eNB(FD_lte_phy_scope_enb *form, + PHY_VARS_eNB *phy_vars_enb, + int UE_id) +{ + int eNB_id = 0; + int i,i2,arx,atx,ind,k; + LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_enb->frame_parms; + int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti; + uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; + uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE + int16_t **rxsig_t; + int16_t **chest_t; + int16_t **chest_f; + int16_t *pusch_llr; + int16_t *pusch_comp; + int32_t *pucch1_comp; + int32_t *pucch1_thres; + int32_t *pucch1ab_comp; + float Re,Im,ymax; + float *llr, *bit; + float I[nsymb_ce*2], Q[nsymb_ce*2]; + float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240],C_pucch[10240]; + float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES]; + float chest_t_abs[nb_antennas_rx][frame_parms->ofdm_symbol_size]; + float *chest_f_abs; + float time[FRAME_LENGTH_COMPLEX_SAMPLES]; + float time2[2048]; + float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx]; + int frame = phy_vars_enb->proc.proc_rxtx[0].frame_tx; + uint32_t total_dlsch_bitrate = phy_vars_enb->total_dlsch_bitrate; + int coded_bits_per_codeword = 0; + uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2 + int mcs = 0; + + // choose max MCS to compute coded_bits_per_codeword + if (phy_vars_enb->ulsch[UE_id]!=NULL) { + for (harq_pid=0; harq_pid<3; harq_pid++) { + mcs = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->mcs,mcs); + } + } + + coded_bits_per_codeword = frame_parms->N_RB_UL*12*get_Qm(mcs)*frame_parms->symbols_per_tti; + + chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); + llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero + bit = malloc(coded_bits_per_codeword*sizeof(float)); + + rxsig_t = (int16_t**) phy_vars_enb->common_vars.rxdata[eNB_id]; + chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; + chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; + pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; + pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0]; + pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; + pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; + pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; + + // Received signal in time domain of receive antenna 0 + if (rxsig_t != NULL) { + if (rxsig_t[0] != NULL) { + for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","",""); + } + + for (arx=1; arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]); + } + } + } + + // Channel Impulse Response + if (chest_t != NULL) { + ymax = 0; + + if (chest_t[0] !=NULL) { + for (i=0; i<(frame_parms->ofdm_symbol_size); i++) { + i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size; + time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1)); + chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1])); + + if (chest_t_abs[0][i] > ymax) + ymax = chest_t_abs[0][i]; + } + + fl_set_xyplot_data(form->chest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","",""); + } + + for (arx=1; arxofdm_symbol_size>>3); i++) { + chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1])); + + if (chest_t_abs[arx][i] > ymax) + ymax = chest_t_abs[arx][i]; + } + + fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]); + fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT); + } + } + + // Avoid flickering effect + // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); + fl_set_xyplot_ybounds(form->chest_t,0,ymax); + } + + // Channel Frequency Response + if (chest_f != NULL) { + ind = 0; + + for (atx=0; atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); + fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3); + fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); + fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); + + for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + + // other tx antennas + if (nb_antennas_tx > 1) { + if (nb_antennas_rx > 1) { + for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + } + } else { // 1 rx antenna + atx=1; + arx=0; + fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + } + } + + // PUSCH LLRs + if (pusch_llr != NULL) { + for (i=0; ipusch_llr,bit,llr,coded_bits_per_codeword,"","",""); + } + + // PUSCH I/Q of MF Output + if (pusch_comp!=NULL) { + ind=0; + + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_UL; i++) { + I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i]; + Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1]; + ind++; + } + } + + fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","",""); + } + + // PUSCH I/Q of MF Output + if (pucch1ab_comp!=NULL) { + for (ind=0; ind<10240; ind++) { + + I_pucch[ind] = (float)pucch1ab_comp[2*(ind)]; + Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1]; + A_pucch[ind] = 10*log10(pucch1_comp[ind]); + B_pucch[ind] = ind; + C_pucch[ind] = (float)pucch1_thres[ind]; + } + fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","",""); + fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","",""); + fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED); + fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000); + fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000); + + fl_set_xyplot_ybounds(form->pucch_comp1,0,80); + } + + + // PUSCH Throughput + memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); + memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); + + tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; + tput_enb[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; + + fl_set_xyplot_data(form->pusch_tput,tput_time_enb[UE_id],tput_enb[UE_id],TPUT_WINDOW_LENGTH,"","",""); + + // fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax); + // fl_set_xyplot_ybounds(form->pusch_tput,0,ymax); + + fl_check_forms(); + + free(llr); + free(bit); + free(chest_f_abs); +} + + +FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) { + + FL_OBJECT *obj; + FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui ); + + // Define form + fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 ); + + // This the whole UI box + obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" ); + fl_set_object_color( obj, FL_BLACK, FL_BLACK ); + + // Received signal + fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); + fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color + fl_set_xyplot_ybounds(fdui->rxsig_t,30,70); + + // Time-domain channel response + fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" ); + fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color + + // Frequency-domain channel response + fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); + fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); + fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color + fl_set_xyplot_ybounds( fdui->chest_f,30,70); + + /* + // LLR of PBCH + fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN ); + fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pbch_llr,2); + fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR); + fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920); + + // I/Q PBCH comp + fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN ); + fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pbch_comp,2); + fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100); + fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100); + + // LLR of PDCCH + fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN ); + fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdcch_llr,2); + + // I/Q PDCCH comp + fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN ); + fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdcch_comp,2); + fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR); + */ + + int offset=240; + // LLR of PDSCH + fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_llr,2); + fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR); + + // I/Q PDSCH comp + fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_comp,2); + + // LLR of PDSCH + fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); + fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2); + fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR); + + // I/Q PDSCH comp + fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" ); + fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW ); + fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color + fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2); + + /* + // Throughput on PDSCH + fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" ); + fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX ); + fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE ); + fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color + + // Generic UE Button + fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" ); + fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); + //openair_daq_vars.use_ia_receiver = 0; + fl_set_button(fdui->button_0,0); + fl_set_object_label(fdui->button_0, "IA Receiver OFF"); + fl_set_object_color(fdui->button_0, FL_RED, FL_RED); + fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 ); + fl_hide_object(fdui->button_0); + */ + + fl_end_form( ); + fdui->lte_phy_scope_ue->fdui = fdui; + + return fdui; +} + +void phy_scope_UE(FD_lte_phy_scope_ue *form, + PHY_VARS_UE *phy_vars_ue, + int eNB_id, + int UE_id, + uint8_t subframe){ + int i,arx,atx,ind,k; + LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; + int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti; + uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; + uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx_eNB; + int16_t **rxsig_t; + int16_t **chest_t; + int16_t **chest_f; + int16_t *pdsch_llr,*pdsch_llr1; + int16_t *pdsch_comp,*pdsch_comp1; + int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1; + int8_t *pdcch_llr; + int16_t *pdcch_comp; + int8_t *pbch_llr; + int16_t *pbch_comp; + float Re,Im,ymax=1; + int num_pdcch_symbols=3; + float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch; + float *I, *Q; + float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES]; + float **chest_t_abs; + float time[FRAME_LENGTH_COMPLEX_SAMPLES]; + float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx]; + int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx; + uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id]; + int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1; + int mod0,mod1; + int mcs0 = 0; + int mcs1=0; + unsigned char harq_pid = 0; + if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[eNB_id][0]->current_harq_pid; + if (harq_pid>=8) + return; + + mcs0 = phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->mcs; + + // Button 0 + /* + if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { + // we are in TM5 + fl_show_object(form->button_0); + } + */ + } + + + if (phy_vars_ue->dlsch[eNB_id][1]!=NULL) { + harq_pid = phy_vars_ue->dlsch[eNB_id][1]->current_harq_pid; + if (harq_pid>=8) + return; + + mcs1 = phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->mcs; + } + + if (phy_vars_ue->pdcch_vars[eNB_id]!=NULL) { + num_pdcch_symbols = phy_vars_ue->pdcch_vars[eNB_id]->num_pdcch_symbols; + } + + // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) { + mod0 = get_Qm(mcs0); + coded_bits_per_codeword0 = get_G(frame_parms, + phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs0), + phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe); + } else { + coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + mod0=0; + } + if (phy_vars_ue->dlsch[eNB_id][1]!=NULL) { + mod1 = get_Qm(mcs1); + coded_bits_per_codeword1 = get_G(frame_parms, + phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, + get_Qm(mcs1), + phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->Nl, + num_pdcch_symbols, + frame, + subframe); + } else { + coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); + mod1=0; + } + + I = (float*) calloc(nsymb_ce*2,sizeof(float)); + Q = (float*) calloc(nsymb_ce*2,sizeof(float)); + chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*)); + for (arx=0;arxofdm_symbol_size,sizeof(float)); + } + chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); + llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // init to zero + bit0 = malloc(coded_bits_per_codeword0*sizeof(float)); + llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // init to zero + bit1 = malloc(coded_bits_per_codeword1*sizeof(float)); + llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero + bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); + + rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata; + chest_t = (int16_t**) phy_vars_ue->common_vars.dl_ch_estimates_time[eNB_id]; + chest_f = (int16_t**) phy_vars_ue->common_vars.dl_ch_estimates[eNB_id]; + pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; + pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; + pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[eNB_id]->llr; + pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[eNB_id]->rxdataF_comp[0]; + pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[eNB_id]->llr[0]; // stream 0 + pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[eNB_id]->llr[1]; // stream 1 + pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[eNB_id]->rxdataF_comp0[0]; + //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_ext[0]; + //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->rxdataF_ext[1]; + pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[eNB_id]->rxdataF_comp1[0][0])[0]; + //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0]; + + pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[eNB_id]->dl_ch_mag0[0]; + pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[eNB_id]->dl_ch_mag1[0][0])[0]; + pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[eNB_id]->dl_ch_magb0[0]; + pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[eNB_id]->dl_ch_magb1[0][0])[0]; + + fl_freeze_form(form->lte_phy_scope_ue); + + // Received signal in time domain of receive antenna 0 + if (rxsig_t != NULL) { + if (rxsig_t[0] != NULL) { + for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","",""); + } + + for (arx=1;arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]); + } + } + } + + // Channel Impulse Response (still repeated format) + if (chest_t != NULL) { + ymax = 0; + + if (chest_t[0] !=NULL) { + for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) { + chest_t_abs[0][i] = (float) (chest_t[0][4*i]*chest_t[0][4*i]+chest_t[0][4*i+1]*chest_t[0][4*i+1]); + + if (chest_t_abs[0][i] > ymax) + ymax = chest_t_abs[0][i]; + } + + fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","",""); + } + + for (arx=1; arxofdm_symbol_size>>3); i++) { + chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]); + + if (chest_t_abs[arx][i] > ymax) + ymax = chest_t_abs[arx][i]; + } + + fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]); + fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT); + } + } + // Avoid flickering effect + // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax); + fl_set_xyplot_ybounds(form->chest_t,0,ymax); + } + + // Channel Frequency Response (includes 5 complex sample for filter) + if (chest_f != NULL) { + ind = 0; + for (atx=0;atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); + //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2); + // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2); + fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); + fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","",""); + + for (arx=1;arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + // other tx antennas + if (nb_antennas_tx > 1) { + if (nb_antennas_rx > 1) { + for (atx=1;atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + } + } else { // 1 rx antenna + atx=1; arx=0; + fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]); + } + } + } + /* + // PBCH LLRs + if (pbch_llr != NULL) { + for (i=0; i<1920;i++) { + llr_pbch[i] = (float) pbch_llr[i]; + bit_pbch[i] = (float) i; + } + + fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","",""); + } + + // PBCH I/Q of MF Output + if (pbch_comp!=NULL) { + for (i=0; i<72*2; i++) { + I[i] = pbch_comp[2*i]; + Q[i] = pbch_comp[2*i+1]; + } + + fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","",""); + } + + // PDCCH LLRs + if (pdcch_llr != NULL) { + for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) { + llr_pdcch[i] = (float) pdcch_llr[i]; + bit_pdcch[i] = (float) i; + } + + fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); + fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); + } + + // PDCCH I/Q of MF Output + if (pdcch_comp!=NULL) { + for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) { + I[i] = pdcch_comp[2*i]; + Q[i] = pdcch_comp[2*i+1]; + } + + fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); + } + */ + + // PDSCH LLRs CW0 + if (pdsch_llr != NULL) { + for (i=0; ipdsch_llr,0,coded_bits_per_codeword0); + fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","",""); + } + + + // PDSCH I/Q of MF Output + if (pdsch_comp!=NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i]; + Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; + ind++; + } + } + fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","",""); + } + + + if (pdsch_mag0 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN); + } + + + if (pdsch_magb0 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED); + } + if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = + (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+ + pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])* + cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = + (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ + pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* + sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE); + } + + + // PDSCH LLRs CW1 + if (pdsch_llr1 != NULL) { + for (i=0; ipdsch_llr1,0,coded_bits_per_codeword1); + fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","",""); + } + + // PDSCH I/Q of MF Output + if (pdsch_comp1!=NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i]; + Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; + ind++; + } + } + fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","",""); + } + + if (pdsch_mag1 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN); + } + + if (pdsch_magb1 != NULL) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED); + } + + if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) { + ind=0; + for (k=0; ksymbols_per_tti; k++) { + for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { + I[ind] = + (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+ + pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])* + cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + Q[ind] = + (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+ + pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])* + sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2)); + ind++; + } + } + fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE); + } + + + /* + // PDSCH Throughput + memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); + memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float)); + + tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; + tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; + + if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) { + tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1]; + } + + fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","",""); + + fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); + */ + + fl_unfreeze_form(form->lte_phy_scope_ue); + + fl_check_forms(); + + free(I); + free(Q); + free(chest_f_abs); + free(llr0); + free(bit0); + free(llr1); + free(bit1); + free(bit_pdcch); + free(llr_pdcch); + for (arx=0;arx Date: Fri, 27 Jan 2017 15:49:00 +0100 Subject: [PATCH 229/571] add missing #ifndef #endif guards in header file modified: targets/COMMON/openairinterface5g_limits.h --- targets/COMMON/openairinterface5g_limits.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 6185dd8bbe..d9590873e8 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -1,3 +1,6 @@ +#ifndef OPENAIRINTERFACE5G_LIMITS_H_ +#define OPENAIRINTERFACE5G_LIMITS_H_ + #if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) #define NUMBER_OF_eNB_MAX 1 #define NUMBER_OF_UE_MAX 16 @@ -18,3 +21,5 @@ #define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory #endif #endif + +#endif From c62b54a030ef77591df36d353de544a2d95ff28c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 Jan 2017 15:49:45 +0100 Subject: [PATCH 230/571] remove duplicated definitions I am not sure if it's the right way to solve the problem, so I keep the definitions here and put them inside #if 0 #endif --- openair3/NAS/COMMON/commonDef.h | 2 ++ openair3/NAS/COMMON/networkDef.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/openair3/NAS/COMMON/commonDef.h b/openair3/NAS/COMMON/commonDef.h index 64216b0094..84d97fc4a8 100644 --- a/openair3/NAS/COMMON/commonDef.h +++ b/openair3/NAS/COMMON/commonDef.h @@ -314,6 +314,7 @@ typedef struct { */ #define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];} +#if 0 /* * User notification callback, executed whenever a change of data with * respect of network information (e.g. network registration and/or @@ -322,6 +323,7 @@ typedef struct { */ typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t, const char*, size_t); +#endif typedef enum eps_protocol_discriminator_e { /* Protocol discriminator identifier for EPS Mobility Management */ diff --git a/openair3/NAS/COMMON/networkDef.h b/openair3/NAS/COMMON/networkDef.h index 46716bee24..e3e8e1f08b 100644 --- a/openair3/NAS/COMMON/networkDef.h +++ b/openair3/NAS/COMMON/networkDef.h @@ -260,12 +260,14 @@ typedef struct { network_pkf_t* pkf[NET_PACKET_FILTER_MAX]; } network_tft_t; +#if 0 /* * User notification callback, executed whenever a change of status with * respect of PDN connection or EPS bearer context is notified by the EPS * Session Management sublayer */ typedef int (*esm_indication_callback_t) (int, network_pdn_state_t); +#endif /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ From f6e42ce9e46f6822b6a311a1804335068691d617 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 Jan 2017 15:52:22 +0100 Subject: [PATCH 231/571] fix compilation of oaisim That's not the end of the story though. --- openair3/NAS/UE/API/USIM/usim_api.c | 17 +++++++++-------- openair3/NAS/UE/API/USIM/usim_api.h | 4 ++-- openair3/NAS/UE/EMM/SecurityModeControl.c | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index e281999a09..efb0383596 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -150,7 +150,8 @@ int usim_api_write(const char *filename, const usim_data_t* data) ** Others: None ** ** ** ***************************************************************************/ -int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* autn_pP, +int usim_api_authenticate_test(usim_data_t *usim_data, + const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts_pP, OctetString* res_pP, OctetString* ck_pP, OctetString* ik_pP) { @@ -166,7 +167,7 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au // RES = XDOUT for (i=0; ivalue[i] = rand_pP->value[i] ^ _usim_api_k[i]; + res_pP->value[i] = rand_pP->value[i] ^ usim_data->keys.usim_api_k[i]; } //step2: res = f2(xdout,n) @@ -257,19 +258,19 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au /* Concealed value of the counter SQNms in the USIM: * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */ - f5star(_usim_api_k, rand_pP->value, ak); + f5star(usim_data->keys.usim_api_k, rand_pP->value, ak, usim_data->keys.opc); u8 sqn_ms[USIM_API_SQNMS_SIZE]; memset(sqn_ms, 0, USIM_API_SQNMS_SIZE); //#define USIM_API_SQN_MS_SIZE 3 - printf("_usim_api_data.sqn_ms %p\n",_usim_api_data.sqn_ms); + printf("usim_data->usim_sqn_data.sqn_ms %p\n", usim_data->usim_sqn_data.sqn_ms); for (i = 0; i < USIM_API_SQNMS_SIZE; i++) { //#warning "LG:BUG HERE TODO" - printf("i %d: ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); + printf("i %d: ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i] %d\n",i, ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]); sqn_ms[USIM_API_SQNMS_SIZE - i] = - ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; + ((uint8_t*)(usim_data->usim_sqn_data.sqn_ms))[USIM_API_SQNMS_SIZE - i]; } u8 sqnms[USIM_API_SQNMS_SIZE]; @@ -285,8 +286,8 @@ int usim_api_authenticate_test(const OctetString* rand_pP, const OctetString* au * MACS = f1*K(SQNMS || RAND || AMF) */ #define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE u8 macs[USIM_API_MACS_SIZE]; - f1star(_usim_api_k, rand_pP->value, sqn_ms, - &rand_pP->value[USIM_API_SQN_SIZE], macs); + f1star(usim_data->keys.usim_api_k, rand_pP->value, sqn_ms, + &rand_pP->value[USIM_API_SQN_SIZE], macs, usim_data->keys.opc); LOG_TRACE(DEBUG, "USIM-API - MACS %02X%02X%02X%02X%02X%02X%02X%02X", macs[0],macs[1],macs[2],macs[3], macs[4],macs[5],macs[6],macs[7]); diff --git a/openair3/NAS/UE/API/USIM/usim_api.h b/openair3/NAS/UE/API/USIM/usim_api.h index 5915d914bf..f2f80d610c 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.h +++ b/openair3/NAS/UE/API/USIM/usim_api.h @@ -366,7 +366,6 @@ typedef struct { /* usim test mode */ uint8_t usimtestmode; usim_sqn_data_t usim_sqn_data; ->>>>>>> UE/API: rename _usim_api_data to usim_sqn_data and move it to usim_data } usim_data_t; /****************************************************************************/ @@ -384,7 +383,8 @@ int usim_api_write(const char *filename, const usim_data_t* data); int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, const OctetString* autn_pP, OctetString* auts, OctetString* res, OctetString* ck, OctetString* ik); -int usim_api_authenticate_test(const OctetString* rand, const OctetString* autn, +int usim_api_authenticate_test(usim_data_t *usim_data, + const OctetString* rand, const OctetString* autn, OctetString* auts, OctetString* res, OctetString* ck, OctetString* ik); diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index 46d2a4fc2e..0991fb22bb 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -286,7 +286,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, user->emm_data->security->selected_algorithms.encryption = seea; user->emm_data->security->selected_algorithms.integrity = seia; #if defined(NAS_BUILT_IN_UE) - nas_itti_kenb_refresh_req(_security_data.kenb.value); + nas_itti_kenb_refresh_req(security_data->kenb.value); #endif } From 106f31524bea2401601157931d0a0702ee0367a9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 Jan 2017 15:58:17 +0100 Subject: [PATCH 232/571] update CMakeLists for ubuntu 16.04 The previous version did not compile on ubuntu 16.04. I left the old version, commented, just in case. --- cmake_targets/at_commands/CMakeLists.txt | 60 +++++++++++++++--------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index 8993466bc2..61d1565bac 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -88,31 +88,47 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototype set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -DMALLOC_CHECK_=3 -O2") -#This is to detect nettle version changes between Ubuntu 14.04/16.04 -set ( nettle_cmd "nettle-hash" ) -set ( nettle_arg "-V" ) -execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev) - -string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov}) - -message("NETTLE_VERSION = ${nv}") - -# we need to remove decimal as floating point arithematic does not work properly with C preprocessor -STRING(REGEX REPLACE "[.]" "" nv ${nv}) - -if ("${nv}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -set (NETTLE_VERSION "${nv}") -add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}") +##This is to detect nettle version changes between Ubuntu 14.04/16.04 +#set ( nettle_cmd "nettle-hash" ) +#set ( nettle_arg "-V" ) +#execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev) +# +#string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov}) +# +#message("NETTLE_VERSION = ${nv}") +# +## we need to remove decimal as floating point arithematic does not work properly with C preprocessor +#STRING(REGEX REPLACE "[.]" "" nv ${nv}) +# +#if ("${nv}" STREQUAL "") +# message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) +#endif() +# +#set (NETTLE_VERSION "${nv}") +#add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}") include(FindPkgConfig) -INCLUDE(FindNettle) -IF( NOT NETTLE_FOUND ) - MESSAGE( SEND_ERROR "Nettle is required" ) -ENDIF( NOT NETTLE_FOUND ) +pkg_search_module(NETTLE nettle) +if(NOT ${NETTLE_FOUND}) + message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") +else() + include_directories(${NETTLE_INCLUDE_DIRS}) +endif() + +message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") + +string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) +string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) +message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") +message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") + +if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") + message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) +endif() + +add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") +add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") pkg_search_module(OPENSSL openssl REQUIRED) From 53e416be0b7f987ffb33cd2a9421d2b9bc9b169c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 27 Jan 2017 16:09:56 +0100 Subject: [PATCH 233/571] update license information Also included some source files not related to this branch. modified: openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c modified: openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c modified: openair1/PHY/MODULATION/beamforming.c modified: openair1/PHY/TOOLS/twiddle18432.h modified: openair1/SIMULATION/LTE_PHY/dlsim_tm7.c modified: openair3/NAS/TOOLS/nvram.c modified: openair3/NAS/TOOLS/usim.c modified: openair3/NAS/UE/user_defs.h --- .../lte_dl_bf_channel_estimation.c | 47 ++++++++---------- openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c | 48 ++++++++----------- openair1/PHY/MODULATION/beamforming.c | 48 ++++++++----------- openair1/PHY/TOOLS/twiddle18432.h | 48 ++++++++----------- openair1/SIMULATION/LTE_PHY/dlsim_tm7.c | 48 ++++++++----------- openair3/NAS/TOOLS/nvram.c | 47 ++++++++---------- openair3/NAS/TOOLS/usim.c | 47 ++++++++---------- openair3/NAS/UE/user_defs.h | 47 ++++++++---------- 8 files changed, 160 insertions(+), 220 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c index 0b220c2c39..61d2d04f01 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c @@ -1,31 +1,24 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ - 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 . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ #ifdef USER_MODE #include #endif diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c index 4a9010fca0..b4199d9b60 100644 --- a/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c +++ b/openair1/PHY/LTE_TRANSPORT/pilots_ue_spec.c @@ -1,31 +1,23 @@ -/******************************************************************************* - 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 . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file PHY/LTE_TRANSPORT/uespec_pilots.c * \brief Top-level routines for generating DL ue-specific reference signals V12.5 2015-03 diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 88ac12b0a7..d2336f6187 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -1,31 +1,23 @@ -/******************************************************************************* - 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 . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - -Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file PHY/MODULATION/beamforming.c * \brief diff --git a/openair1/PHY/TOOLS/twiddle18432.h b/openair1/PHY/TOOLS/twiddle18432.h index f21987c4cb..8c6c9822dc 100644 --- a/openair1/PHY/TOOLS/twiddle18432.h +++ b/openair1/PHY/TOOLS/twiddle18432.h @@ -1,31 +1,23 @@ -/******************************************************************************* - 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 . - - 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 - - *******************************************************************************/ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /* Twiddles generated with twa = floor(32767*exp(-sqrt(-1)*2*pi*(0:6143)/18432)); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 641efd2ed9..06d5cd94cd 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -1,31 +1,23 @@ - /****************************************************************************** - 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 . - - 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 - - *******************************************************************************/ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file dlsim.c \brief Top-level DL simulator diff --git a/openair3/NAS/TOOLS/nvram.c b/openair3/NAS/TOOLS/nvram.c index 2bf5f6ed82..b10511f2fc 100644 --- a/openair3/NAS/TOOLS/nvram.c +++ b/openair3/NAS/TOOLS/nvram.c @@ -1,31 +1,24 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ - 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 . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. - - *******************************************************************************/ /***************************************************************************** Source usim_data.c diff --git a/openair3/NAS/TOOLS/usim.c b/openair3/NAS/TOOLS/usim.c index 53aefb4a2c..242b30d655 100644 --- a/openair3/NAS/TOOLS/usim.c +++ b/openair3/NAS/TOOLS/usim.c @@ -1,31 +1,24 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ - 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 . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. - - *******************************************************************************/ /***************************************************************************** Source usim_data.c diff --git a/openair3/NAS/UE/user_defs.h b/openair3/NAS/UE/user_defs.h index 63eb860d80..c27cf1320e 100644 --- a/openair3/NAS/UE/user_defs.h +++ b/openair3/NAS/UE/user_defs.h @@ -1,31 +1,24 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ - 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 . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. - - *******************************************************************************/ /***************************************************************************** Source user_defs.h From 66b93704e21f2859a5f7ab7692e8f4781fef5490 Mon Sep 17 00:00:00 2001 From: fnabet Date: Mon, 30 Jan 2017 18:16:16 +0100 Subject: [PATCH 234/571] RLC AM fix poll criteria --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 3050d00d6b..4e5875fee5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -150,9 +150,9 @@ config_req_rlc_am ( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p)); } } -uint32_t pollPDU_tab[PollPDU_pInfinity+1]= {4,8,16,32,64,128,256,1024}; // What is PollPDU_pInfinity??? 1024 for now +uint16_t pollPDU_tab[PollPDU_pInfinity+1]= {4,8,16,32,64,128,256,RLC_AM_POLL_PDU_INFINITE}; //PollPDU_pInfinity is chosen to 0xFFFF for now uint32_t maxRetxThreshold_tab[UL_AM_RLC__maxRetxThreshold_t32+1]= {1,2,3,4,6,8,16,32}; -uint32_t pollByte_tab[PollByte_spare1]= {25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,10000}; // What is PollByte_kBinfinity??? 10000 for now +uint32_t pollByte_tab[PollByte_spare1]= {25000,50000,75000,100000,125000,250000,375000,500000,750000,1000000,1250000,1500000,2000000,3000000,RLC_AM_POLL_BYTE_INFINITE}; // PollByte_kBinfinity is chosen to 0xFFFFFFFF for now uint32_t PollRetransmit_tab[T_PollRetransmit_spare9]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; uint32_t am_t_Reordering_tab[T_Reordering_spare1]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; uint32_t t_StatusProhibit_tab[T_StatusProhibit_spare8]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; From 163c37a5a3667fd0f541598ce79e3b8f7990b9c6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 1 Feb 2017 12:17:39 +0100 Subject: [PATCH 235/571] bugfix: return error in 'emm_msg_encode' in case of failure --- openair3/NAS/COMMON/EMM/MSG/emm_msg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair3/NAS/COMMON/EMM/MSG/emm_msg.c b/openair3/NAS/COMMON/EMM/MSG/emm_msg.c index b067b9c0d1..c357e8784f 100644 --- a/openair3/NAS/COMMON/EMM/MSG/emm_msg.c +++ b/openair3/NAS/COMMON/EMM/MSG/emm_msg.c @@ -464,6 +464,9 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) #endif } + if (encode_result < 0) + LOG_FUNC_RETURN (encode_result); + LOG_FUNC_RETURN (header_result + encode_result); } From 00ebfbb0bc9179a015eb7e7a54d7705e1ee2fdb3 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 1 Feb 2017 15:00:01 +0100 Subject: [PATCH 236/571] fix merge compilation --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 297 +++---------------- 1 file changed, 44 insertions(+), 253 deletions(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 2f2e0088fa..c12cc50ead 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -312,6 +312,7 @@ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); } + return(0); } @@ -495,39 +496,33 @@ extern "C" { // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - uhd::device_addrs_t device_adds = uhd::device::find(args); + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; + uhd::device_addrs_t device_adds = uhd::device::find(args); - if(device_adds.size() == 0) - { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; - - } - - - printf("Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // lock mboard clocks + if(device_adds.size() == 0) { + std::cerr<<"No USRP Device Found. " << std::endl; + free(s); + return -1; + } + LOG_I(PHY,"Found USRP X300\n"); + s->usrp = uhd::usrp::multi_usrp::make(args); + // lock mboard clocks if (openair0_cfg[0].clock_source == internal) s->usrp->set_clock_source("internal"); else s->usrp->set_clock_source("external"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); + //Setting device type to USRP X300/X310 + device->type=USRP_X300_DEV; - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: + // this is not working yet, master clock has to be set via constructor + // set master clock rate and sample rate for tx & rx for streaming + //s->usrp->set_master_clock_rate(usrp_master_clock); + + openair0_cfg[0].rx_gain_calib_table = calib_table_x310; + + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: // from usrp_time_offset //openair0_cfg[0].samples_per_packet = 2048; openair0_cfg[0].tx_sample_advance = 15; @@ -551,17 +546,17 @@ extern "C" { openair0_cfg[0].tx_sample_advance = 50; openair0_cfg[0].tx_bw = 1.25e6; openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } + break; + default: + LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); + exit(-1); + break; + } - } else { - printf("Found USRP B200"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); + } else { + LOG_I(PHY,"Found USRP B200\n"); + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + s->usrp = uhd::usrp::multi_usrp::make(args); // s->usrp->set_rx_subdev_spec(rx_subdev); // s->usrp->set_tx_subdev_spec(tx_subdev); @@ -577,17 +572,14 @@ extern "C" { else s->usrp->set_clock_source("external"); - device->type = USRP_B200_DEV; - - - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - } - else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - } + device->type = USRP_B200_DEV; + if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210; + bw_gain_adjust=0; + } else { + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + } switch ((int)openair0_cfg[0].sample_rate) { case 30720000: @@ -626,217 +618,15 @@ extern "C" { openair0_cfg[0].rx_bw = 20e6; break; default: - printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - } - - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered - openair0_cfg[0].iq_txshift = 4;//shift - openair0_cfg[0].iq_rxrescale = 15;//rescale iqs - - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - //printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - s->usrp->set_rx_freq(openair0_cfg[0].rx_freq[i],i); - set_rx_gain_offset(&openair0_cfg[0],i,bw_gain_adjust); - - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(i); - // limit to maximum gain - if (openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] > gain_range.stop()) { - - printf("RX Gain %lu too high, lower by %f dB\n",i,openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i] - gain_range.stop()); - exit(-1); - } - s->usrp->set_rx_gain(openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],i); - printf("RX Gain %lu %f (%f) => %f (max %f)\n",i, - openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], - openair0_cfg[0].rx_gain[i]-openair0_cfg[0].rx_gain_offset[i],gain_range.stop()); - } - } - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_rate(openair0_cfg[0].sample_rate,i); - //s->usrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - //printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i); - s->usrp->set_tx_gain(openair0_cfg[0].tx_gain[i],i); - } - } - - - // display USRP settings - std::cout << boost::format("Actual master clock: %fMHz...") % (s->usrp->get_master_clock_rate()/1e6) << std::endl; - - sleep(1); - - // create tx & rx streamer - uhd::stream_args_t stream_args_rx("sc16", "sc16"); - int samples=openair0_cfg[0].sample_rate; - samples/=24000; - // stream_args_rx.args["spp"] = str(boost::format("%d") % samples); - - for (i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - std::cout << boost::format("rx_max_num_samps %u") % (s->rx_stream->get_max_num_samps()) << std::endl; - //openair0_cfg[0].samples_per_packet = s->rx_stream->get_max_num_samps(); - - uhd::stream_args_t stream_args_tx("sc16", "sc16"); - //stream_args_tx.args["spp"] = str(boost::format("%d") % 2048);//(openair0_cfg[0].tx_num_channels*openair0_cfg[0].samples_per_packet)); - for (i = 0; itx_stream = s->usrp->get_tx_stream(stream_args_tx); - std::cout << boost::format("tx_max_num_samps %u") % (s->tx_stream->get_max_num_samps()) << std::endl; - - - /* Setting TX/RX BW after streamers are created due to USRP calibration issue */ - for(i=0;iusrp->get_tx_num_channels();i++) { - if (iusrp->set_tx_bandwidth(openair0_cfg[0].tx_bw,i); - printf("Setting tx freq/gain on channel %lu/%lu: BW %f (readback %f)\n",i,s->usrp->get_tx_num_channels(),openair0_cfg[0].tx_bw/1e6,s->usrp->get_tx_bandwidth(i)/1e6); - } - } - for(i=0;iusrp->get_rx_num_channels();i++) { - if (iusrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i); - printf("Setting rx freq/gain on channel %lu/%lu : BW %f (readback %f)\n",i,s->usrp->get_rx_num_channels(),openair0_cfg[0].rx_bw/1e6,s->usrp->get_rx_bandwidth(i)/1e6); - } - } - - s->usrp->set_time_now(uhd::time_spec_t(0.0)); - - - for (i=0;iusrp->get_rx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX frequency: %fGHz...") % (s->usrp->get_rx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual RX gain: %f...") % (s->usrp->get_rx_gain(i)) << std::endl; - std::cout << boost::format("Actual RX bandwidth: %fM...") % (s->usrp->get_rx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual RX antenna: %s...") % (s->usrp->get_rx_antenna(i)) << std::endl; - } - } - - for (i=0;iusrp->get_tx_rate(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX frequency: %fGHz...") % (s->usrp->get_tx_freq(i)/1e9) << std::endl; - std::cout << boost::format("Actual TX gain: %f...") % (s->usrp->get_tx_gain(i)) << std::endl; - std::cout << boost::format("Actual TX bandwidth: %fM...") % (s->usrp->get_tx_bandwidth(i)/1e6) << std::endl; - std::cout << boost::format("Actual TX antenna: %s...") % (s->usrp->get_tx_antenna(i)) << std::endl; - } - } - - std::cout << boost::format("Device timestamp: %f...") % (s->usrp->get_time_now().get_real_secs()) << std::endl; - - // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - uhd::device_addrs_t device_adds = uhd::device::find(args); - - if(device_adds.size() == 0) { - std::cerr<<"No USRP Device Found. " << std::endl; - free(s); - return -1; - } - LOG_I(PHY,"Found USRP X300\n"); - s->usrp = uhd::usrp::multi_usrp::make(args); - // lock mboard clocks - s->usrp->set_clock_source("internal"); - - //Setting device type to USRP X300/X310 - device->type=USRP_X300_DEV; - - // this is not working yet, master clock has to be set via constructor - // set master clock rate and sample rate for tx & rx for streaming - //s->usrp->set_master_clock_rate(usrp_master_clock); - - openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - // from usrp_time_offset - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; - break; - default: - LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); - exit(-1); - break; - } - - } else { - LOG_I(PHY,"Found USRP B200\n"); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; - s->usrp = uhd::usrp::multi_usrp::make(args); - device->type = USRP_B200_DEV; - if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210; - bw_gain_adjust=0; - } else { - openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; - bw_gain_adjust=1; - } - - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); exit(-1); break; } } + + /* device specific */ + //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered + //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_rxrescale = 15;//rescale iqs @@ -870,6 +660,7 @@ extern "C" { // display USRP settings LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); + sleep(1); // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); From ea6fb5c4817b3479ee28c01bb601a683932e459d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 2 Feb 2017 16:35:45 +0100 Subject: [PATCH 237/571] better handle user input in hex_string_to_hex_value Adapt calling sites too. When data comes from the user, it is good to check that what we read is correct and warn the user if it's not. --- common/utils/utils.c | 32 ++++++++++++++++++++++++++------ common/utils/utils.h | 4 ++-- openair3/NAS/TOOLS/conf_usim.c | 13 ++++++++----- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/common/utils/utils.c b/common/utils/utils.c index cf5673fa56..a807a27096 100644 --- a/common/utils/utils.c +++ b/common/utils/utils.c @@ -32,12 +32,17 @@ void *malloc_or_fail(size_t size) { ** Others: None ** ** ** ** Outputs: None ** - ** Return: Converted value ** + ** Return: Converted value (-1 on error) ** ** Others: None ** ** ** ***************************************************************************/ -uint8_t hex_char_to_hex_value (char c) +int hex_char_to_hex_value (char c) { + if (!((c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F') || + (c >= '0' && c <= '9'))) + return -1; + if (c >= 'A') { /* Remove case bit */ c &= ~('a' ^ 'A'); @@ -60,17 +65,32 @@ uint8_t hex_char_to_hex_value (char c) ** Others: None ** ** ** ** Outputs: hex_value: Converted value ** - ** Return: None ** + ** Return: 0 on success, -1 on error ** ** Others: None ** ** ** ***************************************************************************/ -void hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size) +int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size) { int i; - for (i=0; i < size; i++) { - hex_value[i] = (hex_char_to_hex_value(hex_string[2 * i]) << 4) | hex_char_to_hex_value(hex_string[2 * i + 1]); + if (strlen(hex_string) != size*2) { + fprintf(stderr, "the string '%s' should be of length %d\n", hex_string, size*2); + return -1; } + + for (i=0; i < size; i++) { + int a = hex_char_to_hex_value(hex_string[2 * i]); + int b = hex_char_to_hex_value(hex_string[2 * i + 1]); + if (a == -1 || b == -1) goto error; + hex_value[i] = (a << 4) | b; + } + return 0; + +error: + fprintf(stderr, "the string '%s' is not a valid hexadecimal string\n", hex_string); + for (i=0; i < size; i++) + hex_value[i] = 0; + return -1; } char *itoa(int i) { diff --git a/common/utils/utils.h b/common/utils/utils.h index a4444a7793..cfe3df34b9 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -8,9 +8,9 @@ void *calloc_or_fail(size_t size); void *malloc_or_fail(size_t size); // Converts an hexadecimal ASCII coded digit into its value. ** -uint8_t hex_char_to_hex_value (char c); +int hex_char_to_hex_value (char c); // Converts an hexadecimal ASCII coded string into its value.** -void hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); +int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size); char *itoa(int i); diff --git a/openair3/NAS/TOOLS/conf_usim.c b/openair3/NAS/TOOLS/conf_usim.c index 5004363275..3a5c6dbf6d 100644 --- a/openair3/NAS/TOOLS/conf_usim.c +++ b/openair3/NAS/TOOLS/conf_usim.c @@ -287,11 +287,14 @@ void gen_usim_data(usim_data_conf_t *u, usim_data_t *usim_data, usim_data->nasconfig.Timer_T3245_Behaviour.length = 1; usim_data->nasconfig.Timer_T3245_Behaviour.value[0] = 0x00; - /* initialize the subscriber authentication security key */ - hex_string_to_hex_value(usim_data->keys.usim_api_k, - u->usim_api_k, USIM_API_K_SIZE); - hex_string_to_hex_value(usim_data->keys.opc, u->opc, - OPC_SIZE); + /* initialize the subscriber authentication security key */ + if (hex_string_to_hex_value(usim_data->keys.usim_api_k, + u->usim_api_k, USIM_API_K_SIZE) == -1 || + hex_string_to_hex_value(usim_data->keys.opc, + u->opc, OPC_SIZE) == -1) { + fprintf(stderr, "fix your configuration file\n"); + exit(1); + } } bool write_usim_data(const char *directory, int user_id, usim_data_t *usim_data){ From d72294b966dfe1ebff2eeb58f702d40aa1d75b77 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 2 Feb 2017 17:10:59 +0100 Subject: [PATCH 238/571] fix gen_emm_data It was not setting emm_data->eplmn.plmn[X], only emm_data->eplmn.n_plmns, leading to the UE to dig for PLMN 00000. (It's not the end of the story, seems like the PLMN selection does not work, the UE only tries one from what I've seen, but I didn't dig much, may be wrong.) --- openair3/NAS/TOOLS/conf_emm.c | 95 +++++++++++++++++--------------- openair3/NAS/TOOLS/conf_emm.h | 9 ++- openair3/NAS/TOOLS/conf_parser.c | 2 +- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/openair3/NAS/TOOLS/conf_emm.c b/openair3/NAS/TOOLS/conf_emm.c index 48627cdc0e..668b90a0ae 100644 --- a/openair3/NAS/TOOLS/conf_emm.c +++ b/openair3/NAS/TOOLS/conf_emm.c @@ -4,56 +4,65 @@ #include "conf_emm.h" #include "fs.h" -void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count, const networks_t networks) { - memset(emm_data, 0, sizeof(emm_nvdata_t)); - int hplmn_index = get_plmn_index(hplmn, networks); - plmn_conf_param_t *conf = &networks.items[hplmn_index].conf; - emm_data->imsi.length = 8; - emm_data->imsi.u.num.parity = get_msin_parity(msin, conf->mcc, conf->mnc); - emm_data->imsi.u.num.digit1 = conf->mcc[0]; - emm_data->imsi.u.num.digit2 = conf->mcc[1]; - emm_data->imsi.u.num.digit3 = conf->mcc[2]; +void gen_emm_data( + emm_nvdata_t *emm_data, + const char *hplmn, + const char *msin, + const plmns_list *eplmn, + const networks_t networks) +{ + memset(emm_data, 0, sizeof(emm_nvdata_t)); + int hplmn_index = get_plmn_index(hplmn, networks); + plmn_conf_param_t *conf = &networks.items[hplmn_index].conf; + int i; - emm_data->imsi.u.num.digit4 = conf->mnc[0]; - emm_data->imsi.u.num.digit5 = conf->mnc[1]; + emm_data->imsi.length = 8; + emm_data->imsi.u.num.parity = get_msin_parity(msin, conf->mcc, conf->mnc); + emm_data->imsi.u.num.digit1 = conf->mcc[0]; + emm_data->imsi.u.num.digit2 = conf->mcc[1]; + emm_data->imsi.u.num.digit3 = conf->mcc[2]; - if (strlen(conf->mnc) == 3) { - emm_data->rplmn.MNCdigit3 = conf->mnc[2]; + emm_data->imsi.u.num.digit4 = conf->mnc[0]; + emm_data->imsi.u.num.digit5 = conf->mnc[1]; - emm_data->imsi.u.num.digit6 = conf->mnc[2]; - emm_data->imsi.u.num.digit7 = msin[0]; - emm_data->imsi.u.num.digit8 = msin[1]; - emm_data->imsi.u.num.digit9 = msin[2]; - emm_data->imsi.u.num.digit10 = msin[3]; - emm_data->imsi.u.num.digit11 = msin[4]; - emm_data->imsi.u.num.digit12 = msin[5]; - emm_data->imsi.u.num.digit13 = msin[6]; - emm_data->imsi.u.num.digit14 = msin[7]; - emm_data->imsi.u.num.digit15 = msin[8]; + if (strlen(conf->mnc) == 3) { + emm_data->rplmn.MNCdigit3 = conf->mnc[2]; - } else { - emm_data->rplmn.MNCdigit3 = 0xf; + emm_data->imsi.u.num.digit6 = conf->mnc[2]; + emm_data->imsi.u.num.digit7 = msin[0]; + emm_data->imsi.u.num.digit8 = msin[1]; + emm_data->imsi.u.num.digit9 = msin[2]; + emm_data->imsi.u.num.digit10 = msin[3]; + emm_data->imsi.u.num.digit11 = msin[4]; + emm_data->imsi.u.num.digit12 = msin[5]; + emm_data->imsi.u.num.digit13 = msin[6]; + emm_data->imsi.u.num.digit14 = msin[7]; + emm_data->imsi.u.num.digit15 = msin[8]; + } else { + emm_data->rplmn.MNCdigit3 = 0xf; - emm_data->imsi.u.num.digit6 = msin[0]; - emm_data->imsi.u.num.digit7 = msin[1]; - emm_data->imsi.u.num.digit8 = msin[2]; - emm_data->imsi.u.num.digit9 = msin[3]; - emm_data->imsi.u.num.digit10 = msin[4]; - emm_data->imsi.u.num.digit11 = msin[5]; - emm_data->imsi.u.num.digit12 = msin[6]; - emm_data->imsi.u.num.digit13 = msin[7]; - emm_data->imsi.u.num.digit14 = msin[8]; - emm_data->imsi.u.num.digit15 = msin[9]; + emm_data->imsi.u.num.digit6 = msin[0]; + emm_data->imsi.u.num.digit7 = msin[1]; + emm_data->imsi.u.num.digit8 = msin[2]; + emm_data->imsi.u.num.digit9 = msin[3]; + emm_data->imsi.u.num.digit10 = msin[4]; + emm_data->imsi.u.num.digit11 = msin[5]; + emm_data->imsi.u.num.digit12 = msin[6]; + emm_data->imsi.u.num.digit13 = msin[7]; + emm_data->imsi.u.num.digit14 = msin[8]; + emm_data->imsi.u.num.digit15 = msin[9]; + } - } + emm_data->rplmn.MCCdigit1 = conf->mcc[0]; + emm_data->rplmn.MCCdigit2 = conf->mcc[1]; + emm_data->rplmn.MCCdigit3 = conf->mcc[2]; + emm_data->rplmn.MNCdigit1 = conf->mnc[0]; + emm_data->rplmn.MNCdigit2 = conf->mnc[1]; - emm_data->rplmn.MCCdigit1 = conf->mcc[0]; - emm_data->rplmn.MCCdigit2 = conf->mcc[1]; - emm_data->rplmn.MCCdigit3 = conf->mcc[2]; - emm_data->rplmn.MNCdigit1 = conf->mnc[0]; - emm_data->rplmn.MNCdigit2 = conf->mnc[1]; - - emm_data->eplmn.n_plmns = ehplmn_count; + emm_data->eplmn.n_plmns = eplmn->size; + for (i = 0; i < eplmn->size; i++) { + emm_data->eplmn.plmn[i] = networks.items[eplmn->items[i]].plmn; + } } bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) { diff --git a/openair3/NAS/TOOLS/conf_emm.h b/openair3/NAS/TOOLS/conf_emm.h index a7b97c5da2..f9c30d31c9 100644 --- a/openair3/NAS/TOOLS/conf_emm.h +++ b/openair3/NAS/TOOLS/conf_emm.h @@ -3,8 +3,15 @@ #include "emmData.h" #include "conf_network.h" +#include "conf_user_plmn.h" + +void gen_emm_data( + emm_nvdata_t *emm_data, + const char *hplmn, + const char *msin, + const plmns_list *eplmn, + const networks_t networks); -void gen_emm_data(emm_nvdata_t *emm_data, const char *hplmn, const char *msin, int ehplmn_count, const networks_t networks); bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data); int get_msin_parity(const char * msin, const char *mcc, const char *mnc); diff --git a/openair3/NAS/TOOLS/conf_parser.c b/openair3/NAS/TOOLS/conf_parser.c index e7d1240fad..d46142c461 100644 --- a/openair3/NAS/TOOLS/conf_parser.c +++ b/openair3/NAS/TOOLS/conf_parser.c @@ -74,7 +74,7 @@ bool parse_config_file(const char *output_dir, const char *conf_filename, int ou gen_usim_data(&usim_data_conf, &usim_data, &user_plmns, networks); gen_emm_data(&emm_data, usim_data_conf.hplmn, usim_data_conf.msin, - user_plmns.equivalents_home.size, networks); + &user_plmns.equivalents_home, networks); if ( output_flags & OUTPUT_UEDATA ) { write_user_data(output_dir, i, &user_data); From 358e6926ca5b5ec460970c8e87365ddba1dc6ecd Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 2 Feb 2017 18:18:16 +0100 Subject: [PATCH 239/571] initializing dlsch_SI and dlsch_RA in dlsim.c --- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index bf7f276ea0..af1b1a6aef 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2107,6 +2107,10 @@ int main(int argc, char **argv) UE->dlsch[0][i]->rnti = n_rnti; } + UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch_ra[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + + // structure for SIC at UE UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); From 883310d88d9ffc8a3db48774df427cac1721926d Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Fri, 3 Feb 2017 12:36:16 +0100 Subject: [PATCH 240/571] Adding standard test cases for dlsim_tm4. test case number is 015110. All the test pass. --- cmake_targets/autotests/README.txt | 13 ++++++++ cmake_targets/autotests/test_case_list.xml | 37 ++++++++++++++++++++++ cmake_targets/build_oai | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index 5841ed6dc2..8156e31bee 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -101,6 +101,19 @@ Obj.# Case# Test# Description 01 51 04 pdcchsim (TBD) 01 51 05 pbchsim (TBD) 01 51 06 mbmssim (TBD) +01 51 10 dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB), + (Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)), + (Test 6: 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)), + (Test 6b: 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (70%)), + (Test 7: 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (30%)), + (Test 7b: 5 MHz, R3-1.FDD (MCS 15), ETU70, 1.4 dB (30%)), + (Test 10: 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)), + (Test 10b: 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)), + (Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)) + (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), + (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), + + 01 55 lte-softmodem tests with USRP B210 RF as eNB and ALU EPC w/ Bandrich COTS UE for 1TX/1RX (TM1), 2TX/2RX (TM2) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 7f2847a5ea..c014b2a037 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -995,6 +995,43 @@ 3 + + execution + dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB), + (Test 5: 1.4 MHz, R4.FDD (MCS 4), EVA5, 0dB (70%)), + (Test 6, 10 MHz, R3.FDD (MCS 15), EVA5, 6.7dB (70%)), + (Test 6b, 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (70%)), + (Test 7, 5 MHz, R3-1.FDD (MCS 15), EVA5, 6.7dB (30%)), + (Test 7b, 5 MHz, R3-1.FDD (MCS 15), ETU70, 1.4 dB (30%)), + (Test 10, 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)), + (Test 10b, 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)), + (Test 11, 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)) + (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), + (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), + + + $OPENAIR_DIR/cmake_targets/build_oai + --phy_simulators -c + $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash + + $OPENAIR_DIR/cmake_targets/lte-simulators/build/dlsim_tm4 + -m5 -gF -s-1 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70 + -m4 -gF -s0 -w1.0 -f.2 -n500 -B6 -c4 -z2 -O70 + -m15 -gF -s6.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70 + -m14 -gF -s6.7 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O70 + -m15 -gG -s6.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O30 + -m14 -gG -s1.4 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O30 + -m25 -gF -s17.4 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O70 + -m25 -gF -s17.5 -w1.0 -f.2 -n500 -B25 -c3 -z2 -r1022 -O70 + -m26 -gF -s17.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70 + -m14 -gF -s6.8 -w1.0 -f.2 -n500 -B50 -c2 -x2 -y2 -z2 -O70 + -m13 -gF -s5.9 -w1.0 -f.2 -n500 -B25 -c3 -x2 -y2 -z2 -O70 + dlsim_tm4.test1 dlsim_tm4.test5 dlsim_tm4.test6 dlsim_tm4.test6b dlsim_tm4.test7 dlsim_tm4.test7b dlsim_tm4.test10 dlsim_tm4.test10b dlsim_tm4.test11 dlsim_tm4.TM2_test1 dlsim_tm4.TM2_test1b + "passed" + segmentation fault|assertion|exiting|fatal + 3 + + lte-softmodem diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 0a64c0a672..575f7fffb9 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -538,7 +538,7 @@ function main() { if [ "$SIMUS_PHY" = "1" ] ; then # lte unitary simulators compilation echo_info "Compiling unitary tests simulators" - simlist="dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" + simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim" for f in $simlist ; do compilations \ lte-simulators $f \ From 41a261266a8a288ff18da04838051ae78dd53135 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 3 Feb 2017 16:17:52 +0100 Subject: [PATCH 241/571] fixing some bugs --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 42 +++++++++++------------ openair1/PHY/LTE_TRANSPORT/pmch.c | 4 +-- openair1/PHY/LTE_TRANSPORT/proto.h | 4 +-- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index acad47f28f..8ec2a40d8d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -85,11 +85,11 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) #endif for (r=0; rharq_processes[i]->c[r]); #endif - + if (dlsch->harq_processes[i]->c[r]) { free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); dlsch->harq_processes[i]->c[r] = NULL; @@ -98,17 +98,17 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144))); dlsch->harq_processes[i]->d[r] = NULL; } - + } free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); dlsch->harq_processes[i] = NULL; } } - + free16(dlsch,sizeof(LTE_eNB_DLSCH_t)); dlsch = NULL; } - + } LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms) @@ -218,7 +218,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ if (dlsch->harq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = LTE_NULL; } - + } return(dlsch); @@ -257,7 +257,7 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) for (r=0; rharq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = LTE_NULL; - + } } } @@ -553,8 +553,8 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, return(0); } -int dlsch_encoding(unsigned char *a, - LTE_DL_FRAME_PARMS *frame_parms, +int dlsch_encoding(PHY_VARS_eNB *eNB, + unsigned char *a, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch, int frame, @@ -568,6 +568,7 @@ int dlsch_encoding(unsigned char *a, unsigned int crc=1; unsigned short iind; + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; unsigned char harq_pid = dlsch->current_harq_pid; unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; unsigned int A; @@ -602,7 +603,7 @@ int dlsch_encoding(unsigned char *a, printf("\n"); */ // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a, //input bits for computation, A is a size of a + crc = crc24a(a, A)>>8; a[A>>3] = ((uint8_t*)&crc)[2]; a[1+(A>>3)] = ((uint8_t*)&crc)[1]; @@ -613,15 +614,15 @@ int dlsch_encoding(unsigned char *a, // dlsch->harq_processes[harq_pid]->b = a; memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); - if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, // bits after CRC attachement - dlsch->harq_processes[harq_pid]->c, // output from segmentation - dlsch->harq_processes[harq_pid]->B, //size of B=L+A - &dlsch->harq_processes[harq_pid]->C, //number of codeblocks - &dlsch->harq_processes[harq_pid]->Cplus, //Number of segments of size K+ - &dlsch->harq_processes[harq_pid]->Cminus,//Number of segments of size K_ - &dlsch->harq_processes[harq_pid]->Kplus, //First segmentation size - &dlsch->harq_processes[harq_pid]->Kminus, //Second segmentation size - &dlsch->harq_processes[harq_pid]->F)<0) //Number of filler bits + if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, + dlsch->harq_processes[harq_pid]->c, + dlsch->harq_processes[harq_pid]->B, + &dlsch->harq_processes[harq_pid]->C, + &dlsch->harq_processes[harq_pid]->Cplus, + &dlsch->harq_processes[harq_pid]->Cminus, + &dlsch->harq_processes[harq_pid]->Kplus, + &dlsch->harq_processes[harq_pid]->Kminus, + &dlsch->harq_processes[harq_pid]->F)<0) return(-1); for (r=0; rharq_processes[harq_pid]->C; r++) { @@ -703,7 +704,7 @@ int dlsch_encoding(unsigned char *a, r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], G, //G dlsch->harq_processes[harq_pid]->w[r], - dlsch->harq_processes[harq_pid]->e+r_offset, // sequence of bits for transmission + dlsch->harq_processes[harq_pid]->e+r_offset, dlsch->harq_processes[harq_pid]->C, // C dlsch->Nsoft, // Nsoft, dlsch->Mdlharq, @@ -715,7 +716,6 @@ int dlsch_encoding(unsigned char *a, nb_rb, m); // r stop_meas(rm_stats); - //printf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx); #ifdef DEBUG_DLSCH_CODING if (r==dlsch->harq_processes[harq_pid]->C-1) diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c index 2973c5e1c9..1a2838e5cf 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch.c @@ -312,8 +312,8 @@ void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a) AMP); - if (dlsch_encoding(a, - &eNB->frame_parms, + if (dlsch_encoding(eNB, + a, 1, eNB->dlsch_MCH, proc->frame_tx, diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 01984ba8c7..44312747d8 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -111,8 +111,8 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag); @param i_stats Time statistics for interleaving @returns status */ -int32_t dlsch_encoding(uint8_t *a, - LTE_DL_FRAME_PARMS *frame_parms, +int32_t dlsch_encoding(PHY_VARS_eNB *eNB, + uint8_t *a, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch, int frame, From 79242aaf54e8240cd5d0f121f7f9e3f1fef2c3df Mon Sep 17 00:00:00 2001 From: fnabet Date: Fri, 3 Feb 2017 17:02:42 +0100 Subject: [PATCH 242/571] RLC AM Tx changes --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 122 +++++++++- .../LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h | 61 +++-- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h | 10 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c | 2 + .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 21 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c | 55 +++-- .../LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h | 4 +- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 210 +++++++++--------- .../LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h | 5 +- 9 files changed, 312 insertions(+), 178 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 23baae3714..3e88a31496 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -43,6 +43,109 @@ #include "DL-AM-RLC.h" +//----------------------------------------------------------------------------- +uint32_t +rlc_am_get_status_pdu_buffer_occupancy( + rlc_am_entity_t * const rlc_pP){ + + //Compute Max Status PDU size according to what has been received and not received in the window [vrR vrMS[ + + // minimum header size in bits to be transmitted: D/C + CPT + ACK_SN + E1 + uint32_t nb_bits_to_transmit = RLC_AM_PDU_D_C_BITS + RLC_AM_STATUS_PDU_CPT_LENGTH + RLC_AM_SN_BITS + RLC_AM_PDU_E_BITS; + mem_block_t *cursor_p = rlc_pP->receiver_buffer.head; + rlc_am_pdu_info_t *pdu_info_cursor_p = NULL; + int waited_so = 0; + + rlc_sn_t sn_cursor = rlc_pP->vr_r; + rlc_sn_t sn_prev = rlc_pP->vr_r; + rlc_sn_t sn_end = rlc_pP->vr_ms; + boolean_t segment_loop_end = false; + + + if (sn_prev != sn_end) + { + while ((RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(sn_end,rlc_pP->vr_r)) && (cursor_p != NULL)) + { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + sn_cursor = pdu_info_cursor_p->sn; + + // Add holes between sn_prev and sn_cursor + while ((sn_prev != sn_cursor) && (sn_prev != sn_end)) + { + /* Add 1 NACK_SN + E1 + E2 */ + nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)); + sn_prev = RLC_AM_NEXT_SN(sn_prev); + } //end while (sn_prev != sn_cursor) + + /* Handle case sn_cursor is partially received */ + /* Each gap will add NACK_SN + E1 + E2 + SOStart + SOEnd */ + if ((((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received == 0) && (RLC_AM_DIFF_SN(sn_cursor,rlc_pP->vr_r) < RLC_AM_DIFF_SN(sn_end,rlc_pP->vr_r))) + { + /* Check lsf */ + segment_loop_end = (pdu_info_cursor_p->lsf == 1); + + /* Fill for [0 SO[ if SO not null */ + if (pdu_info_cursor_p->so) { + nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); + waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size; + /* Go to next segment */ + cursor_p = cursor_p->next; + if (cursor_p != NULL) + { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + else { + waited_so = pdu_info_cursor_p->payload_size; + } + + /* Fill following gaps if any */ + while (!segment_loop_end) + { + if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) + { + /* Check lsf */ + segment_loop_end = (pdu_info_cursor_p->lsf == 1); + + if (waited_so < pdu_info_cursor_p->so) { + nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); + } + else { + /* contiguous segment: only update waited_so */ + /* Assuming so and payload_size updated according to duplication removal done at reception ... */ + waited_so += pdu_info_cursor_p->payload_size; + } + + /* Go to next received PDU or PDU Segment */ + cursor_p = cursor_p->next; + if (cursor_p != NULL) + { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + else + { + /* Fill last gap assuming LSF is not received */ + nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); + segment_loop_end = true; + } + } // end while (!segment_loop_end) + } // end if segments + else + { + /* Go to next received PDU or PDU Segment */ + cursor_p = cursor_p->next; + } + + sn_prev = RLC_AM_NEXT_SN(sn_cursor); + } + } // end if (sn_prev != sn_end) + + // round up to the greatest byte + return ((nb_bits_to_transmit + 7) >> 3); + +} + //----------------------------------------------------------------------------- uint32_t rlc_am_get_buffer_occupancy_in_bytes ( @@ -54,26 +157,24 @@ rlc_am_get_buffer_occupancy_in_bytes ( // priority of control trafic rlc_pP->status_buffer_occupancy = 0; - if (rlc_pP->status_requested) { - if (rlc_pP->t_status_prohibit.running == 0) { + if ((rlc_pP->status_requested) && !(rlc_pP->status_requested & RLC_AM_STATUS_NO_TX_MASK)) { + rlc_pP->status_buffer_occupancy = rlc_am_get_status_pdu_buffer_occupancy(rlc_pP); #if TRACE_RLC_AM_BO - if (((15 + rlc_pP->num_nack_sn*(10+1) + rlc_pP->num_nack_so*(15+15+1) + 7) >> 3) > 0) { - LOG_D(RLC, PROTOCOL_CTXT_FMT RB_AM_FMT" BO : CONTROL PDU %d bytes \n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - ((15 + rlc_pP->num_nack_sn*(10+1) + rlc_pP->num_nack_so*(15+15+1) + 7) >> 3)); - } + LOG_D(RLC, PROTOCOL_CTXT_FMT RB_AM_FMT" BO : CONTROL PDU %d bytes \n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + rlc_pP->status_buffer_occupancy); #endif - rlc_pP->status_buffer_occupancy = ((15 + rlc_pP->num_nack_sn*(10+1) + rlc_pP->num_nack_so*(15+15+1) + 7) >> 3); - } } // data traffic if (rlc_pP->nb_sdu_no_segmented <= 1) { max_li_overhead = 0; } else { - max_li_overhead = (((rlc_pP->nb_sdu_no_segmented - 1) * 3) / 2) + ((rlc_pP->nb_sdu_no_segmented - 1) % 2); + /* This computation assumes there is no SDU with size greater than 2047 bytes, otherwise a new PDU must be built except for LI15 configuration from Rel12*/ + uint32_t num_li = rlc_pP->nb_sdu_no_segmented - 1; + max_li_overhead = num_li + (num_li >> 1) + (num_li & 1); } if (rlc_pP->sdu_buffer_occupancy == 0) { @@ -372,6 +473,7 @@ rlc_am_get_pdus ( } }*/ // THEN TRY TO SEND RETRANS PDU + // BUG FIX : they can be PDU to ReTx due to received NACK or 1 PDU (SN = vtS - 1) to ReTx due TPoll Expiry if Buffer Occupancy is null if (rlc_pP->first_retrans_pdu_sn >= 0) { rlc_am_tx_data_pdu_management_t* tx_data_pdu_management; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h index 77bf31db86..a2fc95aba5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h @@ -72,10 +72,52 @@ # define RLC_AM_MAX_HOLES_REPORT_PER_PDU 16 /** @} */ +#define RLC_AM_POLL_PDU_INFINITE 0xFFFF +#define RLC_AM_POLL_BYTE_INFINITE 0xFFFFFFFF + +/* MACRO DEFINITIONS */ + +#define RLC_AM_NEXT_SN(sn) (((sn)+1) & ((RLC_AM_SN_MODULO)-1)) +#define RLC_AM_PREV_SN(sn) (((sn)+(RLC_AM_SN_MODULO)-1) & ((RLC_AM_SN_MODULO)-1)) + +#define RLC_DIFF_SN(sn,snref,modulus) ((sn+(modulus)-snref) & ((modulus)-1)) +#define RLC_SN_IN_WINDOW(sn,snref,modulus) ((RLC_DIFF_SN(sn,snref,modulus)) < ((modulus) >> 1)) + +#define RLC_AM_DIFF_SN(sn,snref) (RLC_DIFF_SN(sn,snref,RLC_AM_SN_MODULO)) +#define RLC_AM_SN_IN_WINDOW(sn,snref) (RLC_SN_IN_WINDOW(sn,snref,RLC_AM_SN_MODULO)) + +#define RLC_SET_BIT(x,offset) ((x) |= (1 << (offset))) +#define RLC_GET_BIT(x,offset) (((x) & (1 << (offset))) >> (offset)) +#define RLC_CLEAR_BIT(x,offset) ((x) &= ~(1 << (offset))) + +#define RLC_SET_EVENT(x,event) ((x) |= (event)) +#define RLC_GET_EVENT(x,event) ((x) & (event)) +#define RLC_CLEAR_EVENT(x,event) ((x) &= (~(event))) + /* Common to Data and Status PDU */ -#define RLC_AM_SN_BITS 10 -#define RLC_AM_PDU_D_C_BITS 1 -#define RLC_AM_PDU_E_BITS 1 +#define RLC_AM_SN_BITS 10 +#define RLC_AM_PDU_D_C_BITS 1 +#define RLC_AM_PDU_E_BITS 1 +#define RLC_AM_PDU_FI_BITS 2 +#define RLC_AM_PDU_POLL_BITS 1 +#define RLC_AM_PDU_RF_BITS 1 + + +#define EURL_AM_PDU_LSF_BITS 1 + + +/* AM Data PDU */ +#define RLC_AM_PDU_E_OFFSET 2 +#define RLC_AM_PDU_FI_OFFSET (RLC_AM_PDU_E_OFFSET + RLC_AM_PDU_E_BITS) +#define RLC_AM_PDU_POLL_OFFSET (RLC_AM_PDU_FI_OFFSET + RLC_AM_PDU_FI_BITS) +#define RLC_AM_PDU_RF_OFFSET (RLC_AM_PDU_POLL_OFFSET + RLC_AM_PDU_POLL_BITS) +#define RLC_AM_PDU_D_C_OFFSET (RLC_AM_PDU_RF_OFFSET + RLC_AM_PDU_RF_BITS) + +#define RLC_AM_PDU_SET_E(px) (RLC_SET_BIT((px),RLC_AM_PDU_E_OFFSET)) +#define RLC_AM_PDU_SET_D_C(px) (RLC_SET_BIT((px),RLC_AM_PDU_D_C_OFFSET)) +#define RLC_AM_PDU_SET_RF(px) (RLC_SET_BIT((px),RLC_AM_PDU_RF_OFFSET)) +#define RLC_AM_PDU_SET_POLL(px) (RLC_SET_BIT((px),RLC_AM_PDU_POLL_OFFSET)) +#define RLC_AM_PDU_CLEAR_POLL(px) (RLC_CLEAR_BIT((px),RLC_AM_PDU_POLL_OFFSET)) /* STATUS PDU */ #define RLC_AM_STATUS_PDU_CPT_STATUS 0 @@ -89,19 +131,6 @@ #define RLC_AM_STATUS_PDU_SO_END_ALL_BYTES 0x7FFF -/* MACRO DEFINITIONS */ -#define RLC_AM_NEXT_SN(sn) (((sn)+1) & ((RLC_AM_SN_MODULO)-1)) -#define RLC_AM_PREV_SN(sn) (((sn)+(RLC_AM_SN_MODULO)-1) & ((RLC_AM_SN_MODULO)-1)) - -#define RLC_DIFF_SN(sn,snref,modulus) ((sn+(modulus)-snref) & ((modulus)-1)) -#define RLC_SN_IN_WINDOW(sn,snref,modulus) ((RLC_DIFF_SN(sn,snref,modulus)) < ((modulus) >> 1)) - -#define RLC_AM_DIFF_SN(sn,snref) (RLC_DIFF_SN(sn,snref,RLC_AM_SN_MODULO)) -#define RLC_AM_SN_IN_WINDOW(sn,snref) (RLC_SN_IN_WINDOW(sn,snref,RLC_AM_SN_MODULO)) - -#define RLC_SET_EVENT(x,event) ((x) |= (event)) -#define RLC_GET_EVENT(x,event) ((x) & (event)) -#define RLC_CLEAR_EVENT(x,event) ((x) &= (~(event))) /* Uplink STATUS PDU trigger events */ #define RLC_AM_STATUS_NOT_TRIGGERED 0 diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h index 581c4969e0..45d0a5d489 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h @@ -69,17 +69,15 @@ typedef struct rlc_am_entity_s { pthread_mutex_t lock_input_sdus; rlc_am_tx_sdu_management_t *input_sdus; /*!< \brief Input SDU buffer (for SDUs coming from upper layers). */ signed int nb_sdu; /*!< \brief Total number of valid rlc_am_tx_sdu_management_t in input_sdus[]. */ - signed int nb_sdu_no_segmented; /*!< \brief Total number of SDUs not segmented and partially segmented. */ + signed int nb_sdu_no_segmented; /*!< \brief Total number of SDUs not segmented and partially segmented. nb_sdu_no_segmented = next_sdu_index - current_sdu_index */ signed int next_sdu_index; /*!< \brief Next SDU index in input_sdus array where for a new incoming SDU. */ - signed int current_sdu_index; /*!< \brief Current SDU index in input_sdus array to be segmented. */ + signed int current_sdu_index; /*!< \brief Current SDU index in input_sdus array to be segmented which is not segmented or partially segmented. */ rlc_am_tx_data_pdu_management_t *pdu_retrans_buffer; /*!< \brief Retransmission buffer. */ signed int retrans_num_pdus; /*!< \brief Number of PDUs in the retransmission buffer. */ signed int retrans_num_bytes; /*!< \brief Number of bytes in the retransmission buffer. */ signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. */ - unsigned int num_nack_so; /*!< \brief Number of segment offsets asked to be retransmitted by peer RLC entity. */ - unsigned int num_nack_sn; /*!< \brief Number of segment asked to be retransmitted by peer RLC entity. */ boolean_t force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ //--------------------------------------------------------------------- @@ -137,7 +135,7 @@ typedef struct rlc_am_entity_s { //----------------------------- uint16_t max_retx_threshold; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to limit the number of retransmissions of an AMD PDU. */ uint16_t poll_pdu; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollPDU PDUs. */ - uint16_t poll_byte; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollByte bytes. */ + uint32_t poll_byte; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollByte bytes. */ //--------------------------------------------------------------------- // STATISTICS @@ -176,7 +174,7 @@ typedef struct rlc_am_entity_s { //--------------------------------------------------------------------- // OUTPUTS //--------------------------------------------------------------------- - sdu_size_t nb_bytes_requested_by_mac; /*!< \brief Number of bytes requested by lower layer for next transmission. */ + sdu_size_t nb_bytes_requested_by_mac; /*!< \brief Number of remaining bytes available for transmission of any RLC PDU indicated by lower layer */ list_t pdus_to_mac_layer; /*!< \brief PDUs buffered for transmission to MAC layer. */ list_t control_pdu_list; /*!< \brief Control PDUs buffered for transmission to MAC layer. */ rlc_sn_t first_retrans_pdu_sn; /*!< \brief Lowest sequence number of PDU to be retransmitted. */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c index 0f0b0e75e1..4122fd0e66 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c @@ -56,6 +56,8 @@ void rlc_am_free_in_sdu( rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; } + // TODO : this loop is useless as UL SDUs are transmitted and acknowledged in sequence + // even with PDCP UL SDU discard functionality while ((rlcP->current_sdu_index != rlcP->next_sdu_index) && (rlcP->input_sdus[rlcP->current_sdu_index].flags.transmitted_successfully == 1)) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 7fb801b33d..a52c9bee33 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -55,7 +55,6 @@ void rlc_am_nack_pdu ( int sdu_index; if (mb_p != NULL) { - rlc_pP->num_nack_sn += 1; assert(so_startP <= so_endP); //----------------------------------------- @@ -69,10 +68,6 @@ void rlc_am_nack_pdu ( rlc_am_clear_holes(ctxt_pP, rlc_pP, snP); } - if (!((so_startP == 0) && (so_endP == 0x7FFF))) { - rlc_pP->num_nack_so += 1; - } - rlc_am_add_hole(ctxt_pP, rlc_pP, snP, so_startP, so_endP); if (rlc_pP->first_retrans_pdu_sn < 0) { @@ -283,7 +278,7 @@ mem_block_t* rlc_am_retransmit_get_copy ( pdu_mngt->flags.retransmit = 0; - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_p, pdu_mngt->payload_size); + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_p, pdu_mngt->payload_size,false); return mb_copy; } else { return NULL; @@ -745,7 +740,7 @@ mem_block_t* rlc_am_retransmit_get_subsegment( return NULL; } - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sub_segment_p, test_pdu_copy_size); + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sub_segment_p, test_pdu_copy_size,false); return mb_sub_segment_p; } else { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] RE-SEND DATA PDU SN %04d BUT NO PDU AVAILABLE -> RETURN NULL\n", @@ -843,10 +838,12 @@ void rlc_am_retransmit_any_pdu( // no need for update rlc_pP->nb_bytes_requested_by_mac pdu_p = rlc_am_retransmit_get_copy(ctxt_pP, rlc_pP, sn); pdu_sn_10_p = (rlc_am_pdu_sn_10_t*) (&pdu_p->data[sizeof(struct mac_tb_req)]); - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->pdu_retrans_buffer[sn].header_and_payload_size); - pdu_sn_10_p->b1 = pdu_sn_10_p->b1 | 0x20; - rlc_pP->c_pdu_without_poll = 0; - rlc_pP->c_byte_without_poll = 0; + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->pdu_retrans_buffer[sn].header_and_payload_size,false); + //BugFix: polling is checked and done in function above ! + //pdu_sn_10_p->b1 = pdu_sn_10_p->b1 | 0x20; + //BugFix : pdu_without_poll and byte_without_poll are reset only if a Poll is transmitted + //rlc_pP->c_pdu_without_poll = 0; + //rlc_pP->c_byte_without_poll = 0; //rlc_pP->poll_sn = (rlc_pP->vt_s -1) & RLC_AM_SN_MASK; rlc_am_start_timer_poll_retransmit(ctxt_pP, rlc_pP); rlc_pP->stat_tx_data_pdu += 1; @@ -877,7 +874,7 @@ void rlc_am_retransmit_any_pdu( rlc_am_nack_pdu (ctxt_pP, rlc_pP, found_pdu_sn, 0, 0x7FFF); pdu_p = rlc_am_retransmit_get_subsegment(ctxt_pP, rlc_pP, found_pdu_sn, &rlc_pP->nb_bytes_requested_by_mac); pdu_sn_10_p = (rlc_am_pdu_sn_10_t*) (&pdu_p->data[sizeof(struct mac_tb_req)]); - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->pdu_retrans_buffer[found_pdu_sn].header_and_payload_size); + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->pdu_retrans_buffer[found_pdu_sn].header_and_payload_size,false); pdu_sn_10_p->b1 = pdu_sn_10_p->b1 | 0x20; rlc_pP->c_pdu_without_poll = 0; rlc_pP->c_byte_without_poll = 0; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index 893588d65e..af4f67f303 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -39,7 +39,8 @@ void rlc_am_pdu_polling ( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlc_pP, rlc_am_pdu_sn_10_t *const pdu_pP, - const int16_t payload_sizeP) + const int16_t payload_sizeP, + boolean_t is_new_pdu) { // 5.2.2 Polling // An AM RLC entity can poll its peer AM RLC entity in order to trigger STATUS reporting at the peer AM RLC entity. @@ -68,41 +69,50 @@ void rlc_am_pdu_polling ( // - start t-PollRetransmit; // - else: // - restart t-PollRetransmit; - rlc_pP->c_pdu_without_poll += 1; - rlc_pP->c_byte_without_poll += payload_sizeP; + + if (is_new_pdu) { + if (rlc_pP->poll_pdu != RLC_AM_POLL_PDU_INFINITE) { + rlc_pP->c_pdu_without_poll += 1; + } + + if (rlc_pP->poll_byte != RLC_AM_POLL_BYTE_INFINITE) { + rlc_pP->c_byte_without_poll += payload_sizeP; + } + } if ( - (rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu) || - (rlc_pP->c_byte_without_poll >= rlc_pP->poll_byte) || + ((is_new_pdu) && ((rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu) || + (rlc_pP->c_byte_without_poll >= rlc_pP->poll_byte))) || ((rlc_pP->sdu_buffer_occupancy == 0) && (rlc_pP->retrans_num_bytes_to_retransmit == 0)) || (rlc_pP->vt_s == rlc_pP->vt_ms) || - (rlc_pP->force_poll == TRUE) + (rlc_pP->force_poll == true) ) { - rlc_pP->force_poll = FALSE; + rlc_pP->force_poll = false; - if (rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu) { + if ((is_new_pdu) && (rlc_pP->c_pdu_without_poll >= rlc_pP->poll_pdu)) { LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE TX NUM PDU THRESHOLD %d HAS BEEN REACHED\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->poll_pdu); - } else - if (rlc_pP->c_byte_without_poll >= rlc_pP->poll_byte) { + } + if ((is_new_pdu) && (rlc_pP->c_byte_without_poll >= rlc_pP->poll_byte)) { LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE TX NUM BYTES THRESHOLD %d HAS BEEN REACHED\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->poll_byte); - } else + } if ((rlc_pP->sdu_buffer_occupancy == 0) && (rlc_pP->retrans_num_bytes_to_retransmit == 0)) { LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE TX BUFFERS ARE EMPTY\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); - } else + } if (rlc_pP->vt_s == rlc_pP->vt_ms) { LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[POLL] SET POLL BECAUSE OF WINDOW STALLING\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); } - pdu_pP->b1 = pdu_pP->b1 | 0x20; + RLC_AM_PDU_SET_POLL(pdu_pP->b1); rlc_pP->c_pdu_without_poll = 0; rlc_pP->c_byte_without_poll = 0; + // vt_s shall have been updated before in case of new transmission rlc_pP->poll_sn = (rlc_pP->vt_s -1) & RLC_AM_SN_MASK; //optimisation if (!rlc_pP->t_poll_retransmit.running) { rlc_am_start_timer_poll_retransmit(ctxt_pP, rlc_pP); @@ -110,7 +120,8 @@ void rlc_am_pdu_polling ( //optimisation rlc_pP->t_poll_retransmit.frame_time_out = ctxt_pP->frame + rlc_pP->t_poll_retransmit.time_out; //optimisation } } else { - pdu_pP->b1 = pdu_pP->b1 & 0xDF; + // Not sure this is necessary + RLC_AM_PDU_CLEAR_POLL(pdu_pP->b1); } } //----------------------------------------------------------------------------- @@ -178,7 +189,9 @@ void rlc_am_segment_10 ( if (rlc_pP->nb_sdu_no_segmented <= 1) { max_li_overhead = 0; } else { - max_li_overhead = (((rlc_pP->nb_sdu_no_segmented - 1) * 3) / 2) + ((rlc_pP->nb_sdu_no_segmented - 1) % 2); + /* This computation assumes there is no SDU with size greater than 2047 bytes, otherwise a new PDU must be built except for LI15 configuration from Rel12*/ + test_num_li = rlc_pP->nb_sdu_no_segmented - 1; + max_li_overhead = test_num_li + (test_num_li >> 1) + (test_num_li & 1); } LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] max_li_overhead %d\n", @@ -485,11 +498,11 @@ void rlc_am_segment_10 ( fi = fi + 1; } - pdu_p->b1 = pdu_p->b1 | (fi << 3); + pdu_p->b1 = pdu_p->b1 | (fi << RLC_AM_PDU_FI_OFFSET); // set fist e bit if (fill_num_li > 0) { - pdu_p->b1 = pdu_p->b1 | 0x04; + RLC_AM_PDU_SET_E(pdu_p->b1); } LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] SEND PDU SN %04d SIZE %d BYTES PAYLOAD SIZE %d BYTES\n", @@ -501,8 +514,9 @@ void rlc_am_segment_10 ( rlc_pP->stat_tx_data_pdu += 1; rlc_pP->stat_tx_data_bytes += (data_pdu_size - pdu_remaining_size); - //pdu_p->sn = rlc_pP->vt_s; - pdu_p->b1 = pdu_p->b1 | 0x80; // DATA/CONTROL field is DATA PDU + // set DATA/CONTROL field is DATA PDU(1) + RLC_AM_PDU_SET_D_C(pdu_p->b1); + // set sn = rlc_pP->vt_s; pdu_p->b1 = pdu_p->b1 | (rlc_pP->vt_s >> 8); pdu_p->b2 = rlc_pP->vt_s & 0xFF; rlc_pP->vt_s = (rlc_pP->vt_s+1) & RLC_AM_SN_MASK; @@ -511,13 +525,14 @@ void rlc_am_segment_10 ( pdu_tb_req_p->tb_size = data_pdu_size - pdu_remaining_size; //#warning "why 3000: changed to RLC_SDU_MAX_SIZE " assert(pdu_tb_req_p->tb_size < RLC_SDU_MAX_SIZE ); - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_p, pdu_mngt_p->payload_size); + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_p, pdu_mngt_p->payload_size,true); //list_add_tail_eurecom (pdu_mem_p, &rlc_pP->segmentation_pdu_list); pdu_mngt_p->mem_block = pdu_mem_p; pdu_mngt_p->first_byte = (unsigned char*)pdu_p; pdu_mngt_p->header_and_payload_size = data_pdu_size - pdu_remaining_size; pdu_mngt_p->retx_count = -1; + pdu_mngt_p->flags.transmitted = 1; rlc_pP->retrans_num_pdus += 1; rlc_pP->retrans_num_bytes += pdu_mngt_p->header_and_payload_size; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h index 6b67758b80..b52b3e5aaa 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h @@ -51,14 +51,14 @@ # endif # endif -/*! \fn void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP) +/*! \fn void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP,boolean_t is_new_pdu) * \brief Set or not the poll bit in the PDU header depending on RLC AM protocol variables. * \param[in] ctxt_pP Running context. * \param[in] rlcP RLC AM protocol instance pointer. * \param[in] pduP Pointer on the header of the PDU in order to be able to set the poll bit if necessary. * \param[in] payload_sizeP Size of the payload of the PDU. */ -protected_rlc_am_segment(void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP);) +protected_rlc_am_segment(void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP,boolean_t is_new_pdu);) /*! \fn void rlc_am_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlcP) * \brief Segment a PDU with 10 bits sequence number, based on segmentation information given by MAC (size to transmit). diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 4cc987d301..6495c722df 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -309,8 +309,6 @@ rlc_am_receive_process_control_pdu( assert(rlc_pP->control_pdu_info.num_nack < RLC_AM_MAX_NACK_IN_STATUS_PDU); if (rlc_am_in_tx_window(ctxt_pP, rlc_pP, ack_sn) > 0) { - rlc_pP->num_nack_so = 0; - rlc_pP->num_nack_sn = 0; if (rlc_pP->control_pdu_info.num_nack == 0) { while (sn_cursor != ack_sn) { @@ -462,7 +460,6 @@ rlc_am_send_status_pdu( mem_block_t *tb_p = NULL; sdu_size_t pdu_size = 0; boolean_t status_report_completed = false; - boolean_t lsf_received = false; boolean_t segment_loop_end = false; memset(&control_pdu_info, 0, sizeof(rlc_am_control_pdu_info_t)); @@ -479,30 +476,20 @@ rlc_am_send_status_pdu( control_pdu_info.ack_sn = rlc_pP->vr_ms; status_report_completed = true; +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d ALL ACK WITH ACK_SN %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + rlc_pP->vr_ms); +#endif } - else if (cursor_p != NULL) { + else if ((cursor_p != NULL) && ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)) <= nb_bits_to_transmit)) { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; sn_cursor = pdu_info_cursor_p->sn; - // Not very clear why this is needed - // commenting -#if 0 - while (!(RLC_AM_SN_IN_WINDOW(sn_cursor, rlc_pP->vr_r))) { - cursor_p = cursor_p->next; - previous_sn_cursor = sn_cursor; - - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - sn_cursor = pdu_info_cursor_p->sn; -#if TRACE_RLC_AM_STATUS_CREATION - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d FIND VR(R) <= SN sn_cursor %04d -> %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - __LINE__, - previous_sn_cursor, - sn_cursor); -#endif - } -#endif + /* Set E1 bit for the presence of first NACK_SN/E1/E2 */ + control_pdu_info.e1 = 1; // 12 bits = size of NACK_SN field + E1, E2 bits // 42 bits = size of NACK_SN field + SO_START, SO_END fields, E1, E2 bits @@ -512,20 +499,17 @@ rlc_am_send_status_pdu( pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; sn_cursor = pdu_info_cursor_p->sn; all_segments_received = ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received; - // E1 bit is set at the end /* First fill NACK_SN with each missing PDU between current sn_nack and sn_cursor */ while ((sn_nack != sn_cursor) && (sn_nack != rlc_pP->vr_ms)) { if (nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) <= nb_bits_to_transmit) { /* Fill NACK_SN infos */ - if (control_pdu_info.num_nack) { - /* Set E1 of previous NACK_SN */ - control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; - } control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_nack; control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0; control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES; control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 0; + /* Set E1 for next NACK_SN. The last one will be cleared */ + control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; control_pdu_info.num_nack += 1; nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)); #if TRACE_RLC_AM_STATUS_CREATION @@ -541,45 +525,52 @@ rlc_am_send_status_pdu( /* latest value of sn_nack shall be used as ACK_SN */ control_pdu_info.ack_sn = sn_nack; status_report_completed = true; +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d NOT ENOUGH TBS STOP WITH ACK_SN %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + sn_nack); +#endif break; } } /* Now process all Segments of sn_cursor if PDU not fully received */ - if ((!status_report_completed) && (all_segments_received == 0) && (sn_nack != rlc_pP->vr_ms)) { + if ((!status_report_completed) && (all_segments_received == 0) && (sn_cursor != rlc_pP->vr_ms)) { AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id); /* First ensure there is enough TBS for at least 1 SOStart/SOEnd, else break */ if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { - /* Set E1 of previous NACK_SN */ - if (control_pdu_info.num_nack) { - control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; - } /* Init loop flags */ - lsf_received = false; - segment_loop_end = false; + /* Check lsf */ + segment_loop_end = (pdu_info_cursor_p->lsf == 1); /* Init first SO Start according to first segment */ if (pdu_info_cursor_p->so) { - waited_so = 0; /* Fill the first SO */ control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = 0; control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so - 1; control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; + /* Set E1 for next NACK_SN. The last one will be cleared */ + control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; control_pdu_info.num_nack += 1; nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); #if TRACE_RLC_AM_STATUS_CREATION LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d SO START %05d SO END %05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), __LINE__, - previous_sn_cursor, - waited_so, - 0x7FFF); + sn_cursor, + 0, + pdu_info_cursor_p->so - 1); #endif waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size; /* Go to next segment */ cursor_p = cursor_p->next; + if (cursor_p != NULL) + { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } } else { waited_so = pdu_info_cursor_p->payload_size; @@ -587,79 +578,73 @@ rlc_am_send_status_pdu( /* Find the first discontinuity and then fill SOStart/SOEnd */ while (!segment_loop_end) { - if (cursor_p != NULL) { + if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + /* PDU segment is for the same SN*/ + /* Check lsf */ + segment_loop_end = (pdu_info_cursor_p->lsf == 1); - if (pdu_info_cursor_p->sn == sn_cursor) { - /* PDU segment is for the same SN*/ - if (waited_so < pdu_info_cursor_p->so) { - /* SO is greater than previous received portion : gap identified to fill */ - if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { - /* Set E1 of previous NACK_SN */ - if (control_pdu_info.num_nack) { - control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; - } + if (waited_so < pdu_info_cursor_p->so) { + /* SO is greater than previous received portion : gap identified to fill */ + if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { + control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so; + control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; + /* Set E1 for next NACK_SN. The last one will be cleared */ + control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; + control_pdu_info.num_nack += 1; + nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d SO START %05d SO END %05d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + sn_cursor, + waited_so, + pdu_info_cursor_p->so); +#endif + } + else { + /* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */ + control_pdu_info.ack_sn = sn_cursor; + status_report_completed = true; + segment_loop_end = true; + break; + } + } + else { + /* contiguous segment: only update waited_so */ + /* Assuming so and payload_size updated according to duplication removal done at reception ... */ + waited_so += pdu_info_cursor_p->payload_size; + } - control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; - control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; - control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so; - control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; - control_pdu_info.num_nack += 1; - nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); - } - else { - /* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */ - control_pdu_info.ack_sn = sn_cursor; - status_report_completed = true; - segment_loop_end = true; - break; - } + /* Go to next received PDU or PDU Segment */ + cursor_p = cursor_p->next; + if (cursor_p != NULL) + { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } - } - else { - /* Assuming so and payload_size updated according to duplication removal done at reception ... */ - waited_so += pdu_info_cursor_p->payload_size; - } - - } //end if (pdu_info_cursor_p->sn == sn_cursor) - else if (!lsf_received) { - /* We just switched to next SN, fill last gap if not end received */ - if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { - /* Set E1 of previously received NACK */ - control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; - control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; - control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; - control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES; - control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; - control_pdu_info.num_nack += 1; - nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); - } - else { - /* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */ - control_pdu_info.ack_sn = sn_cursor; - status_report_completed = true; - } - - segment_loop_end = true; - continue; //in order not to go to next cursor - } // end if (!lsf_received) - - /* Go to next received PDU or PDU Segment */ - cursor_p = cursor_p->next; - - } //end if (cursor_p != NULL) - else if (!lsf_received) { - /* Previous PDU segment was the last one and had lsf indication : fill the latest gap */ + } //end if (cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor) + else { + /* Previous PDU segment was the last one and did not have lsf indication : fill the latest gap */ if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { - /* Set E1 of previously received NACK */ - control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 1; control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = RLC_AM_STATUS_PDU_SO_END_ALL_BYTES; control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; + /* Set E1 for next NACK_SN. The last one will be cleared */ + control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; control_pdu_info.num_nack += 1; nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); +#if TRACE_RLC_AM_STATUS_CREATION + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING LAST NACK %04d SO START %05d SO END %05d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + sn_cursor, + waited_so, + RLC_AM_STATUS_PDU_SO_END_ALL_BYTES); +#endif } else { /* Not enough resources to set a SOStart/SEnd, then set ACK_SN to current NACK_SN and stop Status PDU build */ @@ -677,16 +662,23 @@ rlc_am_send_status_pdu( control_pdu_info.ack_sn = sn_nack; status_report_completed = true; } - } - - /* Increment sn_nack except if sn_nack = vrMS and if current SN was not fully received */ - if ((sn_nack != rlc_pP->vr_ms) && (all_segments_received)) { - sn_nack = RLC_AM_NEXT_SN(sn_nack); + } // end while on all PDU segments of sn_cursor + else { + /* Go to next received PDU or PDU segment if sn_cursor is fully received */ cursor_p = cursor_p->next; } + /* Increment sn_nack except if sn_nack = vrMS and if current SN was not fully received */ + if (sn_nack != rlc_pP->vr_ms) { + sn_nack = RLC_AM_NEXT_SN(sn_cursor); + } - } + + } // End main while NACK_SN + + /* Clear E1 of last nack_sn entry */ + AssertFatal (control_pdu_info.num_nack, "RLC AM Tx Status PDU Data Error no NACK_SN LcId=%d\n",rlc_pP->channel_id); + control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0; /* Set ACK_SN unless it was set before */ if (!status_report_completed){ @@ -694,12 +686,8 @@ rlc_am_send_status_pdu( control_pdu_info.ack_sn = sn_nack; } - if (control_pdu_info.num_nack) { - control_pdu_info.e1 = 1; - } - - } else { + /* reception buffer empty or not enough TBS for filling at least 1 NACK_SN + E1 + E2 */ control_pdu_info.ack_sn = rlc_pP->vr_r; #if TRACE_RLC_AM_STATUS_CREATION LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING ACK %04d = VR(R)\n", diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h index 4892090716..5ca98c88be 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h @@ -88,9 +88,12 @@ typedef struct rlc_am_tx_sdu_management { * \brief Structure containing PDU variables related to its retransmission. */ typedef struct pdu_management_flags { + uint8_t transmitted:1; /*!< \brief Boolean telling that this PDU is not empty and has been at least transmitted once. */ uint8_t ack:1; /*!< \brief Boolean telling that this PDU has been acknowledged. */ + uint8_t nack:1; /*!< \brief Boolean telling that this PDU has been acknowledged negatively. */ uint8_t retransmit:1; /*!< \brief Boolean telling a retransmission is scheduled for this PDU. */ - uint8_t dummy:6; /*!< \brief Free bits. */ + uint8_t max_retransmit:1; /*!< \brief Boolean telling max retransmission has been hit for this PDU. */ + uint8_t dummy:3; /*!< \brief Free bits. */ } pdu_management_flags_t; From 0cd250bc507e4ebbc69cda6f1f95d3fe73d5a344 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Mon, 6 Feb 2017 14:55:21 +0100 Subject: [PATCH 243/571] 1. Fixing remaining bugs form merge. Both simulators pass all the test. 2. Adding dlsch_encoding_SIC, where the fisrt argument is UE structure. 3. Adding general test cases for dlsim_tm4 simulator. 015110. --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 214 ++++++++++++++++++++-- openair1/PHY/LTE_TRANSPORT/proto.h | 12 ++ openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 11 +- 3 files changed, 215 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 8ec2a40d8d..b9f421204e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -85,11 +85,11 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) #endif for (r=0; rharq_processes[i]->c[r]); #endif - + if (dlsch->harq_processes[i]->c[r]) { free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); dlsch->harq_processes[i]->c[r] = NULL; @@ -98,17 +98,17 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144))); dlsch->harq_processes[i]->d[r] = NULL; } - + } free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); dlsch->harq_processes[i] = NULL; } } - + free16(dlsch,sizeof(LTE_eNB_DLSCH_t)); dlsch = NULL; } - + } LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms) @@ -148,7 +148,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ for (layer=0; layer<4; layer++) { dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*)); - + for (aa=0; aanb_antennas_tx; aa++) { dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); for (re=0;recalib_dl_ch_estimates = (int32_t**)malloc16(frame_parms->nb_antennas_tx*sizeof(int32_t*)); for (aa=0; aanb_antennas_tx; aa++) { dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); - + } for (i=0; i<10; i++) @@ -207,7 +207,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ exit_flag=3; } } - + if (exit_flag==0) { for (i=0; iharq_processes[i]->round=0; @@ -218,7 +218,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ if (dlsch->harq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = LTE_NULL; } - + } return(dlsch); @@ -257,7 +257,7 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) for (r=0; rharq_processes[i]->d[r]) dlsch->harq_processes[i]->d[r][j] = LTE_NULL; - + } } } @@ -352,7 +352,7 @@ void *te_thread(void *param) { while (!oai_exit) { - if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break; + if (wait_on_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread")<0) break; dlsch_encoding_2threads0((te_params*)param); @@ -432,14 +432,14 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, return(-1); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); ++proc->instance_cnt_te; proc->tep.eNB = eNB; proc->tep.dlsch = dlsch; proc->tep.G = G; - // wakeup worker to do second half segments + // wakeup worker to do second half segments if (pthread_cond_signal(&proc->cond_te) != 0) { printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); @@ -497,8 +497,8 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, proc->tep.eNB = eNB; proc->tep.dlsch = dlsch; proc->tep.G = G; - - // wakeup worker to do second half segments + + // wakeup worker to do second half segments if (pthread_cond_signal(&proc->cond_te) != 0) { printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); @@ -545,9 +545,9 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, // wait for worker to finish - wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread"); + wait_on_busy_condition(&proc->mutex_te,&proc->cond_te,&proc->instance_cnt_te,"te thread"); + - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); return(0); @@ -729,6 +729,186 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, return(0); } + +int dlsch_encoding_SIC(PHY_VARS_UE *ue, + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats) +{ + + unsigned int G; + unsigned int crc=1; + unsigned short iind; + + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + unsigned char harq_pid = dlsch->current_harq_pid; + unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; + unsigned int A; + unsigned char mod_order; + unsigned int Kr=0,Kr_bytes,r,r_offset=0; + unsigned short m=dlsch->harq_processes[harq_pid]->mcs; + uint8_t beamforming_mode=0; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); + + A = dlsch->harq_processes[harq_pid]->TBS; //6228 + // printf("Encoder: A: %d\n",A); + mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs); + + if(dlsch->harq_processes[harq_pid]->mimo_mode == TM7) + beamforming_mode = 7; + else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM8) + beamforming_mode = 8; + else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10) + beamforming_mode = 9; + G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode); + + + // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet + if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet + + /* + int i; + printf("dlsch (tx): \n"); + for (i=0;i<(A>>3);i++) + printf("%02x.",a[i]); + printf("\n"); + */ + // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a, + A)>>8; + a[A>>3] = ((uint8_t*)&crc)[2]; + a[1+(A>>3)] = ((uint8_t*)&crc)[1]; + a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + // printf("CRC %x (A %d)\n",crc,A); + + dlsch->harq_processes[harq_pid]->B = A+24; + // dlsch->harq_processes[harq_pid]->b = a; + memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); + + if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, + dlsch->harq_processes[harq_pid]->c, + dlsch->harq_processes[harq_pid]->B, + &dlsch->harq_processes[harq_pid]->C, + &dlsch->harq_processes[harq_pid]->Cplus, + &dlsch->harq_processes[harq_pid]->Cminus, + &dlsch->harq_processes[harq_pid]->Kplus, + &dlsch->harq_processes[harq_pid]->Kminus, + &dlsch->harq_processes[harq_pid]->F)<0) + return(-1); + + for (r=0; rharq_processes[harq_pid]->C; r++) { + + if (rharq_processes[harq_pid]->Cminus) + Kr = dlsch->harq_processes[harq_pid]->Kminus; + else + Kr = dlsch->harq_processes[harq_pid]->Kplus; + + Kr_bytes = Kr>>3; + + // get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14) + if (Kr_bytes<=64) + iind = (Kr_bytes-5); + else if (Kr_bytes <=128) + iind = 59 + ((Kr_bytes-64)>>1); + else if (Kr_bytes <= 256) + iind = 91 + ((Kr_bytes-128)>>2); + else if (Kr_bytes <= 768) + iind = 123 + ((Kr_bytes-256)>>3); + else { + printf("dlsch_coding: Illegal codeword size %d!!!\n",Kr_bytes); + return(-1); + } + + +#ifdef DEBUG_DLSCH_CODING + printf("Generating Code Segment %d (%d bits)\n",r,Kr); + // generate codewords + + printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A); + printf("N_RB = %d\n",nb_rb); + printf("Ncp %d\n",frame_parms->Ncp); + printf("mod_order %d\n",mod_order); +#endif + + +#ifdef DEBUG_DLSCH_CODING + printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); +#endif + start_meas(te_stats); + threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); + stop_meas(te_stats); +#ifdef DEBUG_DLSCH_CODING + + if (r==0) + write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4); + +#endif + start_meas(i_stats); + dlsch->harq_processes[harq_pid]->RTC[r] = + sub_block_interleaving_turbo(4+(Kr_bytes*8), + &dlsch->harq_processes[harq_pid]->d[r][96], + dlsch->harq_processes[harq_pid]->w[r]); + stop_meas(i_stats); + } + + } + + // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the + // outputs for each code segment, see Section 5.1.5 p.20 + + for (r=0; rharq_processes[harq_pid]->C; r++) { +#ifdef DEBUG_DLSCH_CODING + printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", + r, + G, + Kr*3, + mod_order,nb_rb); +#endif + + start_meas(rm_stats); + r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], + G, //G + dlsch->harq_processes[harq_pid]->w[r], + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->C, // C + dlsch->Nsoft, // Nsoft, + dlsch->Mdlharq, + dlsch->Kmimo, + dlsch->harq_processes[harq_pid]->rvidx, + get_Qm(dlsch->harq_processes[harq_pid]->mcs), + dlsch->harq_processes[harq_pid]->Nl, + r, + nb_rb, + m); // r + stop_meas(rm_stats); +#ifdef DEBUG_DLSCH_CODING + + if (r==dlsch->harq_processes[harq_pid]->C-1) + write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->e,r_offset,1,4); + +#endif + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); + + return(0); +} + + + + #ifdef PHY_ABSTRACTION void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB, uint8_t *DLSCH_pdu, diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 44312747d8..2395f477f9 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -121,6 +121,18 @@ int32_t dlsch_encoding(PHY_VARS_eNB *eNB, time_stats_t *te_stats, time_stats_t *i_stats); +int32_t dlsch_encoding_SIC(PHY_VARS_UE *ue, + uint8_t *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats); + + + /** \fn dlsch_encoding_2threads(PHY_VARS_eNB *eNB, uint8_t *input_buffer, uint8_t num_pdcch_symbols, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index b2ad2b23b8..ff6edc5a6e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -3089,11 +3089,12 @@ int main(int argc, char **argv) } start_meas(&eNB->dlsch_encoding_stats); - if (dlsch_encoding(((TB==0) ? input_buffer0[k] : input_buffer1[k]), - &eNB->frame_parms, + if (dlsch_encoding(eNB, + (TB==0) ? input_buffer0[k] : input_buffer1[k], num_pdcch_symbols, eNB->dlsch[k][TB], - 0,subframe, + 0, + subframe, &eNB->dlsch_rate_matching_stats, &eNB->dlsch_turbo_encoding_stats, &eNB->dlsch_interleaving_stats)<0) @@ -4058,8 +4059,8 @@ int main(int argc, char **argv) UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti; UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[eNB_id][0]->current_harq_pid; - dlsch_encoding(input_buffer0[0], //UE->dlsch[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b, - &UE->frame_parms, + dlsch_encoding_SIC(UE, + input_buffer0[0], //UE->dlsch[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,, num_pdcch_symbols, UE->dlsch_eNB[eNB_id], 0, From ab2c1fcc8e6144feb81072348b15bc633aea26ba Mon Sep 17 00:00:00 2001 From: gabrielC Date: Mon, 6 Feb 2017 14:55:50 +0100 Subject: [PATCH 244/571] fix TStatus Prohibit 0ms --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 1 - openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 3e88a31496..6a6daeab01 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -445,7 +445,6 @@ rlc_am_get_pdus ( RLC_AM_CLEAR_ALL_STATUS(rlc_pP->status_requested); rlc_pP->status_buffer_occupancy = 0; rlc_am_start_timer_status_prohibit(ctxt_pP, rlc_pP); - RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_PROHIBIT); return; } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c index d067c5d9bb..65ea056120 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_status_prohibit.c @@ -112,6 +112,7 @@ rlc_am_start_timer_status_prohibit( rlc_pP->t_status_prohibit.running = 1; rlc_pP->t_status_prohibit.ms_time_out = rlc_pP->t_status_prohibit.ms_duration + PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP); rlc_pP->t_status_prohibit.ms_start = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP); + RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_PROHIBIT); LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T-STATUS-PROHIBIT] STARTED (TIME-OUT = %u ms)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->t_status_prohibit.ms_time_out); From 39bdc2bce8c78231acc0917e6d773414004efb72 Mon Sep 17 00:00:00 2001 From: fnabet Date: Mon, 6 Feb 2017 16:29:01 +0100 Subject: [PATCH 245/571] fix Tx Status PDU --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 6495c722df..f75b481dbb 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -511,7 +511,7 @@ rlc_am_send_status_pdu( /* Set E1 for next NACK_SN. The last one will be cleared */ control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; control_pdu_info.num_nack += 1; - nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)); + nb_bits_transmitted += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1)); #if TRACE_RLC_AM_STATUS_CREATION LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] LINE %d PREPARE SENDING NACK %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), From e0b8998def79d45519b40a5b38f52a0c30501fe6 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 27 Jan 2017 14:00:22 +0100 Subject: [PATCH 246/571] fixing bug in PDSCH power allocation for TM2 Conflicts: openair1/PHY/INIT/lte_init.c openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c openair1/PHY/LTE_TRANSPORT/power_control.c --- openair1/PHY/INIT/lte_init.c | 14 +++++-- openair1/PHY/INIT/lte_param_init.c | 4 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 38 +++++++++++-------- openair1/PHY/LTE_TRANSPORT/power_control.c | 9 +++-- openair1/SCHED/phy_procedures_lte_eNb.c | 14 +++++-- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 5 ++- .../CONF/enb.band7.tm1.usrpb210.conf | 8 ++-- .../CONF/enb.band7.tm2.usrpb210.conf | 14 +++---- 8 files changed, 67 insertions(+), 39 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 34c5b0bd2b..fb8f73e276 100755 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -1265,7 +1265,11 @@ int phy_init_lte_ue(PHY_VARS_UE *ue, ue->sinr_CQI_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) ); ue->init_averaging = 1; - ue->pdsch_config_dedicated->p_a = dB0; // default value until overwritten by RRCConnectionReconfiguration + // default value until overwritten by RRCConnectionReconfiguration + if (fp->nb_antenna_ports_eNB==2) + ue->pdsch_config_dedicated->p_a = dBm3; + else + ue->pdsch_config_dedicated->p_a = dB0; // set channel estimation to do linear interpolation in time ue->high_speed_flag = 1; @@ -1552,8 +1556,12 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, for (UE_id=0; UE_idUE_stats_ptr[UE_id] = &eNB->UE_stats[UE_id]; - - eNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration + + //defaul value until overwritten by RRCConnectionReconfiguration + if (fp->nb_antenna_ports_eNB==2) + eNB->pdsch_config_dedicated->p_a = dBm3; + else + eNB->pdsch_config_dedicated->p_a = dB0; init_prach_tables(839); } // node_function != NGFI_RRU_IF4p5 diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index 4625eba430..f3833b7709 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -121,9 +121,9 @@ void lte_param_init(unsigned char N_tx_port_eNB, UE->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 0; } else { // rho_a = rhob - eNB->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB + eNB->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((eNB->frame_parms).pdsch_config_common).p_b = 1; - UE->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB + UE->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 1; } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index e89900c2ce..3c81085b0e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -814,11 +814,12 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; *jj=*jj+1; + //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore // normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0])); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1])); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0])); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1])); break; @@ -843,11 +844,11 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, qam16_table_offset_im+=1; *jj=*jj+1; - ((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); - - //((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15; - //((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; + //((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + //gain_lin_QPSK (=amp/sqrt(2)) is already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore + ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam16_table_offset_re]); + ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]); // Antenna 1 position n Real part -> -x1* @@ -869,8 +870,11 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, qam16_table_offset_im+=1; *jj=*jj+1; - ((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); - ((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + //((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15); + //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15); + //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore + ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam16_table_offset_re]); + ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam16_table_offset_im]); //((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam16_table_offset_re]; //((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam16_table_offset_im]; @@ -904,8 +908,10 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, //((int16_t *)&txdataF[0][tti_offset])[0]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); //((int16_t *)&txdataF[0][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]*ONE_OVER_SQRT2_Q15)>>15; - ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]*ONE_OVER_SQRT2_Q15)>>15; + //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore + ((int16_t *)&txdataF[0][tti_offset])[0]+=(qam_table_s0[qam64_table_offset_re]); + ((int16_t *)&txdataF[0][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]); + // Antenna 1 => -x1* qam64_table_offset_re = 0; @@ -931,8 +937,10 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, //((int16_t *)&txdataF[1][tti_offset])[0]+=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15); //((int16_t *)&txdataF[1][tti_offset])[1]+=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); - ((int16_t *)&txdataF[1][tti_offset])[0]+=-qam_table_s0[qam64_table_offset_re]; - ((int16_t *)&txdataF[1][tti_offset])[1]+=qam_table_s0[qam64_table_offset_im]; + //qam_table_s0 already contains the power offset from rho_a/rho_b, so here we do not need divide by sqrt(2) anymore + ((int16_t *)&txdataF[1][tti_offset])[0]+=-(qam_table_s0[qam64_table_offset_re]); + ((int16_t *)&txdataF[1][tti_offset])[1]+=(qam_table_s0[qam64_table_offset_im]); + break; } diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index d82b17a247..b3e4b132f6 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -35,7 +35,10 @@ double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by highe double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated) { - return(pa_values[pdsch_config_dedicated->p_a]); + if (pdsch_config_dedicated) + return(pa_values[ pdsch_config_dedicated->p_a]); + else + return(0.0); } double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, @@ -43,7 +46,7 @@ double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB; double sqrt_rho_a_lin; - rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; + rho_a_dB = get_pa_dB(pdsch_config_dedicated); if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5 rho_a_dB-=10*log10(2); @@ -99,7 +102,7 @@ double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB; double sqrt_rho_a_lin; - rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; + rho_a_dB = get_pa_dB(pdsch_config_dedicated); if(!dl_power_off) rho_a_dB-=10*log10(2); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 85c0956866..9f6215c3f2 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -686,7 +686,7 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC dci_alloc->format, &eNB->dlsch_SI, fp, - eNB->pdsch_config_dedicated, + NULL, SI_RNTI, 0, P_RNTI, @@ -720,7 +720,7 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC dci_alloc->format, &eNB->dlsch_ra, fp, - eNB->pdsch_config_dedicated, + NULL, SI_RNTI, dci_alloc->rnti, P_RNTI, @@ -770,7 +770,7 @@ void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC dci_alloc->format, eNB->dlsch[(uint8_t)UE_id], fp, - eNB->pdsch_config_dedicated, + &eNB->pdsch_config_dedicated[UE_id], SI_RNTI, 0, P_RNTI, @@ -1486,7 +1486,13 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, 0); } - + /* + if (frame>=10 && subframe>=9) { + write_output("/tmp/txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("/tmp/txsigF1.m","txsF1", &eNB->common_vars.txdataF[0][0][0],120*eNB->frame_parms.ofdm_symbol_size,1,1); + abort(); + } + */ #ifdef EMOS phy_procedures_emos_eNB_TX(subframe, eNB); diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 5f9a8e0e2a..5840006a37 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -1505,7 +1505,10 @@ do_RRCConnectionSetup( // PDSCH //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a, // PDSCH_ConfigDedicated__p_a_dB0); - physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= PDSCH_ConfigDedicated__p_a_dB0; + if (frame_parms->nb_antenna_ports_eNB==2) + physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= PDSCH_ConfigDedicated__p_a_dB_3; + else + physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= PDSCH_ConfigDedicated__p_a_dB0; // PUCCH physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present=PUCCH_ConfigDedicated__ackNackRepetition_PR_release; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index 5ef5a4f50b..b70a9122ff 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -68,9 +68,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; + pusch_p0_Nominal = -100; pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; + pucch_p0_Nominal = -106; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -148,9 +148,9 @@ eNBs = { ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.147/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.212/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.147/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.212/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm2.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm2.usrpb210.conf index dbd2220cbc..4a89eb86e4 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm2.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm2.usrpb210.conf @@ -31,7 +31,7 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2680000000L; + downlink_frequency = 2660000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; N_RB_DL = 25; @@ -51,7 +51,7 @@ eNBs = pucch_nCS_AN = 0; pucch_n1_AN = 32; pdsch_referenceSignalPower = -24; - pdsch_p_b = 0; + pdsch_p_b = 1; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; pusch_hoppingMode = "interSubFrame"; @@ -68,9 +68,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; + pusch_p0_Nominal = -100; pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; + pucch_p0_Nominal = -106; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -138,7 +138,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.171"; + mme_ip_address = ( { ipv4 = "192.168.12.70"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -148,10 +148,10 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.150/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.212/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.150/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.212/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; From d3af6f1f3664c3561d6c6a869b1f269442e6cba1 Mon Sep 17 00:00:00 2001 From: fnabet Date: Tue, 7 Feb 2017 10:47:47 +0100 Subject: [PATCH 247/571] Renaming or removing some Tx RLC AM fields --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 35 ++-- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h | 3 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c | 20 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 134 ++++++------- .../LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c | 7 +- .../RLC/AM_v9.3.0/rlc_am_segments_holes.c | 182 +++++++++--------- .../LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h | 4 +- 7 files changed, 192 insertions(+), 193 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 6a6daeab01..4d16a368fe 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -481,7 +481,7 @@ rlc_am_get_pdus ( (rlc_pP->first_retrans_pdu_sn >= 0) && (rlc_pP->first_retrans_pdu_sn != rlc_pP->vt_s)) { - tx_data_pdu_management = &rlc_pP->pdu_retrans_buffer[rlc_pP->first_retrans_pdu_sn]; + tx_data_pdu_management = &rlc_pP->tx_data_pdu_buffer[rlc_pP->first_retrans_pdu_sn]; if ((tx_data_pdu_management->header_and_payload_size <= rlc_pP->nb_bytes_requested_by_mac) && (tx_data_pdu_management->retx_count >= 0) && (tx_data_pdu_management->nack_so_start == 0) && (tx_data_pdu_management->nack_so_stop == 0x7FFF)) { @@ -500,7 +500,7 @@ rlc_am_get_pdus ( list_add_tail_eurecom (copy, &rlc_pP->pdus_to_mac_layer); rlc_pP->nb_bytes_requested_by_mac = rlc_pP->nb_bytes_requested_by_mac - tx_data_pdu_management->header_and_payload_size; - tx_data_pdu_management->retx_count += 1; + tx_data_pdu_management->retx_count = tx_data_pdu_management->retx_count_next; return; } else if ((tx_data_pdu_management->retx_count >= 0) && (rlc_pP->nb_bytes_requested_by_mac >= RLC_AM_MIN_SEGMENT_SIZE_REQUEST)) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" SEND SEGMENT OF DATA PDU SN %04d MAC BYTES %d SIZE %d RTX COUNT %d nack_so_start %d nack_so_stop %04X(hex)\n", @@ -535,7 +535,7 @@ rlc_am_get_pdus ( // update first_retrans_pdu_sn while ((rlc_pP->first_retrans_pdu_sn != rlc_pP->vt_s) && - (!(rlc_pP->pdu_retrans_buffer[rlc_pP->first_retrans_pdu_sn].flags.retransmit))) { + (!(rlc_pP->tx_data_pdu_buffer[rlc_pP->first_retrans_pdu_sn].flags.retransmit))) { rlc_pP->first_retrans_pdu_sn = (rlc_pP->first_retrans_pdu_sn+1) & RLC_AM_SN_MASK; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" UPDATED first_retrans_pdu_sn SN %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -706,22 +706,23 @@ rlc_am_mac_status_indication ( // force BO to be > 0 rlc_sn_t sn = (rlc->vt_s - 1) & RLC_AM_SN_MASK; rlc_sn_t sn_end = (rlc->vt_a - 1) & RLC_AM_SN_MASK; - int found_pdu = 0; - rlc_sn_t found_pdu_sn = 0; // avoid warning - (void)found_pdu_sn; /* avoid gcc warning "set but not used" */ - + /* Look for the first retransmittable PDU starting from vtS - 1 */ while (sn != sn_end) { - if (rlc->pdu_retrans_buffer[sn].mem_block != NULL) { - if (!found_pdu) { - found_pdu = 1; - found_pdu_sn = sn; - } - status_resp.buffer_occupancy_in_bytes = rlc->pdu_retrans_buffer[sn].header_and_payload_size; - status_resp.buffer_occupancy_in_pdus = rlc->nb_sdu; - status_resp.head_sdu_remaining_size_to_send = status_resp.buffer_occupancy_in_bytes; - // TODO head_sdu_is_segmented - break; + AssertFatal (rlc->tx_data_pdu_buffer[sn].mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n", + sn, rlc->vt_a,rlc->vt_s,rlc->channel_id); + if ((rlc->tx_data_pdu_buffer[sn].flags.ack == 0) && (rlc->tx_data_pdu_buffer[sn].flags.max_retransmit == 0)) { + rlc->retrans_num_bytes_to_retransmit = rlc->tx_data_pdu_buffer[sn].header_and_payload_size; + rlc->tx_data_pdu_buffer[sn].flags.retransmit = 1; + status_resp.buffer_occupancy_in_bytes = rlc->tx_data_pdu_buffer[sn].header_and_payload_size; + status_resp.buffer_occupancy_in_pdus = rlc->nb_sdu; + status_resp.head_sdu_remaining_size_to_send = status_resp.buffer_occupancy_in_bytes; + // TODO head_sdu_is_segmented + break; + } + else + { + sn = RLC_AM_PREV_SN(sn); } } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h index 45d0a5d489..87150f115c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h @@ -74,9 +74,8 @@ typedef struct rlc_am_entity_s { signed int current_sdu_index; /*!< \brief Current SDU index in input_sdus array to be segmented which is not segmented or partially segmented. */ - rlc_am_tx_data_pdu_management_t *pdu_retrans_buffer; /*!< \brief Retransmission buffer. */ + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer; /*!< \brief Transmission PDU data buffer. Used also for retransmissions */ signed int retrans_num_pdus; /*!< \brief Number of PDUs in the retransmission buffer. */ - signed int retrans_num_bytes; /*!< \brief Number of bytes in the retransmission buffer. */ signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. */ boolean_t force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index d08d010468..b93f331676 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -51,16 +51,16 @@ rlc_am_init( pthread_mutex_init(&rlc_pP->lock_input_sdus, NULL); rlc_pP->input_sdus = calloc(1, RLC_AM_SDU_CONTROL_BUFFER_SIZE*sizeof(rlc_am_tx_sdu_management_t)); //#warning "cast the rlc retrans buffer to uint32" - // rlc_pP->pdu_retrans_buffer = calloc(1, (uint16_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(rlc_am_tx_data_pdu_management_t))); - rlc_pP->pdu_retrans_buffer = calloc(1, (uint32_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof( + // rlc_pP->tx_data_pdu_buffer = calloc(1, (uint16_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof(rlc_am_tx_data_pdu_management_t))); + rlc_pP->tx_data_pdu_buffer = calloc(1, (uint32_t)((unsigned int)RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE*(unsigned int)sizeof( rlc_am_tx_data_pdu_management_t))); LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] input_sdus[] = %p element size=%zu\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->input_sdus, sizeof(rlc_am_tx_sdu_management_t)); - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] pdu_retrans_buffer[] = %p element size=%zu\n", + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] tx_data_pdu_buffer[] = %p element size=%zu\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->pdu_retrans_buffer, + rlc_pP->tx_data_pdu_buffer, sizeof(rlc_am_tx_data_pdu_management_t)); // TX state variables @@ -175,16 +175,16 @@ rlc_am_cleanup( pthread_mutex_destroy(&rlc_pP->lock_input_sdus); - if (rlc_pP->pdu_retrans_buffer != NULL) { + if (rlc_pP->tx_data_pdu_buffer != NULL) { for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) { - if (rlc_pP->pdu_retrans_buffer[i].mem_block != NULL) { - free_mem_block(rlc_pP->pdu_retrans_buffer[i].mem_block, __func__); - rlc_pP->pdu_retrans_buffer[i].mem_block = NULL; + if (rlc_pP->tx_data_pdu_buffer[i].mem_block != NULL) { + free_mem_block(rlc_pP->tx_data_pdu_buffer[i].mem_block, __func__); + rlc_pP->tx_data_pdu_buffer[i].mem_block = NULL; } } - free(rlc_pP->pdu_retrans_buffer); - rlc_pP->pdu_retrans_buffer = NULL; + free(rlc_pP->tx_data_pdu_buffer); + rlc_pP->tx_data_pdu_buffer = NULL; } memset(rlc_pP, 0, sizeof(rlc_am_entity_t)); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index a52c9bee33..4db9893f8a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -50,7 +50,7 @@ void rlc_am_nack_pdu ( // - indicate to upper layers that max retransmission has been reached. - mem_block_t* mb_p = rlc_pP->pdu_retrans_buffer[snP].mem_block; + mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; int pdu_sdu_index; int sdu_index; @@ -63,8 +63,8 @@ void rlc_am_nack_pdu ( // increasing order among calls refering to only one status PDU // and among time //----------------------------------------- - if (rlc_pP->pdu_retrans_buffer[snP].last_nack_time != ctxt_pP->frame) { - rlc_pP->pdu_retrans_buffer[snP].last_nack_time = ctxt_pP->frame; + if (rlc_pP->tx_data_pdu_buffer[snP].last_nack_time != ctxt_pP->frame) { + rlc_pP->tx_data_pdu_buffer[snP].last_nack_time = ctxt_pP->frame; rlc_am_clear_holes(ctxt_pP, rlc_pP, snP); } @@ -79,21 +79,22 @@ void rlc_am_nack_pdu ( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] NACK PDU SN %04d previous retx_count %d 1ST_RETRANS_PDU %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, - rlc_pP->pdu_retrans_buffer[snP].retx_count, + rlc_pP->tx_data_pdu_buffer[snP].retx_count, rlc_pP->first_retrans_pdu_sn); - rlc_pP->pdu_retrans_buffer[snP].flags.retransmit = 1; + rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 1; - if (rlc_pP->pdu_retrans_buffer[snP].retx_count == -1) { - rlc_pP->pdu_retrans_buffer[snP].retx_count = 0; - rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->pdu_retrans_buffer[snP].header_and_payload_size; - } else { - rlc_pP->pdu_retrans_buffer[snP].retx_count += 1; + /* TODO : before incrementing retx_count_next, this must be a new occurrence of retransmission */ + if (rlc_pP->tx_data_pdu_buffer[snP].retx_count == rlc_pP->tx_data_pdu_buffer[snP].retx_count_next){ + rlc_pP->tx_data_pdu_buffer[snP].retx_count_next ++; + rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->tx_data_pdu_buffer[snP].header_and_payload_size; } - if (rlc_pP->pdu_retrans_buffer[snP].retx_count >= rlc_pP->max_retx_threshold) { - for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->pdu_retrans_buffer[snP].nb_sdus; pdu_sdu_index++) { - sdu_index = rlc_pP->pdu_retrans_buffer[snP].sdus_index[pdu_sdu_index]; + /* TODO: Move this part in UL SCH processing */ +#if 0 + if (rlc_pP->tx_data_pdu_buffer[snP].retx_count >= rlc_pP->max_retx_threshold) { + for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP].nb_sdus; pdu_sdu_index++) { + sdu_index = rlc_pP->tx_data_pdu_buffer[snP].sdus_index[pdu_sdu_index]; assert(pdu_sdu_index < RLC_AM_MAX_SDU_IN_PDU); assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE); rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1; @@ -117,6 +118,7 @@ void rlc_am_nack_pdu ( } } } +#endif } else { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU SN %05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -130,29 +132,27 @@ void rlc_am_ack_pdu ( rlc_am_entity_t *const rlc_pP, const rlc_sn_t snP) { - mem_block_t* mb_p = rlc_pP->pdu_retrans_buffer[snP].mem_block; + mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; int pdu_sdu_index; int sdu_index; - rlc_pP->pdu_retrans_buffer[snP].flags.retransmit = 0; + rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 0; - if ((rlc_pP->pdu_retrans_buffer[snP].flags.ack == 0) && (mb_p != NULL)) { + if ((rlc_pP->tx_data_pdu_buffer[snP].flags.ack == 0) && (mb_p != NULL)) { //if (mb_pP != NULL) { free_mem_block(mb_p, __func__); - rlc_pP->pdu_retrans_buffer[snP].mem_block = NULL; + rlc_pP->tx_data_pdu_buffer[snP].mem_block = NULL; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] ACK PDU SN %05d previous retx_count %d \n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, - rlc_pP->pdu_retrans_buffer[snP].retx_count); - rlc_pP->retrans_num_pdus -= 1; - rlc_pP->retrans_num_bytes -= rlc_pP->pdu_retrans_buffer[snP].header_and_payload_size; + rlc_pP->tx_data_pdu_buffer[snP].retx_count); - if (rlc_pP->pdu_retrans_buffer[snP].retx_count >= 0) { - rlc_pP->retrans_num_bytes_to_retransmit -= rlc_pP->pdu_retrans_buffer[snP].header_and_payload_size; + if (rlc_pP->tx_data_pdu_buffer[snP].retx_count >= 0) { + rlc_pP->retrans_num_bytes_to_retransmit -= rlc_pP->tx_data_pdu_buffer[snP].header_and_payload_size; } - for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->pdu_retrans_buffer[snP].nb_sdus; pdu_sdu_index++) { - sdu_index = rlc_pP->pdu_retrans_buffer[snP].sdus_index[pdu_sdu_index]; + for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP].nb_sdus; pdu_sdu_index++) { + sdu_index = rlc_pP->tx_data_pdu_buffer[snP].sdus_index[pdu_sdu_index]; assert(sdu_index >= 0); assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE); rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1; @@ -182,19 +182,19 @@ void rlc_am_ack_pdu ( // This state variable holds the value of the SN of the next AMD PDU for which a positive acknowledgment is to be // received in-sequence, and it serves as the lower edge of the transmitting window. It is initially set to 0, and is updated // whenever the AM RLC entity receives a positive acknowledgment for an AMD PDU with SN = VT(A). - rlc_pP->pdu_retrans_buffer[snP].flags.ack = 1; + rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; if (snP == rlc_pP->vt_a) { - //rlc_pP->pdu_retrans_buffer[snP].flags.ack = 1; + //rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; do { - memset(&rlc_pP->pdu_retrans_buffer[rlc_pP->vt_a], 0, sizeof(rlc_am_tx_data_pdu_management_t)); + memset(&rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a], 0, sizeof(rlc_am_tx_data_pdu_management_t)); if (rlc_pP->vt_a == rlc_pP->first_retrans_pdu_sn) { rlc_pP->first_retrans_pdu_sn = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; } rlc_pP->vt_a = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; - } while ((rlc_pP->pdu_retrans_buffer[rlc_pP->vt_a].flags.ack == 1) && (rlc_pP->vt_a != rlc_pP->vt_s)); + } while ((rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a].flags.ack == 1) && (rlc_pP->vt_a != rlc_pP->vt_s)); rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; @@ -209,7 +209,7 @@ void rlc_am_ack_pdu ( do { rlc_pP->first_retrans_pdu_sn = (rlc_pP->first_retrans_pdu_sn + 1) & RLC_AM_SN_MASK; - if (rlc_pP->pdu_retrans_buffer[rlc_pP->first_retrans_pdu_sn].retx_count >= 0) { + if (rlc_pP->tx_data_pdu_buffer[rlc_pP->first_retrans_pdu_sn].retx_count >= 0) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] UPDATED first_retrans_pdu_sn -> %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->first_retrans_pdu_sn); @@ -231,21 +231,21 @@ void rlc_am_ack_pdu ( if (mb_p != NULL) { free_mem_block(mb_p, __func__); - rlc_pP->pdu_retrans_buffer[snP].mem_block = NULL; + rlc_pP->tx_data_pdu_buffer[snP].mem_block = NULL; } - if (rlc_pP->pdu_retrans_buffer[snP].flags.ack > 0) { + if (rlc_pP->tx_data_pdu_buffer[snP].flags.ack > 0) { if (snP == rlc_pP->vt_a) { - //rlc_pP->pdu_retrans_buffer[snP].flags.ack = 1; + //rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; do { - memset(&rlc_pP->pdu_retrans_buffer[rlc_pP->vt_a], 0, sizeof(rlc_am_tx_data_pdu_management_t)); + memset(&rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a], 0, sizeof(rlc_am_tx_data_pdu_management_t)); if (rlc_pP->vt_a == rlc_pP->first_retrans_pdu_sn) { rlc_pP->first_retrans_pdu_sn = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; } rlc_pP->vt_a = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; - } while ((rlc_pP->pdu_retrans_buffer[rlc_pP->vt_a].flags.ack == 1) && (rlc_pP->vt_a != rlc_pP->vt_s)); + } while ((rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a].flags.ack == 1) && (rlc_pP->vt_a != rlc_pP->vt_s)); rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] UPDATED VT(A) %04d VT(MS) %04d VT(S) %04d\n", @@ -263,11 +263,11 @@ mem_block_t* rlc_am_retransmit_get_copy ( rlc_am_entity_t *const rlc_pP, const rlc_sn_t snP) { - mem_block_t* mb_original_p = rlc_pP->pdu_retrans_buffer[snP].mem_block; + mem_block_t* mb_original_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; if (mb_original_p != NULL) { - rlc_am_tx_data_pdu_management_t *pdu_mngt = &rlc_pP->pdu_retrans_buffer[snP % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE]; + rlc_am_tx_data_pdu_management_t *pdu_mngt = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE]; int size = pdu_mngt->header_and_payload_size + sizeof(struct mac_tb_req); mem_block_t* mb_copy = get_free_mem_block(size, __func__); @@ -335,7 +335,7 @@ mem_block_t* rlc_am_retransmit_get_subsegment( // - set the header of the new AMD PDU segment in accordance with the description in sub clause 6.; // - set the P field according to sub clause 5.2.2. - mem_block_t* mb_original_p = rlc_pP->pdu_retrans_buffer[snP].mem_block; + mem_block_t* mb_original_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; if (mb_original_p != NULL) { mem_block_t* mb_sub_segment_p = get_free_mem_block(*sizeP + sizeof(struct mac_tb_req), __func__); @@ -348,10 +348,10 @@ mem_block_t* rlc_am_retransmit_get_subsegment( ((struct mac_tb_req*)(mb_sub_segment_p->data))->data_ptr = (uint8_t*)&(mb_sub_segment_p->data[sizeof(struct mac_tb_req)]); - if (rlc_am_get_data_pdu_infos(ctxt_pP, rlc_pP, pdu_original_p, rlc_pP->pdu_retrans_buffer[snP].header_and_payload_size, &pdu_info) >= 0) { + if (rlc_am_get_data_pdu_infos(ctxt_pP, rlc_pP, pdu_original_p, rlc_pP->tx_data_pdu_buffer[snP].header_and_payload_size, &pdu_info) >= 0) { int li_index = 0; - int start_offset = rlc_pP->pdu_retrans_buffer[snP].nack_so_start; - int stop_offset = rlc_pP->pdu_retrans_buffer[snP].nack_so_stop; + int start_offset = rlc_pP->tx_data_pdu_buffer[snP].nack_so_start; + int stop_offset = rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] ORIGINAL PDU SN %04d:\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -361,8 +361,8 @@ mem_block_t* rlc_am_retransmit_get_subsegment( // all 15 bits set to 1 (indicate that the missing portion of the AMD PDU includes all bytes // to the last byte of the AMD PDU) if (stop_offset == 0x7FFF) { - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = rlc_pP->pdu_retrans_buffer[snP].payload_size - 1; - stop_offset = rlc_pP->pdu_retrans_buffer[snP].nack_so_stop; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = rlc_pP->tx_data_pdu_buffer[snP].payload_size - 1; + stop_offset = rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] UPDATED RETRANS PDU SN %04d nack_so_stop FROM 0x7FFF to %05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, @@ -622,7 +622,7 @@ mem_block_t* rlc_am_retransmit_get_subsegment( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); test_pdu_copy_size = max_copy_payload_size; - if ((stop_offset == (start_offset + max_copy_payload_size - 1)) && (stop_offset == rlc_pP->pdu_retrans_buffer[snP].payload_size - 1)) { + if ((stop_offset == (start_offset + max_copy_payload_size - 1)) && (stop_offset == rlc_pP->tx_data_pdu_buffer[snP].payload_size - 1)) { not_test_fi = (not_test_fi & 0x2) | (not_fi_original & 0x1); // set b0 idendical to the b0 of the non segmented PDU } else { not_test_fi = not_test_fi & 0x2; // clear b0 because no SDU ending in this PDU @@ -630,7 +630,7 @@ mem_block_t* rlc_am_retransmit_get_subsegment( } //--------------------------------------------------------------- - /*if (stop_offset == (rlc_pP->pdu_retrans_buffer[snP].payload_size - 1)) { + /*if (stop_offset == (rlc_pP->tx_data_pdu_buffer[snP].payload_size - 1)) { test_fi = (test_fi & 0x02) | (fi_original & 0x01); }*/ //--------------------------------------------------------------- @@ -687,16 +687,16 @@ mem_block_t* rlc_am_retransmit_get_subsegment( // copy payload to retransmit //--------------------------------------------------------------- memcpy(fill_payload_p, - &rlc_pP->pdu_retrans_buffer[snP].payload[start_offset], + &rlc_pP->tx_data_pdu_buffer[snP].payload[start_offset], test_pdu_copy_size); ((struct mac_tb_req*)(mb_sub_segment_p->data))->tb_size = (tb_size_t)(((uint64_t)fill_payload_p)+ test_pdu_copy_size) - ((uint64_t)(&pdu_sub_segment_p->b1)); // set LSF - if ((test_pdu_copy_size + start_offset) == rlc_pP->pdu_retrans_buffer[snP].payload_size) { + if ((test_pdu_copy_size + start_offset) == rlc_pP->tx_data_pdu_buffer[snP].payload_size) { pdu_sub_segment_p->data[0] = pdu_sub_segment_p->data[0] | 0x80; - rlc_pP->pdu_retrans_buffer[snP].flags.retransmit = 0; + rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 0; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] RE-SEND DATA PDU SN %04d SO %d %d BYTES PAYLOAD %d BYTES LSF!\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -723,15 +723,15 @@ mem_block_t* rlc_am_retransmit_get_subsegment( // update nack_so_start //--------------------------------------------------------------- rlc_am_remove_hole(ctxt_pP, rlc_pP, snP, start_offset, test_pdu_copy_size+start_offset - 1); - //rlc_pP->pdu_retrans_buffer[snP].nack_so_start = rlc_pP->pdu_retrans_buffer[snP].nack_so_start + test_pdu_copy_size; + //rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = rlc_pP->tx_data_pdu_buffer[snP].nack_so_start + test_pdu_copy_size; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] RE-SEND DATA PDU SN %04d NOW nack_so_start %d nack_so_stop %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, - rlc_pP->pdu_retrans_buffer[snP].nack_so_start, - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop); - /*if (rlc_pP->pdu_retrans_buffer[snP].nack_so_start == rlc_pP->pdu_retrans_buffer[snP].nack_so_stop) { - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = 0; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = 0x7FFF; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start, + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop); + /*if (rlc_pP->tx_data_pdu_buffer[snP].nack_so_start == rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop) { + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = 0; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = 0x7FFF; }*/ } else { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] COULD NOT GET INFO FOR DATA PDU SN %04d -> RETURN NULL\n", @@ -773,25 +773,25 @@ void rlc_am_tx_buffer_display ( } while (rlc_pP->vt_s != sn) { - if (rlc_pP->pdu_retrans_buffer[sn].mem_block) { + if (rlc_pP->tx_data_pdu_buffer[sn].mem_block) { if ((loop % 1) == 0) { LOG_D(RLC, "\nTX SN:\t"); } - if (rlc_pP->pdu_retrans_buffer[sn].flags.retransmit) { - LOG_D(RLC, "%04d %d/%d Bytes (NACK RTX:%02d ",sn, rlc_pP->pdu_retrans_buffer[sn].header_and_payload_size, rlc_pP->pdu_retrans_buffer[sn].payload_size, - rlc_pP->pdu_retrans_buffer[sn].retx_count); + if (rlc_pP->tx_data_pdu_buffer[sn].flags.retransmit) { + LOG_D(RLC, "%04d %d/%d Bytes (NACK RTX:%02d ",sn, rlc_pP->tx_data_pdu_buffer[sn].header_and_payload_size, rlc_pP->tx_data_pdu_buffer[sn].payload_size, + rlc_pP->tx_data_pdu_buffer[sn].retx_count); } else { - LOG_D(RLC, "%04d %d/%d Bytes (RTX:%02d ",sn, rlc_pP->pdu_retrans_buffer[sn].header_and_payload_size, rlc_pP->pdu_retrans_buffer[sn].payload_size, - rlc_pP->pdu_retrans_buffer[sn].retx_count); + LOG_D(RLC, "%04d %d/%d Bytes (RTX:%02d ",sn, rlc_pP->tx_data_pdu_buffer[sn].header_and_payload_size, rlc_pP->tx_data_pdu_buffer[sn].payload_size, + rlc_pP->tx_data_pdu_buffer[sn].retx_count); } - if (rlc_pP->pdu_retrans_buffer[sn].num_holes == 0) { - LOG_D(RLC, "SO:%04d->%04d)\t", rlc_pP->pdu_retrans_buffer[sn].nack_so_start, rlc_pP->pdu_retrans_buffer[sn].nack_so_stop); + if (rlc_pP->tx_data_pdu_buffer[sn].num_holes == 0) { + LOG_D(RLC, "SO:%04d->%04d)\t", rlc_pP->tx_data_pdu_buffer[sn].nack_so_start, rlc_pP->tx_data_pdu_buffer[sn].nack_so_stop); } else { - for (i=0; ipdu_retrans_buffer[sn].num_holes; i++) { + for (i=0; itx_data_pdu_buffer[sn].num_holes; i++) { assert(i < RLC_AM_MAX_HOLES_REPORT_PER_PDU); - LOG_D(RLC, "SO:%04d->%04d)\t", rlc_pP->pdu_retrans_buffer[sn].hole_so_start[i], rlc_pP->pdu_retrans_buffer[sn].hole_so_stop[i]); + LOG_D(RLC, "SO:%04d->%04d)\t", rlc_pP->tx_data_pdu_buffer[sn].hole_so_start[i], rlc_pP->tx_data_pdu_buffer[sn].hole_so_stop[i]); } } @@ -819,13 +819,13 @@ void rlc_am_retransmit_any_pdu( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); while (sn != sn_end) { - if (rlc_pP->pdu_retrans_buffer[sn].mem_block != NULL) { + if (rlc_pP->tx_data_pdu_buffer[sn].mem_block != NULL) { if (!found_pdu) { found_pdu = 1; found_pdu_sn = sn; } - if (rlc_pP->pdu_retrans_buffer[sn].header_and_payload_size <= rlc_pP->nb_bytes_requested_by_mac) { + if (rlc_pP->tx_data_pdu_buffer[sn].header_and_payload_size <= rlc_pP->nb_bytes_requested_by_mac) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[FORCE-TRAFFIC] RE-SEND DATA PDU SN %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), sn); @@ -838,7 +838,7 @@ void rlc_am_retransmit_any_pdu( // no need for update rlc_pP->nb_bytes_requested_by_mac pdu_p = rlc_am_retransmit_get_copy(ctxt_pP, rlc_pP, sn); pdu_sn_10_p = (rlc_am_pdu_sn_10_t*) (&pdu_p->data[sizeof(struct mac_tb_req)]); - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->pdu_retrans_buffer[sn].header_and_payload_size,false); + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->tx_data_pdu_buffer[sn].header_and_payload_size,false); //BugFix: polling is checked and done in function above ! //pdu_sn_10_p->b1 = pdu_sn_10_p->b1 | 0x20; //BugFix : pdu_without_poll and byte_without_poll are reset only if a Poll is transmitted @@ -874,7 +874,7 @@ void rlc_am_retransmit_any_pdu( rlc_am_nack_pdu (ctxt_pP, rlc_pP, found_pdu_sn, 0, 0x7FFF); pdu_p = rlc_am_retransmit_get_subsegment(ctxt_pP, rlc_pP, found_pdu_sn, &rlc_pP->nb_bytes_requested_by_mac); pdu_sn_10_p = (rlc_am_pdu_sn_10_t*) (&pdu_p->data[sizeof(struct mac_tb_req)]); - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->pdu_retrans_buffer[found_pdu_sn].header_and_payload_size,false); + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sn_10_p, rlc_pP->tx_data_pdu_buffer[found_pdu_sn].header_and_payload_size,false); pdu_sn_10_p->b1 = pdu_sn_10_p->b1 | 0x20; rlc_pP->c_pdu_without_poll = 0; rlc_pP->c_byte_without_poll = 0; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index af4f67f303..824154b311 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -223,7 +223,7 @@ void rlc_am_segment_10 ( pdu_remaining_size = data_pdu_size - RLC_AM_HEADER_MIN_SIZE; pdu_p = (rlc_am_pdu_sn_10_t*) (&pdu_mem_p->data[sizeof(struct mac_tb_req)]); pdu_tb_req_p = (struct mac_tb_req*) (pdu_mem_p->data); - pdu_mngt_p = &rlc_pP->pdu_retrans_buffer[rlc_pP->vt_s % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE]; + pdu_mngt_p = &rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_s % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE]; memset(pdu_mngt_p, 0, sizeof (rlc_am_tx_data_pdu_management_t)); memset (pdu_mem_p->data, 0, sizeof (rlc_am_pdu_sn_10_t)+sizeof(struct mac_tb_req)); @@ -531,11 +531,10 @@ void rlc_am_segment_10 ( pdu_mngt_p->mem_block = pdu_mem_p; pdu_mngt_p->first_byte = (unsigned char*)pdu_p; pdu_mngt_p->header_and_payload_size = data_pdu_size - pdu_remaining_size; - pdu_mngt_p->retx_count = -1; + pdu_mngt_p->retx_count = 0; + pdu_mngt_p->retx_count_next = 0; pdu_mngt_p->flags.transmitted = 1; - rlc_pP->retrans_num_pdus += 1; - rlc_pP->retrans_num_bytes += pdu_mngt_p->header_and_payload_size; pdu_p = NULL; pdu_mem_p = NULL; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c index 37e9b13508..b1eabdd1ca 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c @@ -32,7 +32,7 @@ void rlc_am_clear_holes ( rlc_am_entity_t *const rlc_pP, const rlc_sn_t snP) { - rlc_pP->pdu_retrans_buffer[snP].num_holes = 0; + rlc_pP->tx_data_pdu_buffer[snP].num_holes = 0; } //----------------------------------------------------------------------------- void rlc_am_shift_down_holes ( @@ -43,12 +43,12 @@ void rlc_am_shift_down_holes ( { int i; - for (i=indexP; i < rlc_pP->pdu_retrans_buffer[snP].num_holes - 1; i++) { - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i] = rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i+1]; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i] = rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i+1]; + for (i=indexP; i < rlc_pP->tx_data_pdu_buffer[snP].num_holes - 1; i++) { + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i] = rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i+1]; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i] = rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i+1]; } - rlc_pP->pdu_retrans_buffer[snP].num_holes = rlc_pP->pdu_retrans_buffer[snP].num_holes - 1; + rlc_pP->tx_data_pdu_buffer[snP].num_holes = rlc_pP->tx_data_pdu_buffer[snP].num_holes - 1; } //----------------------------------------------------------------------------- void rlc_am_shift_up_holes ( @@ -60,13 +60,13 @@ void rlc_am_shift_up_holes ( // shift include indexP int i; - for (i=rlc_pP->pdu_retrans_buffer[snP].num_holes; i > indexP; i--) { - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i] = rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i-1]; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i] = rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i-1]; + for (i=rlc_pP->tx_data_pdu_buffer[snP].num_holes; i > indexP; i--) { + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i] = rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i-1]; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i] = rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i-1]; } - rlc_pP->pdu_retrans_buffer[snP].num_holes = rlc_pP->pdu_retrans_buffer[snP].num_holes + 1; - assert(rlc_pP->pdu_retrans_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); + rlc_pP->tx_data_pdu_buffer[snP].num_holes = rlc_pP->tx_data_pdu_buffer[snP].num_holes + 1; + assert(rlc_pP->tx_data_pdu_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); } //----------------------------------------------------------------------------- void rlc_am_remove_hole ( @@ -79,81 +79,81 @@ void rlc_am_remove_hole ( int i; #if TRACE_RLC_AM_HOLE LOG_D(RLC, - PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] REMOVE HOLE SN %04d so_startP %05d so_stopP %05d rlc_pP->pdu_retrans_buffer[snP].nack_so_start %05d rlc_pP->pdu_retrans_buffer[snP].nack_so_stop %05d\n", + PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] REMOVE HOLE SN %04d so_startP %05d so_stopP %05d rlc_pP->tx_data_pdu_buffer[snP].nack_so_start %05d rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop %05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, so_startP, so_stopP, - rlc_pP->pdu_retrans_buffer[snP].nack_so_start, - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop); + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start, + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop); #endif assert(so_startP <= so_stopP); - if (rlc_pP->pdu_retrans_buffer[snP].num_holes == 0) { - assert(so_startP == rlc_pP->pdu_retrans_buffer[snP].nack_so_start); - assert(so_stopP <= rlc_pP->pdu_retrans_buffer[snP].nack_so_stop); + if (rlc_pP->tx_data_pdu_buffer[snP].num_holes == 0) { + assert(so_startP == rlc_pP->tx_data_pdu_buffer[snP].nack_so_start); + assert(so_stopP <= rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop); #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] REMOVE HOLE SN %04d MODIFIED nack_so_start %05d->%05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, - rlc_pP->pdu_retrans_buffer[snP].nack_so_start, + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start, so_stopP+1); #endif - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = so_stopP+1; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = so_stopP+1; - if (rlc_pP->pdu_retrans_buffer[snP].nack_so_start >= rlc_pP->pdu_retrans_buffer[snP].nack_so_stop) { - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = 0; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = 0x7FFF; + if (rlc_pP->tx_data_pdu_buffer[snP].nack_so_start >= rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop) { + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = 0; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = 0x7FFF; } } else { // normally should be removed in increasing order... - for (i = 0; i < rlc_pP->pdu_retrans_buffer[snP].num_holes; i++) { - if (so_startP <= rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i]) { - if (so_stopP >= rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i]) { + for (i = 0; i < rlc_pP->tx_data_pdu_buffer[snP].num_holes; i++) { + if (so_startP <= rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i]) { + if (so_stopP >= rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i]) { rlc_am_shift_down_holes(ctxt_pP, rlc_pP, snP, i); i = i - 1; } else { - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i] = so_stopP; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i] = so_stopP; - if (rlc_pP->pdu_retrans_buffer[snP].num_holes == 0) { - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = 0; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = 0x7FFF; + if (rlc_pP->tx_data_pdu_buffer[snP].num_holes == 0) { + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = 0; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = 0x7FFF; } else { - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = rlc_pP->pdu_retrans_buffer[snP].hole_so_start[0]; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[rlc_pP->pdu_retrans_buffer[snP].num_holes - 1]; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[0]; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[rlc_pP->tx_data_pdu_buffer[snP].num_holes - 1]; } #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] REMOVE HOLE SN %04d NOW nack_so_start %05d nack_so_stop %05d num holes %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, - rlc_pP->pdu_retrans_buffer[snP].nack_so_start, - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop, - rlc_pP->pdu_retrans_buffer[snP].num_holes); + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start, + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop, + rlc_pP->tx_data_pdu_buffer[snP].num_holes); #endif return; } - } else if (so_startP > rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i]) { - if (so_startP <= rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i]) { - if (so_stopP < rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i]) { + } else if (so_startP > rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i]) { + if (so_startP <= rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i]) { + if (so_stopP < rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i]) { // BAD CASE: 1 HOLE IS SPLITTED IN 2 HOLES rlc_am_shift_up_holes(ctxt_pP, rlc_pP, snP, i+1); - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i+1] = so_startP+1; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i+1] = rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i]; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i] = so_startP - 1; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i+1] = so_startP+1; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i+1] = rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i]; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i] = so_startP - 1; } else { - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i] = so_startP; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i] = so_startP; } } } } - if (rlc_pP->pdu_retrans_buffer[snP].num_holes == 0) { - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = 0; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = 0x7FFF; + if (rlc_pP->tx_data_pdu_buffer[snP].num_holes == 0) { + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = 0; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = 0x7FFF; } else { - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = rlc_pP->pdu_retrans_buffer[snP].hole_so_start[0]; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[rlc_pP->pdu_retrans_buffer[snP].num_holes - 1]; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[0]; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[rlc_pP->tx_data_pdu_buffer[snP].num_holes - 1]; } } @@ -161,11 +161,11 @@ void rlc_am_remove_hole ( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] REMOVE HOLE SN %04d NOW nack_so_start %05d nack_so_stop %05d num holes %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, - rlc_pP->pdu_retrans_buffer[snP].nack_so_start, - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop, - rlc_pP->pdu_retrans_buffer[snP].num_holes); + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start, + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop, + rlc_pP->tx_data_pdu_buffer[snP].num_holes); #endif - assert(rlc_pP->pdu_retrans_buffer[snP].nack_so_start < rlc_pP->pdu_retrans_buffer[snP].payload_size); + assert(rlc_pP->tx_data_pdu_buffer[snP].nack_so_start < rlc_pP->tx_data_pdu_buffer[snP].payload_size); } //----------------------------------------------------------------------------- void rlc_am_get_next_hole ( @@ -175,9 +175,9 @@ void rlc_am_get_next_hole ( sdu_size_t* const so_startP, sdu_size_t* const so_stopP) { - if (rlc_pP->pdu_retrans_buffer[snP].num_holes == 0) { - *so_startP = rlc_pP->pdu_retrans_buffer[snP].nack_so_start; - *so_stopP = rlc_pP->pdu_retrans_buffer[snP].nack_so_stop; + if (rlc_pP->tx_data_pdu_buffer[snP].num_holes == 0) { + *so_startP = rlc_pP->tx_data_pdu_buffer[snP].nack_so_start; + *so_stopP = rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop; #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] rlc_am_get_next_hole(SN %04d) %05d->%05d (NUM HOLES == 0)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -186,15 +186,15 @@ void rlc_am_get_next_hole ( *so_stopP); #endif } else { - *so_startP = rlc_pP->pdu_retrans_buffer[snP].hole_so_start[0]; - *so_stopP = rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[0]; + *so_startP = rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[0]; + *so_stopP = rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[0]; #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] rlc_am_get_next_hole(SN %04d) %05d->%05d (NUM HOLES == %d)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, *so_startP, *so_stopP, - rlc_pP->pdu_retrans_buffer[snP].num_holes); + rlc_pP->tx_data_pdu_buffer[snP].num_holes); #endif } } @@ -214,33 +214,33 @@ void rlc_am_add_hole ( // if global NACK - if ((so_startP == 0) && ((so_stopP == 0x7FFF) || (so_stopP == rlc_pP->pdu_retrans_buffer[snP].payload_size - 1))) { - rlc_pP->pdu_retrans_buffer[snP].num_holes = 0; - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = so_startP; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = so_stopP; + if ((so_startP == 0) && ((so_stopP == 0x7FFF) || (so_stopP == rlc_pP->tx_data_pdu_buffer[snP].payload_size - 1))) { + rlc_pP->tx_data_pdu_buffer[snP].num_holes = 0; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = so_startP; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = so_stopP; #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] SN %04d GLOBAL NACK 0->%05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, so_stopP); #endif - assert(rlc_pP->pdu_retrans_buffer[snP].nack_so_start < rlc_pP->pdu_retrans_buffer[snP].payload_size); + assert(rlc_pP->tx_data_pdu_buffer[snP].nack_so_start < rlc_pP->tx_data_pdu_buffer[snP].payload_size); return; } if (so_stopP == 0x7FFF) { - so_stopP = rlc_pP->pdu_retrans_buffer[snP].payload_size - 1; + so_stopP = rlc_pP->tx_data_pdu_buffer[snP].payload_size - 1; } // first hole - if (rlc_pP->pdu_retrans_buffer[snP].num_holes == 0) { - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[0] = so_startP; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop [0] = so_stopP; + if (rlc_pP->tx_data_pdu_buffer[snP].num_holes == 0) { + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[0] = so_startP; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop [0] = so_stopP; - rlc_pP->pdu_retrans_buffer[snP].num_holes = 1; + rlc_pP->tx_data_pdu_buffer[snP].num_holes = 1; - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = so_startP; - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = so_stopP; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = so_startP; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = so_stopP; #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] FIRST HOLE SN %04d GLOBAL NACK %05d->%05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -248,44 +248,44 @@ void rlc_am_add_hole ( so_startP, so_stopP); #endif - assert(rlc_pP->pdu_retrans_buffer[snP].nack_so_start < rlc_pP->pdu_retrans_buffer[snP].payload_size); + assert(rlc_pP->tx_data_pdu_buffer[snP].nack_so_start < rlc_pP->tx_data_pdu_buffer[snP].payload_size); return; } hole_index = 0; - while (hole_index < rlc_pP->pdu_retrans_buffer[snP].num_holes) { - if (so_stopP < rlc_pP->pdu_retrans_buffer[snP].hole_so_start[hole_index]) { - assert(rlc_pP->pdu_retrans_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); + while (hole_index < rlc_pP->tx_data_pdu_buffer[snP].num_holes) { + if (so_stopP < rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[hole_index]) { + assert(rlc_pP->tx_data_pdu_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); if (hole_index > 0) { - assert(so_startP > rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[hole_index-1]); + assert(so_startP > rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[hole_index-1]); } - for (i=rlc_pP->pdu_retrans_buffer[snP].num_holes; i >= hole_index; i--) { - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i] = rlc_pP->pdu_retrans_buffer[snP].hole_so_start[i-1]; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i] = rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[i-1]; + for (i=rlc_pP->tx_data_pdu_buffer[snP].num_holes; i >= hole_index; i--) { + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i] = rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[i-1]; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i] = rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[i-1]; } - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[hole_index] = so_startP; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[hole_index] = so_stopP; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[hole_index] = so_startP; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[hole_index] = so_stopP; // update nack "window" vars nack_so_start, nack_so_stop if (hole_index == 0) { - rlc_pP->pdu_retrans_buffer[snP].nack_so_start = so_startP; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_start = so_startP; } - rlc_pP->pdu_retrans_buffer[snP].num_holes += 1; + rlc_pP->tx_data_pdu_buffer[snP].num_holes += 1; #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] INSERT %d th HOLE SN %04d GLOBAL NACK %05d->%05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->pdu_retrans_buffer[snP].num_holes, + rlc_pP->tx_data_pdu_buffer[snP].num_holes, snP, so_startP, so_stopP); #endif - assert(rlc_pP->pdu_retrans_buffer[snP].nack_so_start < rlc_pP->pdu_retrans_buffer[snP].payload_size); - assert(rlc_pP->pdu_retrans_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); + assert(rlc_pP->tx_data_pdu_buffer[snP].nack_so_start < rlc_pP->tx_data_pdu_buffer[snP].payload_size); + assert(rlc_pP->tx_data_pdu_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); return; } @@ -293,17 +293,17 @@ void rlc_am_add_hole ( } // if here insert to the "tail" - if (so_startP > rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[hole_index - 1]) { - assert(rlc_pP->pdu_retrans_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); - rlc_pP->pdu_retrans_buffer[snP].hole_so_start[hole_index] = so_startP; - rlc_pP->pdu_retrans_buffer[snP].hole_so_stop[hole_index] = so_stopP; - rlc_pP->pdu_retrans_buffer[snP].num_holes += 1; + if (so_startP > rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[hole_index - 1]) { + assert(rlc_pP->tx_data_pdu_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); + rlc_pP->tx_data_pdu_buffer[snP].hole_so_start[hole_index] = so_startP; + rlc_pP->tx_data_pdu_buffer[snP].hole_so_stop[hole_index] = so_stopP; + rlc_pP->tx_data_pdu_buffer[snP].num_holes += 1; // update nack "window" vars nack_so_start, nack_so_stop - rlc_pP->pdu_retrans_buffer[snP].nack_so_stop = so_stopP; + rlc_pP->tx_data_pdu_buffer[snP].nack_so_stop = so_stopP; #if TRACE_RLC_AM_HOLE LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] INSERT THE %d th LAST HOLE SN %04d GLOBAL NACK %05d->%05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->pdu_retrans_buffer[snP].num_holes, + rlc_pP->tx_data_pdu_buffer[snP].num_holes, snP, so_startP, so_stopP); @@ -312,6 +312,6 @@ void rlc_am_add_hole ( assert(1==2); } - assert(rlc_pP->pdu_retrans_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); - assert(rlc_pP->pdu_retrans_buffer[snP].nack_so_start < rlc_pP->pdu_retrans_buffer[snP].payload_size); + assert(rlc_pP->tx_data_pdu_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); + assert(rlc_pP->tx_data_pdu_buffer[snP].nack_so_start < rlc_pP->tx_data_pdu_buffer[snP].payload_size); } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h index 5ca98c88be..e201e909c5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h @@ -117,8 +117,8 @@ typedef struct rlc_am_tx_data_pdu_management { sdu_size_t nack_so_stop; /*!< \brief Highest NACK stop segment offset, must be set to data_size if global NACK */ int8_t nb_sdus; /*!< \brief Number of sdu having segments in this pdu. */ - int8_t - retx_count; /*!< \brief Counts the number of retransmissions of an AMD PDU (see subclause 5.2.1). There is one RETX_COUNT counter per PDU that needs to be retransmitted. there is one VT(DAT) for each PDU and it is incremented each time the PDU is transmitted. */ + int8_t retx_count; /*!< \brief Counts the number of already occurred retransmissions of an AMD PDU (see subclause 5.2.1). */ + int8_t retx_count_next; /*!< \brief Counts the number of already occurred retransmissions plus the latest pending one. */ pdu_management_flags_t flags; /*!< \brief PDU variables related to its retransmission. */ } rlc_am_tx_data_pdu_management_t; From b44c49bc3048fb8707eb521fbb9a64f9045fafe5 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 7 Feb 2017 21:58:39 +0100 Subject: [PATCH 248/571] adjusting power levels in alamouti receiver and dlsim. now TM2 dlsim tests pass again. Conflicts: openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c openair1/PHY/impl_defs_top.h --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 9 +++++++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 041e59adae..529bfe1438 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -3817,14 +3817,15 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, #if defined(__x86_64__)||defined(__i386__) short *rxF0,*rxF1; - __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b, amp, *rxF0_128; + __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b, *rxF0_128; unsigned char rb,re; int jj = (symbol*frame_parms->N_RB_DL*12); uint8_t symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; uint8_t pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0; rxF0_128 = (__m128i*) &rxdataF_comp[0][jj]; - amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + //amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + //amp = _mm_set1_epi16(ONE_OVER_2_Q15); // printf("Doing alamouti!\n"); rxF0 = (short*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y @@ -3861,6 +3862,7 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, ch_mag0b[1] = _mm_adds_epi16(ch_mag0b[1],ch_mag1b[1]); // account for 1/sqrt(2) scaling at transmission + /* ch_mag0[0] = _mm_srai_epi16(ch_mag0[0],1); ch_mag0[1] = _mm_srai_epi16(ch_mag0[1],1); ch_mag0b[0] = _mm_srai_epi16(ch_mag0b[0],1); @@ -3870,16 +3872,19 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, rxF0_128[0] = _mm_slli_epi16(rxF0_128[0],1); rxF0_128[1] = _mm_mulhi_epi16(rxF0_128[1],amp); rxF0_128[1] = _mm_slli_epi16(rxF0_128[1],1); + */ if (pilots==0) { ch_mag0[2] = _mm_adds_epi16(ch_mag0[2],ch_mag1[2]); ch_mag0b[2] = _mm_adds_epi16(ch_mag0b[2],ch_mag1b[2]); + /* ch_mag0[2] = _mm_srai_epi16(ch_mag0[2],1); ch_mag0b[2] = _mm_srai_epi16(ch_mag0b[2],1); rxF0_128[2] = _mm_mulhi_epi16(rxF0_128[2],amp); rxF0_128[2] = _mm_slli_epi16(rxF0_128[2],1); + */ ch_mag0+=3; ch_mag1+=3; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index af1b1a6aef..4109307ba9 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -233,8 +233,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } //AWGN - // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR - get_pa_dB(eNB->pdsch_config_dedicated); + // tx_lev is the average energy over the whole subframe + // but SNR should be better defined wrt the energy in the reference symbols + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { From d3b42510536715b68981e0e7ca5f46469e729c99 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 8 Feb 2017 11:36:48 +0100 Subject: [PATCH 249/571] yet another bugfix for dlsim --- openair1/SIMULATION/LTE_PHY/dlsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 4109307ba9..26a24ae01a 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2110,7 +2110,7 @@ int main(int argc, char **argv) UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->dlsch_ra[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - + UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); // structure for SIC at UE UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); From ce465e503a1dfd2e07882fa83f61f4844c418915 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 8 Feb 2017 12:03:41 +0100 Subject: [PATCH 250/571] applying last dlsim fix to dlsim_tm4 --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index ff6edc5a6e..9fbe27bee3 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -3316,8 +3316,9 @@ int main(int argc, char **argv) } //AWGN - // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(eNB->pdsch_config_dedicated); + // tx_lev is the average energy over the whole subframe + // but SNR should be better defined wrt the energy in the reference symbols + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); if (n_frames==1) printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(eNB->pdsch_config_dedicated)); From 157707b0422201ef1cd9b505578c9a11d6e19604 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 8 Feb 2017 18:06:24 +0100 Subject: [PATCH 251/571] fix USE_MME compilation flag We should use ENABLE_USE_MME, not USE_MME. This code is useless anyway (I think, not sure, that's why I leave it here), because the other threads wait for 'sync_var' to become >=0. --- targets/RT/USER/lte-ue.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 10883921e7..5945431dda 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -198,14 +198,14 @@ void init_UE(int nb_inst) { } printf("UE threads created\n"); -#ifdef USE_MME - +#if 0 +#if defined(ENABLE_USE_MME) + extern volatile int start_UE; while (start_UE == 0) { sleep(1); } - #endif - +#endif } /*! From 393fe865633a3b69aca3c06c66aafafabbf707fe Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Feb 2017 09:47:13 +0100 Subject: [PATCH 252/571] fix: pass UE parameter to UE threads oaisim is not functional with several UEs. This fixes one issue. (It's still not functional for other reasons.) --- openair3/NAS/UE/nas_ue_task.c | 1 + targets/RT/USER/lte-ue.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index d548d480c7..d5d1f5c209 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -150,6 +150,7 @@ void *nas_ue_task(void *args_p) msg_name = ITTI_MSG_NAME (msg_p); instance = ITTI_MSG_INSTANCE (msg_p); Mod_id = instance - NB_eNB_INST; + if (instance == INSTANCE_DEFAULT) abort(); nas_user_t *user = &users->item[Mod_id]; switch (ITTI_MSG_ID(msg_p)) { diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5945431dda..0d24e9f55b 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -186,7 +186,7 @@ void init_UE(int nb_inst) { } UE->rfdevice.host_type = BBU_HOST; // UE->rfdevice.type = NONE_DEV; - error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL); + error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, UE); if (error_code!= 0) { LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); @@ -599,6 +599,14 @@ static void *UE_thread_synch(void *arg) } +/* this structure is used to pass both UE phy vars and + * proc to the function UE_thread_rxn_txnp4 + */ +struct rx_tx_thread_data { + PHY_VARS_UE *UE; + UE_rxtx_proc_t *proc; +}; + /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. @@ -611,9 +619,10 @@ static void *UE_thread_synch(void *arg) static void *UE_thread_rxn_txnp4(void *arg) { static int UE_thread_rxtx_retval; - UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + PHY_VARS_UE *UE = rtd->UE; int ret; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; proc->instance_cnt_rxtx=-1; @@ -849,6 +858,7 @@ static void *UE_thread_rxn_txnp4(void *arg) } // thread finished + free(arg); return &UE_thread_rxtx_retval; } @@ -873,7 +883,7 @@ static void *UE_thread_rxn_txnp4(void *arg) void *UE_thread(void *arg) { static int UE_thread_retval; - PHY_VARS_UE *UE = PHY_vars_UE_g[0][0]; + PHY_VARS_UE *UE = arg; //PHY_vars_UE_g[0][0]; // int tx_enabled = 0; uint32_t rxs=0,txs=0; int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); @@ -936,7 +946,7 @@ void *UE_thread(void *arg) { #ifdef NAS_UE message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif while (!oai_exit) { @@ -1650,8 +1660,9 @@ void *UE_thread_old(void *arg) */ void init_UE_threads(int inst) { + struct rx_tx_thread_data *rtd; PHY_VARS_UE *UE; - + UE = PHY_vars_UE_g[inst][0]; pthread_attr_init (&UE->proc.attr_ue); @@ -1674,9 +1685,17 @@ void init_UE_threads(int inst) pthread_cond_init(&UE->proc.proc_rxtx[0].cond_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[1].cond_rxtx,NULL); pthread_cond_init(&UE->proc.cond_synch,NULL); - pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[0]); + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[0].CC_id]; + rtd->proc = &UE->proc.proc_rxtx[0]; + pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[0]); pthread_setname_np( UE->proc.proc_rxtx[0].pthread_rxtx, "rxn_txnp4_even" ); - pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[1]); + rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[1].CC_id]; + rtd->proc = &UE->proc.proc_rxtx[1]; + pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[1]); pthread_setname_np( UE->proc.proc_rxtx[1].pthread_rxtx, "rxn_txnp4_odd" ); pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); pthread_setname_np( UE->proc.pthread_synch, "UE_thread_synch" ); From 9c6cb96baf345c386daf635195b61ca4e73c9e01 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Feb 2017 10:46:20 +0100 Subject: [PATCH 253/571] put UE id in thread names --- targets/RT/USER/lte-ue.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 0d24e9f55b..380a3d5226 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -192,8 +192,10 @@ void init_UE(int nb_inst) { LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code); return; } else { + char name[128]; + sprintf(name, "main UE %d", inst); LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" ); - pthread_setname_np( UE->proc.pthread_ue, "main UE" ); + pthread_setname_np(UE->proc.pthread_ue, name); } } @@ -1661,6 +1663,7 @@ void *UE_thread_old(void *arg) void init_UE_threads(int inst) { struct rx_tx_thread_data *rtd; + char name[128]; PHY_VARS_UE *UE; UE = PHY_vars_UE_g[inst][0]; @@ -1690,15 +1693,18 @@ void init_UE_threads(int inst) rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[0].CC_id]; rtd->proc = &UE->proc.proc_rxtx[0]; pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[0]); - pthread_setname_np( UE->proc.proc_rxtx[0].pthread_rxtx, "rxn_txnp4_even" ); + sprintf(name, "rxn_txnp4_even UE %d", inst); + pthread_setname_np(UE->proc.proc_rxtx[0].pthread_rxtx, name); rtd = calloc(1, sizeof(struct rx_tx_thread_data)); if (rtd == NULL) abort(); rtd->UE = PHY_vars_UE_g[inst][UE->proc.proc_rxtx[1].CC_id]; rtd->proc = &UE->proc.proc_rxtx[1]; pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,rtd);//(void*)&UE->proc.proc_rxtx[1]); - pthread_setname_np( UE->proc.proc_rxtx[1].pthread_rxtx, "rxn_txnp4_odd" ); + sprintf(name, "rxn_txnp4_odd UE %d", inst); + pthread_setname_np(UE->proc.proc_rxtx[1].pthread_rxtx, name); pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); - pthread_setname_np( UE->proc.pthread_synch, "UE_thread_synch" ); + sprintf(name, "UE_thread_synch UE %d", inst); + pthread_setname_np(UE->proc.pthread_synch, name); } From 234acfea7f05344ab3321bc36a8553348b5e7336 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Feb 2017 10:53:15 +0100 Subject: [PATCH 254/571] fix: this piece of code should not be here It was probably the result of a bad merge. At this point eNB_inst is not valid. Plus the T_ENB_MASTER_TICK is now handled in lte-enb.c, even for oaisim. --- targets/SIMU/USER/oaisim.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 1d1e9c947b..915cdc7aed 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -764,23 +764,6 @@ l2l1_task (void *args_p) current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti; } - - if (oai_emulation.info.cli_start_enb[eNB_inst] != 0) { - T(T_ENB_MASTER_TICK, T_INT(eNB_inst), T_INT(frame % 1024), T_INT(slot/2)); - /* - LOG_D(EMU, - "PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d) TDD %d/%d Nid_cell %d\n", - eNB_inst, - frame%MAX_FRAME_NUMBER, - 2*sf, - PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_tx, - PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_rx, - PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.frame_type, - PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.tdd_config, - PHY_vars_eNB_g[eNB_inst][0]->lte_frame_parms.Nid_cell); - */ - } - for (eNB_inst = oai_emulation.info.first_enb_local; (eNB_inst < (oai_emulation.info.first_enb_local From e400b5e709609eb494ae4459cf6cf12dc66280da Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Feb 2017 10:56:42 +0100 Subject: [PATCH 255/571] fix: remove T_ENB_MASTER_TICK in oaisim.c It's now done in lte-enb.c, even for oaisim. --- targets/SIMU/USER/oaisim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 915cdc7aed..7ccc1668bc 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -771,7 +771,6 @@ l2l1_task (void *args_p) eNB_inst++) { if (oai_emulation.info.cli_start_enb[eNB_inst] != 0) { - T(T_ENB_MASTER_TICK, T_INT(eNB_inst), T_INT(frame % 1024), T_INT(sf)); /* LOG_D(EMU, "PHY procedures eNB %d for frame %d, subframe %d TDD %d/%d Nid_cell %d\n", From 3e77251f96afa6e7998e8d551227a0a2c72431f9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Feb 2017 10:57:46 +0100 Subject: [PATCH 256/571] minor: add a message before aborting The case instance == INSTANCE_DEFAULT should normally not happen, but let's be a bit verbose if it does. --- openair3/NAS/UE/nas_ue_task.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index d5d1f5c209..58e38fdbc2 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -150,7 +150,11 @@ void *nas_ue_task(void *args_p) msg_name = ITTI_MSG_NAME (msg_p); instance = ITTI_MSG_INSTANCE (msg_p); Mod_id = instance - NB_eNB_INST; - if (instance == INSTANCE_DEFAULT) abort(); + if (instance == INSTANCE_DEFAULT) { + printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n", + __FILE__, __LINE__); + abort(); + } nas_user_t *user = &users->item[Mod_id]; switch (ITTI_MSG_ID(msg_p)) { From 62bcd5edf92a1fa5d6566960f7fba90c0746e83e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 9 Feb 2017 11:00:59 +0100 Subject: [PATCH 257/571] fix: create tasks before sync in oaisim Not sure if this is the right thing to do, but it seems to be. "start_eNB = 1;" is also necessary when the l2l1 task gets INITIALIZE_MESSAGE otherwise the eNB does not start. As it is today, I don't think oaisim will work with more than one eNB. --- targets/SIMU/USER/oaisim.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 7ccc1668bc..d5f49d9faf 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -589,6 +589,7 @@ l2l1_task (void *args_p) switch (ITTI_MSG_ID(message_p)) { case INITIALIZE_MESSAGE: l2l1_state = L2L1_RUNNING; + start_eNB = 1; break; case ACTIVATE_MESSAGE: @@ -1276,6 +1277,11 @@ main (int argc, char **argv) init_ocm (); +#if defined(ENABLE_ITTI) + if (create_tasks(oai_emulation.info.nb_enb_local, oai_emulation.info.nb_ue_local) < 0) + exit(1); +#endif + // wait for all threads to startup sleep(3); printf("Sending sync to all threads\n"); @@ -1316,11 +1322,7 @@ main (int argc, char **argv) #if defined(ENABLE_ITTI) // Handle signals until all tasks are terminated - if (create_tasks(oai_emulation.info.nb_enb_local, oai_emulation.info.nb_ue_local) >= 0) { - itti_wait_tasks_end(); - } else { - exit(-1); // need a softer mode - } + itti_wait_tasks_end(); #else From 3c191c26f384359381f76b28039ea15b7b8a2e95 Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 9 Feb 2017 17:46:04 +0100 Subject: [PATCH 258/571] fix BCH tracking --- openair2/UTIL/LOG/log.h | 2 + targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 363 +++++++++---------- targets/RT/USER/lte-ue.c | 264 ++++---------- 3 files changed, 245 insertions(+), 384 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 1735a89a73..5e5be23e0d 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -46,7 +46,9 @@ #include #include #include +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #else #include "rtai_fifos.h" diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index c12cc50ead..00db1f46c6 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -66,17 +66,17 @@ typedef struct { // -------------------------------- //! USRP device pointer uhd::usrp::multi_usrp::sptr usrp; - - //create a send streamer and a receive streamer - //! USRP TX Stream - uhd::tx_streamer::sptr tx_stream; - //! USRP RX Stream - uhd::rx_streamer::sptr rx_stream; - //! USRP TX Metadata - uhd::tx_metadata_t tx_md; - //! USRP RX Metadata - uhd::rx_metadata_t rx_md; + //create a send streamer and a receive streamer + //! USRP TX Stream + uhd::tx_streamer::sptr tx_stream; + //! USRP RX Stream + uhd::rx_streamer::sptr rx_stream; + + //! USRP TX Metadata + uhd::tx_metadata_t tx_md; + //! USRP RX Metadata + uhd::rx_metadata_t rx_md; //! Sampling rate double sample_rate; @@ -109,7 +109,7 @@ static int trx_usrp_start(openair0_device *device) { // init recv and send streaming uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05); - cmd.stream_now = true; + cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); @@ -122,7 +122,7 @@ static int trx_usrp_start(openair0_device *device) { s->rx_timestamp = 0; return 0; } -/*! \brief Terminate operation of the USRP transceiver -- free all associated resources +/*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ static void trx_usrp_end(openair0_device *device) { @@ -151,36 +151,33 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); s->tx_md.has_time_spec = flags; - - if(flags>0) - s->tx_md.has_time_spec = true; - else - s->tx_md.has_time_spec = false; - if (flags == 2) { // start of burst - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false; - } - else if (flags == 3) { // end of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = true; - } - else if (flags == 4) { // start and end - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = true; - } - else if (flags==1) { // middle of burst - s->tx_md.start_of_burst = false; - s->tx_md.end_of_burst = false; - } - - if (cc>1) { - std::vector buff_ptrs; + if(flags>0) + s->tx_md.has_time_spec = true; + else + s->tx_md.has_time_spec = false; + + if (flags == 2) { // start of burst + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = false; + } else if (flags == 3) { // end of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = true; + } else if (flags == 4) { // start and end + s->tx_md.start_of_burst = true; + s->tx_md.end_of_burst = true; + } else if (flags==1) { // middle of burst + s->tx_md.start_of_burst = false; + s->tx_md.end_of_burst = false; + } + + if (cc>1) { + std::vector buff_ptrs; for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); + ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md,1e-3); } else - ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); + ret = (int)s->tx_stream->send(buff[0], nsamps, s->tx_md,1e-3); @@ -239,27 +236,27 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp for (int j=0; jtype == USRP_X300_DEV) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector buff_ptrs; + + for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { + // receive a single channel (e.g. from connector RF A) + samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); + } } - } else if (device->type == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; - - for (int i=0;irx_stream->recv(buff_ptrs, nsamps, s->rx_md); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md); - } - } if (samples_received < nsamps) LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); @@ -280,39 +277,39 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp * \param b second variable */ static bool is_equal(double a, double b) { - return std::fabs(a-b) < std::numeric_limits::epsilon(); + return std::fabs(a-b) < std::numeric_limits::epsilon(); } void *freq_thread(void *arg) { - - openair0_device *device=(openair0_device *)arg; - usrp_state_t *s = (usrp_state_t*)device->priv; - - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + + openair0_device *device=(openair0_device *)arg; + usrp_state_t *s = (usrp_state_t*)device->priv; + + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); } /*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application * \param dummy dummy variable not used - * \returns 0 in success + * \returns 0 in success */ int trx_usrp_set_freq(openair0_device* device, openair0_config_t *openair0_cfg, int dont_block) { - usrp_state_t *s = (usrp_state_t*)device->priv; - pthread_t f_thread; + usrp_state_t *s = (usrp_state_t*)device->priv; + pthread_t f_thread; - printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); + printf("Setting USRP TX Freq %f, RX Freq %f\n",openair0_cfg[0].tx_freq[0],openair0_cfg[0].rx_freq[0]); - // spawn a thread to handle the frequency change to not block the calling thread - if (dont_block == 1) - pthread_create(&f_thread,NULL,freq_thread,(void*)device); - else { - s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); - s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); - } + // spawn a thread to handle the frequency change to not block the calling thread + if (dont_block == 1) + pthread_create(&f_thread,NULL,freq_thread,(void*)device); + else { + s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); + s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + } - return(0); + return(0); } @@ -361,14 +358,14 @@ int trx_usrp_set_gains(openair0_device* device, openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0], openair0_cfg[0].rx_gain[0],gain_range.stop()); - return(0); + return(0); } /*! \brief Stop USRP * \param card refers to the hardware index to use */ int trx_usrp_stop(openair0_device* device) { - return(0); + return(0); } /*! \brief USRPB210 RX calibration table */ @@ -441,12 +438,12 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index,int bw_ LOG_I(PHY,"cal %d: freq %f, offset %f, diff %f\n", i, openair0_cfg->rx_gain_calib_table[i].freq, - openair0_cfg->rx_gain_calib_table[i].offset,diff); - if (min_diff > diff) { - min_diff = diff; - openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; - } - i++; + openair0_cfg->rx_gain_calib_table[i].offset,diff); + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset+gain_adj; + } + i++; } } @@ -491,11 +488,11 @@ extern "C" { double usrp_master_clock = 184.32e6; std::string args = "type=x300"; - // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate - args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - + // workaround for an api problem, master clock has to be set with the constructor not via set_master_clock_rate + args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; - + // args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=4096, recv_frame_size=4096"; uhd::device_addrs_t device_adds = uhd::device::find(args); @@ -507,10 +504,10 @@ extern "C" { LOG_I(PHY,"Found USRP X300\n"); s->usrp = uhd::usrp::multi_usrp::make(args); // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); //Setting device type to USRP X300/X310 device->type=USRP_X300_DEV; @@ -523,29 +520,29 @@ extern "C" { switch ((int)openair0_cfg[0].sample_rate) { case 30720000: - // from usrp_time_offset - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 15; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 45; - openair0_cfg[0].tx_bw = 10e6; - openair0_cfg[0].rx_bw = 10e6; - break; - case 7680000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 5e6; - openair0_cfg[0].rx_bw = 5e6; - break; - case 1920000: - //openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 50; - openair0_cfg[0].tx_bw = 1.25e6; - openair0_cfg[0].rx_bw = 1.25e6; + // from usrp_time_offset + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 15; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 45; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + case 7680000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + case 1920000: + //openair0_cfg[0].samples_per_packet = 2048; + openair0_cfg[0].tx_sample_advance = 50; + openair0_cfg[0].tx_bw = 1.25e6; + openair0_cfg[0].rx_bw = 1.25e6; break; default: LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); @@ -558,19 +555,19 @@ extern "C" { args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; s->usrp = uhd::usrp::multi_usrp::make(args); - // s->usrp->set_rx_subdev_spec(rx_subdev); - // s->usrp->set_tx_subdev_spec(tx_subdev); - - // do not explicitly set the clock to "internal", because this will disable the gpsdo - // // lock mboard clocks - // s->usrp->set_clock_source("internal"); - // set master clock rate and sample rate for tx & rx for streaming + // s->usrp->set_rx_subdev_spec(rx_subdev); + // s->usrp->set_tx_subdev_spec(tx_subdev); - // lock mboard clocks - if (openair0_cfg[0].clock_source == internal) - s->usrp->set_clock_source("internal"); - else - s->usrp->set_clock_source("external"); + // do not explicitly set the clock to "internal", because this will disable the gpsdo + // // lock mboard clocks + // s->usrp->set_clock_source("internal"); + // set master clock rate and sample rate for tx & rx for streaming + + // lock mboard clocks + if (openair0_cfg[0].clock_source == internal) + s->usrp->set_clock_source("internal"); + else + s->usrp->set_clock_source("external"); device->type = USRP_B200_DEV; if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { @@ -581,52 +578,52 @@ extern "C" { bw_gain_adjust=1; } - switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 115; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 23040000: - s->usrp->set_master_clock_rate(23.04e6); //to be checked - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 113; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 15360000: - s->usrp->set_master_clock_rate(30.72e06); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 103; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 7680000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 80; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - case 1920000: - s->usrp->set_master_clock_rate(30.72e6); - //openair0_cfg[0].samples_per_packet = 1024; - openair0_cfg[0].tx_sample_advance = 40; - openair0_cfg[0].tx_bw = 20e6; - openair0_cfg[0].rx_bw = 20e6; - break; - default: + switch ((int)openair0_cfg[0].sample_rate) { + case 30720000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 23040000: + s->usrp->set_master_clock_rate(23.04e6); //to be checked + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 15360000: + s->usrp->set_master_clock_rate(30.72e06); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 103; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 7680000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 1920000: + s->usrp->set_master_clock_rate(30.72e6); + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 40; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + default: LOG_E(PHY,"Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate); exit(-1); break; } } - /* device specific */ - //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered - //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered + /* device specific */ + //openair0_cfg[0].txlaunch_wait = 1;//manage when TX processing is triggered + //openair0_cfg[0].txlaunch_wait_slotcount = 1; //manage when TX processing is triggered openair0_cfg[0].iq_txshift = 4;//shift openair0_cfg[0].iq_rxrescale = 15;//rescale iqs @@ -660,7 +657,7 @@ extern "C" { // display USRP settings LOG_I(PHY,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); - sleep(1); + sleep(1); // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); @@ -711,24 +708,24 @@ extern "C" { device->trx_start_func = trx_usrp_start; device->trx_write_func = trx_usrp_write; device->trx_read_func = trx_usrp_read; - device->trx_get_stats_func = trx_usrp_get_stats; - device->trx_reset_stats_func = trx_usrp_reset_stats; - device->trx_end_func = trx_usrp_end; - device->trx_stop_func = trx_usrp_stop; - device->trx_set_freq_func = trx_usrp_set_freq; - device->trx_set_gains_func = trx_usrp_set_gains; - device->openair0_cfg = openair0_cfg; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; - s->sample_rate = openair0_cfg[0].sample_rate; - // TODO: - // init tx_forward_nsamps based usrp_time_offset ex - if(is_equal(s->sample_rate, (double)30.72e6)) - s->tx_forward_nsamps = 176; - if(is_equal(s->sample_rate, (double)15.36e6)) - s->tx_forward_nsamps = 90; - if(is_equal(s->sample_rate, (double)7.68e6)) - s->tx_forward_nsamps = 50; - return 0; - } + s->sample_rate = openair0_cfg[0].sample_rate; + // TODO: + // init tx_forward_nsamps based usrp_time_offset ex + if(is_equal(s->sample_rate, (double)30.72e6)) + s->tx_forward_nsamps = 176; + if(is_equal(s->sample_rate, (double)15.36e6)) + s->tx_forward_nsamps = 90; + if(is_equal(s->sample_rate, (double)7.68e6)) + s->tx_forward_nsamps = 50; + return 0; + } } /*@}*/ diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5115a824fc..0f341d29a5 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -79,6 +79,7 @@ #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL +#define FIFO_PRIORITY 40 typedef enum { pss=0, @@ -241,171 +242,69 @@ static void *UE_thread_synch(void *arg) { int current_offset = 0; sync_mode_t sync_mode = pbch; int CC_id = UE->CC_id; - int ind; - int found; int freq_offset=0; - UE->is_synchronized = 0; - printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); - printf("waiting for sync (UE_thread_synch) \n"); - -#ifndef DEADLINE_SCHEDULER - int policy, s, j; - struct sched_param sparam; - char cpu_affinity[1024]; cpu_set_t cpuset; - - /* Set affinity mask to include CPUs 1 to MAX_CPUS */ - /* CPU 0 is reserved for UHD threads */ CPU_ZERO(&cpuset); + CPU_SET(3, &cpuset); + // this thread priority must be lower that the main acquisition thread + init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, + "sync UE"); -#ifdef CPU_AFFINITY - if (get_nprocs() >2) { - for (j = 1; j < get_nprocs(); j++) - CPU_SET(j, &cpuset); - - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - } -#endif - - /* Check the actual affinity mask assigned to the thread */ - - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); - for (j = 0; j < CPU_SETSIZE; j++) - if (CPU_ISSET(j, &cpuset)) { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); - } - - memset(&sparam, 0 , sizeof (sparam)); - sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; - policy = SCHED_FIFO ; - - s = pthread_setschedparam(pthread_self(), policy, &sparam); - if (s != 0) { - perror("pthread_setschedparam : "); - exit_fun("Error setting thread priority"); - } - s = pthread_getschedparam(pthread_self(), &policy, &sparam); - if (s != 0) { - perror("pthread_getschedparam : "); - exit_fun("Error getting thread priority"); - - } - - LOG_I( HW, "[SCHED][UE] Started UE synch thread on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(), - (policy == SCHED_FIFO) ? "SCHED_FIFO" : - (policy == SCHED_RR) ? "SCHED_RR" : - (policy == SCHED_OTHER) ? "SCHED_OTHER" : - "???", - (int) sparam.sched_priority, cpu_affinity); - -#endif - - printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); - ind = 0; - found = 0; - + UE->is_synchronized = 0; if (UE->UE_scan == 0) { - do { + int ind; + for ( ind=0; + ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]); + ind++) { current_band = eutra_bands[ind].band; - printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); - - if ((eutra_bands[ind].dl_min <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) { + LOG_D(PHY, "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); + if ( eutra_bands[ind].dl_min <= downlink_frequency[0][0] && eutra_bands[ind].dl_max >= downlink_frequency[0][0] ) { for (i=0; i<4; i++) uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; - - found = 1; break; } - - ind++; - } while (ind < sizeof(eutra_bands) / sizeof(eutra_bands[0])); - - if (found == 0) { - exit_fun("Can't find EUTRA band for frequency"); - return &UE_thread_synch_retval; } + AssertFatal( ind < sizeof(eutra_bands) / sizeof(eutra_bands[0]), "Can't find EUTRA band for frequency"); - - - - - - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0],oai_exit, openair0_cfg[0].rx_num_channels); + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", + downlink_frequency[0][0], downlink_frequency[0][0]+uplink_frequency_offset[0][0], + oai_exit, openair0_cfg[0].rx_num_channels); for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; if (uplink_frequency_offset[CC_id][i] != 0) // openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; else //FDD openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; } - sync_mode = pbch; - } else if (UE->UE_scan == 1) { + } else { current_band=0; - for (i=0; irf_map.card].rx_num_channels; i++) { downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; - + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = + bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; } } - - pthread_mutex_lock(&sync_mutex); - printf("Locked sync_mutex, waiting (UE_sync_thread)\n"); - - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - - pthread_mutex_unlock(&sync_mutex); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); - - if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - } + AssertFatal(UE->rfdevice.trx_start_func(&UE->rfdevice) == 0, "Could not start the device\n"); while (oai_exit==0) { - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } - - - while (UE->proc.instance_cnt_synch < 0) { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + while (UE->proc.instance_cnt_synch < 0) // the thread waits here most of the time pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); - } - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" ); - exit_fun("nothing to add"); - return &UE_thread_synch_retval; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 1 ); + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); switch (sync_mode) { case pss: @@ -453,17 +352,16 @@ static void *UE_thread_synch(void *arg) { UE->UE_scan_carrier ); if (UE->UE_scan_carrier == 1) { - UE->UE_scan_carrier = 0; // rerun with new cell parameters and frequency-offset for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (freq_offset >= 0) { + if (freq_offset >= 0) openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += UE->common_vars.freq_offset; - } else { + else openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; - } - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; freq_offset=0; } @@ -506,7 +404,9 @@ static void *UE_thread_synch(void *arg) { oai_exit=1; } } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); UE->is_synchronized = 1; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if( UE->mode == rx_dump_frame ) { FILE *fd; @@ -524,7 +424,10 @@ static void *UE_thread_synch(void *arg) { exit(0); } } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); UE->is_synchronized = 0; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + } } } @@ -532,12 +435,9 @@ static void *UE_thread_synch(void *arg) { // initial sync failed // calculate new offset and try again if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) { + if (freq_offset >= 0) freq_offset += 100; - freq_offset *= -1; - } else { - freq_offset *= -1; - } + freq_offset *= -1; if (abs(freq_offset) > 7500) { LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); @@ -554,8 +454,6 @@ static void *UE_thread_synch(void *arg) { mac_xface->macphy_exit("No cell synchronization found, abandoning"); return &UE_thread_synch_retval; // not reached } - } else { - } LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", freq_offset, @@ -566,40 +464,22 @@ static void *UE_thread_synch(void *arg) { for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - - if (UE->UE_scan_carrier==1) { + if (UE->UE_scan_carrier==1) openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } } - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 - break; - case si: default: break; } - - if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } - + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); // indicate readiness UE->proc.instance_cnt_synch--; - - if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" ); - exit_fun("noting to add"); - return &UE_thread_synch_retval; - } + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); } // while !oai_exit @@ -631,7 +511,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(proc->sub_frame_start+1, &cpuset); - init_thread(900000,1000000 , 40, &cpuset,//sched_get_priority_max(SCHED_FIFO)-1, + init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, threadname); while (!oai_exit) { @@ -750,12 +630,11 @@ void *UE_thread(void *arg) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(3, &cpuset); - init_thread(100000, 500000, 40, &cpuset, //sched_get_priority_max(SCHED_FIFO), + init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, "main UE"); AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); UE->rfdevice.host_type = BBU_HOST; - sleep(1); init_UE_threads(UE); #ifdef NAS_UE @@ -767,13 +646,12 @@ void *UE_thread(void *arg) { int sub_frame=-1; //int cumulated_shift=0; while (!oai_exit) { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + int instance_cnt_synch = UE->proc.instance_cnt_synch; + int is_synchronized = UE->is_synchronized; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - if (UE->is_synchronized == 0) { - - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - int instance_cnt_synch = UE->proc.instance_cnt_synch; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - + if (is_synchronized == 0) { if (instance_cnt_synch < 0) { // we can invoke the synch // grab 10 ms of signal and wakeup synch thread for (int i=0; iframe_parms.nb_antennas_rx; i++) @@ -793,14 +671,12 @@ void *UE_thread(void *arg) { LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); exit_fun("nothing to add"); } - } // - else { + } else { // grab 10 ms of signal into dummy buffer - if (UE->mode != loop_through_memory) { for (int i=0; iframe_parms.nb_antennas_rx; i++) rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0; sf<10; sf++) { + for (int sf=0; sf<10; sf++) // printf("Reading dummy sf %d\n",sf); AssertFatal ( UE->frame_parms.samples_per_tti == UE->rfdevice.trx_read_func(&UE->rfdevice, @@ -808,8 +684,6 @@ void *UE_thread(void *arg) { rxp, UE->frame_parms.samples_per_tti, UE->frame_parms.nb_antennas_rx), ""); - - } } } @@ -861,32 +735,20 @@ void *UE_thread(void *arg) { readBlockSize=UE->frame_parms.samples_per_tti; writeBlockSize=UE->frame_parms.samples_per_tti; } else { - static int rx_correction_timer=5; - static int rx_off_diff =0; - if ((UE->rx_offset<(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset > 0) && - (rx_correction_timer == 0)) { - rx_off_diff = -1 ; - LOG_D(PHY,"AbsSubframe %d.%d UE->rx_offset %d > %d, diff %d\n", - proc->frame_rx,proc->subframe_rx,UE->rx_offset,0,rx_off_diff); - rx_correction_timer = 5; - } else if ((UE->rx_offset>(5*UE->frame_parms.samples_per_tti)) && - (UE->rx_offset < ((10*UE->frame_parms.samples_per_tti))) && - (rx_correction_timer == 0)) { // moving to the left so drop rx_off_diff samples - rx_off_diff = 1; - LOG_D(PHY,"AbsSubframe %d.%d UE->rx_offset %d < %d, diff %d\n", - proc->frame_rx,proc->subframe_rx,UE->rx_offset,10*UE->frame_parms.samples_per_tti,rx_off_diff); - rx_correction_timer = 5; - } - if (rx_correction_timer>0) - rx_correction_timer--; - UE->rx_offset_diff = rx_off_diff; + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && + UE->rx_offset > 0 ) + UE->rx_offset_diff = -1 ; + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && + UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) + UE->rx_offset_diff = 1; + LOG_D(PHY,"SET rx_off_diff to %d\n",UE->rx_offset_diff); - rx_off_diff = 0; - readBlockSize=UE->frame_parms.samples_per_tti- - UE->frame_parms.ofdm_symbol_size- - UE->frame_parms.nb_prefix_samples0; - writeBlockSize=UE->frame_parms.samples_per_tti - rx_off_diff; + readBlockSize=UE->frame_parms.samples_per_tti - + UE->frame_parms.ofdm_symbol_size - + UE->frame_parms.nb_prefix_samples0 - + UE->rx_offset_diff; + writeBlockSize=UE->frame_parms.samples_per_tti - + UE->rx_offset_diff; } AssertFatal(readBlockSize == From b9e03cf2517bea0d3621b84439e70f80194f5f65 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 9 Feb 2017 19:17:28 +0100 Subject: [PATCH 259/571] fix usrp thread priority --- common/utils/T/T.h | 12 ++++++++++++ targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/common/utils/T/T.h b/common/utils/T/T.h index bd090ac221..819615131e 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -188,6 +188,12 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ + if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ + printf("%s:%d:%s: " \ + "bad use of T, pass a message ID as first parameter\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ struct timespec T_HEADER_time; \ if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \ memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \ @@ -199,6 +205,12 @@ extern T_cache_t *T_cache; #define T_HEADER(x) \ do { \ + if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ + printf("%s:%d:%s: " \ + "bad use of T, pass a message ID as first parameter\n", \ + __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ T_PUT_int(1, (int)(uintptr_t)(x)); \ } while (0) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 00db1f46c6..2ac70b2d82 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -469,7 +469,7 @@ extern "C" { * \param openair0_cfg RF frontend parameters set by application */ int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { - //uhd::set_thread_priority_safe(1.0); + uhd::set_thread_priority_safe(1.0); usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); // Initialize USRP device device->openair0_cfg = openair0_cfg; From 012d333c8ef61f5bf53559d00d984a82d608c1d6 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 10 Feb 2017 17:08:28 +0100 Subject: [PATCH 260/571] tune USRP/USB packet size --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 2ac70b2d82..b2b386ba7d 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -662,14 +662,18 @@ extern "C" { // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); int samples=openair0_cfg[0].sample_rate; - //while ( samples > s->rx_stream->get_max_num_samps()) - samples/=24000; - stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + int max=s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps(); + samples/=10000; + LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); + if ( samples < max ) + stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + LOG_I(PHY,"rx_max_num_samps %u\n", + s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); + for (int i = 0; irx_stream = s->usrp->get_rx_stream(stream_args_rx); - LOG_I(PHY,"rx_max_num_samps %u\n",s->rx_stream->get_max_num_samps()); - + uhd::stream_args_t stream_args_tx("sc16", "sc16"); for (int i = 0; i Date: Sat, 11 Feb 2017 12:20:15 +0100 Subject: [PATCH 261/571] fix: set default value of nb_rb Not sure if necessary, but better do it. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index a24084e24c..bd9b896dfa 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -107,7 +107,7 @@ int rx_pdsch(PHY_VARS_UE *ue, unsigned char aatx,aarx; - unsigned short nb_rb, round; + unsigned short nb_rb = 0, round; int avgs, rb; LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0; From 80f47817d9d9c9a4447b369439d7ae2d51590a8b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 11 Feb 2017 12:21:05 +0100 Subject: [PATCH 262/571] fix: warn if no PDSCH active I doubt the case should happen. If it does, let's print an error, will ease debugging. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index bd9b896dfa..14dfd95640 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -163,6 +163,10 @@ int rx_pdsch(PHY_VARS_UE *ue, dlsch1_harq = NULL; codeword_TB0 = -1; } + else { + LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe); + return(-1); + } beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]; break; From fc46dcff36c8f2a4be710ce2c041582f38ea87b3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 11 Feb 2017 12:23:05 +0100 Subject: [PATCH 263/571] fix format 1A DCI management I am not sure this is enough. To be refined. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 0542c2f658..e246fe4634 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4329,6 +4329,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->first_tx, dlsch0_harq->status, dlsch0_harq->round); + + dlsch[0]->active = 1; + if ((ndi!=dlsch0_harq->DCINdi)|| // DCI has been toggled or this is the first transmission (dlsch0_harq->first_tx==1)) { @@ -4403,6 +4406,10 @@ int generate_ue_dlsch_params_from_dci(int frame, } dlsch[0]->rnti = rnti; dlsch0 = dlsch[0]; + + if (dlsch0_harq->round == 0) + dlsch0_harq->status = ACTIVE; + //printf("Format 1A: harq_pid %d, nb_rb %d, round %d\n",harq_pid,dlsch0_harq->nb_rb,dlsch0_harq->round); break; @@ -4649,7 +4656,6 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); } - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; dlsch[0]->current_harq_pid = harq_pid; From c5f400e9d3c6c26ea7ca0f0e1b7973a7d8dd8b41 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 11 Feb 2017 12:25:46 +0100 Subject: [PATCH 264/571] fix: do not access array before check --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index e246fe4634..90535dbd70 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4637,13 +4637,13 @@ int generate_ue_dlsch_params_from_dci(int frame, break; } - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - if (harq_pid>=8) { LOG_E(PHY,"Format 1: harq_pid=%d >= 8\n", harq_pid); return(-1); } + dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + if((mcs>28) && (dlsch0_harq->round == 0) ) { // DCI false detection From 8f7b6391a51db02580d0faf09edc6bec07de7f2a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 11 Feb 2017 12:31:45 +0100 Subject: [PATCH 265/571] fix: enough to do it once This is done a bit above in the code, no need to do it twice. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 90535dbd70..e38824861b 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4736,7 +4736,6 @@ int generate_ue_dlsch_params_from_dci(int frame, else LOG_E(PHY,"invalid mcs %d\n",mcs); // printf("test: MCS %d, NPRB %d, TBS %d\n",mcs,NPRB,dlsch0_harq->TBS); - dlsch[0]->current_harq_pid = harq_pid; dlsch[0]->active = 1; From 0bcee1e40ede03f022e76ed55e70e691f8055990 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 11 Feb 2017 12:34:05 +0100 Subject: [PATCH 266/571] fix: set mcs, TBS and Qm only if round == 0 Not sure at all about this one, seemed necessary to me, but I don't get the full logic in there. To be refined. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index e38824861b..a905d386ef 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4712,8 +4712,6 @@ int generate_ue_dlsch_params_from_dci(int frame, } } - dlsch0_harq->mcs = mcs; - // this a retransmission if(dlsch0_harq->round) { @@ -4728,17 +4726,25 @@ int generate_ue_dlsch_params_from_dci(int frame, } } - dlsch0_harq->TBS = TBStable[get_I_TBS(mcs)][NPRB-1]; - if (mcs <= 28) - dlsch0_harq->Qm = get_Qm(mcs); - else if (mcs<=31) - dlsch0_harq->Qm = (mcs-28)<<1; - else - LOG_E(PHY,"invalid mcs %d\n",mcs); // printf("test: MCS %d, NPRB %d, TBS %d\n",mcs,NPRB,dlsch0_harq->TBS); dlsch[0]->active = 1; + if (dlsch0_harq->round == 0) { + dlsch0_harq->status = ACTIVE; + // printf("Setting DLSCH process %d to ACTIVE\n",harq_pid); + // MCS and TBS don't change across HARQ rounds + dlsch0_harq->mcs = mcs; + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1]; + + if (mcs <= 28) + dlsch0_harq->Qm = get_Qm(mcs); + else if (mcs<=31) + dlsch0_harq->Qm = (mcs-28)<<1; + else + LOG_E(PHY,"invalid mcs %d\n",mcs); + } + dlsch[0]->rnti = rnti; if (beamforming_mode == 0) From 9e55f8ebcd9d3d31328f077ddcce62591e786d05 Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Sat, 11 Feb 2017 17:57:11 +0200 Subject: [PATCH 267/571] Fixed bug in the establishment of DRBs --- openair2/RRC/LITE/rrc_eNB.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 8b5b012ff1..399d86984e 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -3432,7 +3432,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ) //----------------------------------------------------------------------------- { - int i; + int i, drb_id; #ifdef PDCP_USE_NETLINK int oip_ifup = 0; int dest_ip_offset = 0; @@ -3564,6 +3564,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( if (DRB_configList != NULL) { for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) if (DRB_configList->list.array[i]) { + drb_id = (int)DRB_configList->list.array[i]->drb_Identity; LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, @@ -3580,7 +3581,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (int)DRB_configList->list.array[i]->drb_Identity, (int)*DRB_configList->list.array[i]->logicalChannelIdentity); - if (ue_context_pP->ue_context.DRB_active[i] == 0) { + if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) { /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_ADD, (ue_mod_idP * NB_RB_MAX) + *DRB_configList->list.array[i]->logicalChannelIdentity,UNDEF_SECURITY_MODE); @@ -3588,7 +3589,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (ue_mod_idP * NB_RB_MAX) + (int)*eNB_rrc_inst[ctxt_pP->module_id].DRB_config[ue_mod_idP][i]->logicalChannelIdentity, RADIO_ACCESS_BEARER,Rlc_info_um); */ - ue_context_pP->ue_context.DRB_active[i] = 1; + ue_context_pP->ue_context.DRB_active[drb_id] = 1; LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", @@ -3673,7 +3674,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( } else { // remove LCHAN from MAC/PHY - if (ue_context_pP->ue_context.DRB_active[i] == 1) { + if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); @@ -3687,7 +3688,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( Rlc_info_um); } - ue_context_pP->ue_context.DRB_active[i] = 0; + ue_context_pP->ue_context.DRB_active[drb_id] = 0; LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); From fa432bdd26e728d1f3c853f0d0f7b8a9835ee70a Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 13 Feb 2017 13:58:09 +0100 Subject: [PATCH 268/571] optim measurement function checkcpu() --- targets/RT/USER/lte-ue.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 0f341d29a5..1292fef095 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -528,9 +528,11 @@ static void *UE_thread_rxn_txnp4(void *arg) { initRefTimes(t3); pickTime(current); updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); + check(2200); // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + check(100); if ((sf_type == SF_DL) || (UE->frame_parms.frame_type == FDD) || (sf_type == SF_S)) { @@ -553,7 +555,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { } phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); } - + check(900); if (UE->mac_enabled==1) { ret = mac_xface->ue_scheduler(UE->Mod_id, @@ -583,6 +585,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); } } + check(350); // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || @@ -596,6 +599,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { if (UE->mode != loop_through_memory) phy_procedures_UE_S_TX(UE,0,0,no_relay); updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); + check(300); } @@ -603,10 +607,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { return &UE_thread_rxtx_retval; } -#define RX_OFF_MAX 10 -#define RX_OFF_MIN 5 -#define RX_OFF_MID ((RX_OFF_MAX+RX_OFF_MIN)/2) - /*! * \brief This is the main UE thread. * This thread controls the other three UE threads: From 82403ed1ddc950d2948131dbe39cddecbf7df8de Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Feb 2017 15:07:06 +0100 Subject: [PATCH 269/571] cleanup: comments "Needs to be checked" are not needed --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index a905d386ef..1357f91677 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4530,7 +4530,6 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; dlsch0_harq->dl_power_off = 1; //no power offset - // Needs to be checked dlsch0_harq->codeword=0; LOG_D(PHY,"UE (%x/%d): Subframe %d Format1C DCI: harq_status %d, round %d\n", @@ -4691,7 +4690,6 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq->dl_power_off = 1; //no power offset - // Needs to be checked dlsch0_harq->codeword=0; LOG_D(PHY,"UE (%x/%d): Subframe %d Format1 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, From 4d8e41100ae7e6cf9a7950bff3bf4f9c1763a098 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Feb 2017 15:08:20 +0100 Subject: [PATCH 270/571] fix: check that dlsch[0] is not NULL Note: the dci formats 2, 2A and 1E were not checked, this has to be done. dlsch[0] and dlsch[1] (when applicable) must be checked somehow. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 1357f91677..b7c7b63110 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4001,6 +4001,7 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case format1A: + if (!dlsch[0]) return -1; switch (frame_parms->N_RB_DL) { case 6: @@ -4414,6 +4415,7 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case format1C: + if (!dlsch[0]) return -1; harq_pid = 0; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; @@ -4549,6 +4551,7 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case format1: + if (!dlsch[0]) return -1; switch (frame_parms->N_RB_DL) { case 6: @@ -5868,6 +5871,7 @@ int generate_ue_dlsch_params_from_dci(int frame, break; case format1E_2A_M10PRB: + if (!dlsch[0]) return -1; harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; From 8d7c06b194ce6a147fc37540babb376df5292fc0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Feb 2017 15:10:00 +0100 Subject: [PATCH 271/571] cleanup: setting status to ACTIVE is done below Don't do it twice. The logic is: if ndi changed or it's a first tx then round=0 and later: if round==0 then status=ACTIVE --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index b7c7b63110..44e832605e 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4703,7 +4703,6 @@ int generate_ue_dlsch_params_from_dci(int frame, (dlsch0_harq->first_tx==1)) { // printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx); dlsch0_harq->round=0; - dlsch0_harq->status = ACTIVE; dlsch0_harq->DCINdi = ndi; dlsch[0]->harq_ack[subframe].send_harq_status = 1; From 6ba07564af47a7710134524e7f626271e6e700c3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Feb 2017 15:12:08 +0100 Subject: [PATCH 272/571] fix: do not modify dlsch[0]->g_pucch This is done in another function. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 44e832605e..f7dcad9fcc 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4043,7 +4043,6 @@ int generate_ue_dlsch_params_from_dci(int frame, NPRB = RIV2nb_rb_LUT6[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; } @@ -4101,9 +4100,6 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT25[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; - } if (vrb_type == LOCALIZED) { @@ -4157,9 +4153,6 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT50[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; - } if (vrb_type == LOCALIZED) { @@ -4227,9 +4220,6 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; NPRB = RIV2nb_rb_LUT100[rballoc]; dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - - dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3]; - } if (vrb_type == LOCALIZED) { @@ -5153,12 +5143,10 @@ int generate_ue_dlsch_params_from_dci(int frame, if (dlsch0_harq != NULL) { dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch0->g_pucch += delta_PUCCH_lut[TPC&3]; } if (dlsch1_harq != NULL) { dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch1->g_pucch += delta_PUCCH_lut[TPC&3]; } // assume one layer per codeword (2 antenna port case) From cd6ac4529df4555f59067f2a38747d4eb5465a22 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 8 Feb 2017 08:24:26 -0800 Subject: [PATCH 273/571] addition of TX portion of pucch2a/b --- openair1/PHY/LTE_TRANSPORT/pucch.c | 70 ++++++++++++++++++------------ 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index db671f048c..fc54fcca8f 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -523,29 +523,8 @@ void generate_pucch2x(int32_t **txdataF, pucch2x_modulation(btilde,d,amp); // add extra symbol for 2a/2b - d[20]=0; - d[21]=0; - if (fmt==pucch_format2a) - d[20] = (B2 == 0) ? amp : -amp; - else if (fmt==pucch_format2b) { - switch (B2) { - case 0: - d[20] = amp; - break; - case 1: - d[21] = -amp; - break; - case 2: - d[21] = amp; - break; - case 3: - d[20] = -amp; - break; - default: - AssertFatal(1==0,"Illegal modulation symbol %d for PUCCH %s\n",B2,pucch_format_string[fmt]); - break; - } - } + + #ifdef DEBUG_PUCCH_TX @@ -584,10 +563,47 @@ void generate_pucch2x(int32_t **txdataF, //LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n); } else { - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); - //LOG_I(PHY,"slot %d ofdm# %d ==> dmrs[%d] \n",ns,l,n); - } + if (l==1){ + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); + } + else if (fmt==pucch_format2a) { + d[20]=amp; + d[21]=amp; + if (B2 == 0) { + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); + } + else { + ((int16_t *)&zptr[n])[0] = -((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[1] = -((int32_t)amp*ref_im>>15); + } + //LOG_I(PHY,"slot %d ofdm# %d ==> dmrs[%d] \n",ns,l,n); + } + else if (fmt==pucch_format2b) { + switch (B2) { + case 0: // 1 + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); + break; + case 1: // -j + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[0] = -((int32_t)amp*ref_im>>15); + break; + case 2: // -1 + ((int16_t *)&zptr[n])[0] = -((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[1] = -((int32_t)amp*ref_im>>15); + break; + case 3: // j + ((int16_t *)&zptr[n])[1] = -((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_im>>15); + break; + default: + AssertFatal(1==0,"Illegal modulation symbol %d for PUCCH %s\n",B2,pucch_format_string[fmt]); + break; + } + }// fmt==pucch_format2b + }// l==1 || l==5 alpha_ind = (alpha_ind + n_cs)%12; } // n zptr+=12; From d930378e13209ce0c6eedd1dcc9f2e2a30b6bb03 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 13 Feb 2017 16:05:40 +0100 Subject: [PATCH 274/571] calibration for new firmware/gateware --- targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index a6f7837a70..1e3e1a8cbf 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -320,7 +320,7 @@ rx_gain_calib_table_t calib_table_lmssdr[] = { {2660000000.0,110.0}, // on H PAD {2300000000.0,106.0}, // on H PAD {1880000000.0,106.0}, // on H PAD - {816000000.0,102.0}, // on W PAD + {816000000.0,116.0}, // on W PAD {-1,0}}; From e88d1e739e0ad55b25df47928d41d881b8c7c7f8 Mon Sep 17 00:00:00 2001 From: hbilel Date: Mon, 13 Feb 2017 16:15:47 +0100 Subject: [PATCH 275/571] [OAI-UE] new pucch procedure to support all formats --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 33 +- openair1/PHY/LTE_TRANSPORT/phich.c | 6 +- openair1/PHY/LTE_TRANSPORT/power_control.c | 246 +++---- openair1/PHY/LTE_TRANSPORT/proto.h | 2 +- openair1/PHY/LTE_TRANSPORT/pucch.c | 2 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 2 +- openair1/SCHED/defs.h | 5 +- openair1/SCHED/phy_procedures_lte_common.c | 13 +- openair1/SCHED/phy_procedures_lte_ue.c | 678 ++++++++++-------- openair1/SCHED/pucch_pc.c | 8 +- openair2/RRC/LITE/rrc_UE.c | 25 +- targets/RT/USER/lte-softmodem.c | 24 +- 12 files changed, 575 insertions(+), 469 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 7d14e8aca7..bb93287507 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -3184,7 +3184,7 @@ void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext, #endif } - +#define ONE_OVER_2_Q15 16384 void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp, int **dl_ch_mag, @@ -3203,7 +3203,7 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, uint8_t pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0; rxF0_128 = (__m128i*) &rxdataF_comp[0][jj]; - amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + amp = _mm_set1_epi16(ONE_OVER_2_Q15); // printf("Doing alamouti!\n"); rxF0 = (short*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y @@ -3240,25 +3240,30 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, ch_mag0b[1] = _mm_adds_epi16(ch_mag0b[1],ch_mag1b[1]); // account for 1/sqrt(2) scaling at transmission - ch_mag0[0] = _mm_srai_epi16(ch_mag0[0],1); - ch_mag0[1] = _mm_srai_epi16(ch_mag0[1],1); - ch_mag0b[0] = _mm_srai_epi16(ch_mag0b[0],1); - ch_mag0b[1] = _mm_srai_epi16(ch_mag0b[1],1); + //ch_mag0[0] = _mm_srai_epi16(ch_mag0[0],1); + //ch_mag0[1] = _mm_srai_epi16(ch_mag0[1],1); + //ch_mag0b[0] = _mm_srai_epi16(ch_mag0b[0],1); + //ch_mag0b[1] = _mm_srai_epi16(ch_mag0b[1],1); - rxF0_128[0] = _mm_mulhi_epi16(rxF0_128[0],amp); - rxF0_128[0] = _mm_slli_epi16(rxF0_128[0],1); - rxF0_128[1] = _mm_mulhi_epi16(rxF0_128[1],amp); - rxF0_128[1] = _mm_slli_epi16(rxF0_128[1],1); + //rxF0_128[0] = _mm_mulhi_epi16(rxF0_128[0],amp); + //rxF0_128[0] = _mm_slli_epi16(rxF0_128[0],1); + //rxF0_128[1] = _mm_mulhi_epi16(rxF0_128[1],amp); + //rxF0_128[1] = _mm_slli_epi16(rxF0_128[1],1); + + //rxF0_128[0] = _mm_srai_epi16(rxF0_128[0],1); + //rxF0_128[1] = _mm_srai_epi16(rxF0_128[1],1); if (pilots==0) { ch_mag0[2] = _mm_adds_epi16(ch_mag0[2],ch_mag1[2]); ch_mag0b[2] = _mm_adds_epi16(ch_mag0b[2],ch_mag1b[2]); - ch_mag0[2] = _mm_srai_epi16(ch_mag0[2],1); - ch_mag0b[2] = _mm_srai_epi16(ch_mag0b[2],1); + //ch_mag0[2] = _mm_srai_epi16(ch_mag0[2],1); + //ch_mag0b[2] = _mm_srai_epi16(ch_mag0b[2],1); - rxF0_128[2] = _mm_mulhi_epi16(rxF0_128[2],amp); - rxF0_128[2] = _mm_slli_epi16(rxF0_128[2],1); + //rxF0_128[2] = _mm_mulhi_epi16(rxF0_128[2],amp); + //rxF0_128[2] = _mm_slli_epi16(rxF0_128[2],1); + + //rxF0_128[2] = _mm_srai_epi16(rxF0_128[2],1); ch_mag0+=3; ch_mag1+=3; diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index b46c416706..fe4090bb47 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1375,11 +1375,7 @@ void rx_phich(PHY_VARS_UE *ue, HI16, nseq_PHICH, ngroup_PHICH); - get_Msg3_alloc_ret(&ue->frame_parms, - subframe, - proc->frame_rx, - &ue->ulsch_Msg3_frame[eNB_id], - &ue->ulsch_Msg3_subframe[eNB_id]); + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; // ulsch->harq_processes[harq_pid]->Ndi = 0; ulsch->harq_processes[harq_pid]->round++; diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 4de2b6b775..9f2bf71d27 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -19,126 +19,126 @@ * contact@openairinterface.org */ -#include "PHY/defs.h" -#include "PHY/impl_defs_lte.h" - -//#define DEBUG_PC 1 - -/* -double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0}, - { 5.0/4.0,1.0,3.0/4.0,1.0/2.0}}; -*/ - -double ratioPB[2][4]= {{ 0.00000, -0.96910, -2.21849, -3.97940}, - { 0.96910, 0.00000, -1.24939, -3.01030} -}; - -double pa_values[8]= {-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; - -double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated) -{ - return(pa_values[pdsch_config_dedicated->p_a]); -} - -double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - LTE_eNB_DLSCH_t *dlsch_eNB,int dl_power_off) -{ - double rho_a_dB; - double sqrt_rho_a_lin; - - rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; - - if(!dl_power_off) - rho_a_dB-=10*log10(2); - - sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); - - dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); - -#ifdef DEBUG_PC - printf("sqrt_rho_a(eNB):%d\n",dlsch_eNB->sqrt_rho_a); -#endif - - return(rho_a_dB); -} - -double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - PDSCH_CONFIG_COMMON *pdsch_config_common, - uint8_t n_antenna_port, - LTE_eNB_DLSCH_t *dlsch_eNB, - int dl_power_off) -{ - - double rho_a_dB, rho_b_dB; - double sqrt_rho_b_lin; - - rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off); - - if(n_antenna_port>1) - rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; - else - rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB; - - sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB)); - - dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); - -#ifdef DEBUG_PC - printf("sqrt_rho_b(eNB):%d\n",dlsch_eNB->sqrt_rho_b); -#endif - return(rho_b_dB); -} - - -double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - LTE_UE_DLSCH_t *dlsch_ue, - unsigned char dl_power_off) -{ - - double rho_a_dB; - double sqrt_rho_a_lin; - - rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; - - if(!dl_power_off) - rho_a_dB-=10*log10(2); - - sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); - - dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); - -#ifdef DEBUG_PC - printf("sqrt_rho_a(ue):%d\n",dlsch_ue->sqrt_rho_a); -#endif - - return(rho_a_dB); -} - -double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - PDSCH_CONFIG_COMMON *pdsch_config_common, - uint8_t n_antenna_port, - LTE_UE_DLSCH_t *dlsch_ue, - unsigned char dl_power_off) -{ - - double rho_a_dB, rho_b_dB; - double sqrt_rho_b_lin; - - rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off); - - if(n_antenna_port>1) - rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; - else - rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB; - - sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB)); - - dlsch_ue->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); - -#ifdef DEBUG_PC - printf("sqrt_rho_b(ue):%d\n",dlsch_ue->sqrt_rho_b); -#endif - return(rho_b_dB); -} - - +#include "PHY/defs.h" +#include "PHY/impl_defs_lte.h" + +//#define DEBUG_PC 1 + +/* +double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0}, + { 5.0/4.0,1.0,3.0/4.0,1.0/2.0}}; +*/ + +double ratioPB[2][4]= {{ 0.00000, -0.96910, -2.21849, -3.97940}, + { 0.96910, 0.00000, -1.24939, -3.01030} +}; + +double pa_values[8]= {-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; + +double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated) +{ + return(pa_values[pdsch_config_dedicated->p_a]); +} + +double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, + LTE_eNB_DLSCH_t *dlsch_eNB,int dl_power_off) +{ + double rho_a_dB; + double sqrt_rho_a_lin; + + rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; + + if(!dl_power_off) + rho_a_dB-=10*log10(2); + + sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); + + dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); + +#ifdef DEBUG_PC + printf("sqrt_rho_a(eNB):%d\n",dlsch_eNB->sqrt_rho_a); +#endif + + return(rho_a_dB); +} + +double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, + PDSCH_CONFIG_COMMON *pdsch_config_common, + uint8_t n_antenna_port, + LTE_eNB_DLSCH_t *dlsch_eNB, + int dl_power_off) +{ + + double rho_a_dB, rho_b_dB; + double sqrt_rho_b_lin; + + rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off); + + if(n_antenna_port>1) + rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; + else + rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB; + + sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB)); + + dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); + +#ifdef DEBUG_PC + printf("sqrt_rho_b(eNB):%d\n",dlsch_eNB->sqrt_rho_b); +#endif + return(rho_b_dB); +} + + +double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, + LTE_UE_DLSCH_t *dlsch_ue, + unsigned char dl_power_off) +{ + + double rho_a_dB; + double sqrt_rho_a_lin; + + rho_a_dB = pa_values[ pdsch_config_dedicated->p_a]; + + if(!dl_power_off) + rho_a_dB-=10*log10(2); + + sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB)); + + dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); + +#ifdef DEBUG_PC + printf("p_a %d, rho_a_dB: %f, sqrt_rho_a(ue):%d \n",pdsch_config_dedicated->p_a, rho_a_dB, dlsch_ue->sqrt_rho_a); +#endif + + return(rho_a_dB); +} + +double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, + PDSCH_CONFIG_COMMON *pdsch_config_common, + uint8_t n_antenna_port, + LTE_UE_DLSCH_t *dlsch_ue, + unsigned char dl_power_off) +{ + + double rho_a_dB, rho_b_dB; + double sqrt_rho_b_lin; + + rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off); + + if(n_antenna_port>1) + rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; + else + rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB; + + sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB)); + + dlsch_ue->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); + +#ifdef DEBUG_PC + printf("p_b : %d, rho_b_dB: %f, sqrt_rho_b(ue):%d\n",pdsch_config_common->p_b, rho_b_dB, dlsch_ue->sqrt_rho_b); +#endif + return(rho_b_dB); +} + + diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 52c258762b..c90dcdbde6 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1849,7 +1849,7 @@ void generate_pucch2x(int32_t **txdataF, PUCCH_FMT_t fmt, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint16_t n2_pucch, - uint16_t *payload, + uint8_t *payload, int A, int B2, int16_t amp, diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index fc54fcca8f..795de17ea9 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -473,7 +473,7 @@ void generate_pucch2x(int32_t **txdataF, PUCCH_FMT_t fmt, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint16_t n2_pucch, - uint16_t *payload, + uint8_t *payload, int A, int B2, int16_t amp, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 8edb1eaf94..bcc9a77fb0 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -2067,7 +2067,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, get_ack(&eNB->frame_parms, PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0]->harq_ack, subframe, - eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK); + eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0); } else { // get remote UEs' ack eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0]; eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[1]; diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 5fd5009f1f..3c5f85f6a6 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -305,7 +305,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); @param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH @returns status indicator for PUCCH/PUSCH transmission */ -uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK); +uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK, uint8_t cw_idx); /*! \brief Reset ACK/NACK information @param frame_parms Pointer to DL frame parameter descriptor @@ -317,7 +317,8 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, unsigned char subframe, - unsigned char *o_ACK); + unsigned char *o_ACK, + uint8_t cw_idx); /*! \brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH. Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6) @param frame_parms Pointer to DL frame parameter descriptor diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index 93d3c94b11..ae61f7be0d 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -325,6 +325,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, unsigned char subframe, unsigned char *o_ACK, + uint8_t cw_idx, uint8_t do_reset) // 1 to reset ACK/NACK status : 0 otherwise { uint8_t status=0; @@ -337,7 +338,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, else subframe_dl0 = subframe - 4; - o_ACK[0] = harq_ack[subframe_dl0].ack; + o_ACK[cw_idx] = harq_ack[subframe_dl0].ack; status = harq_ack[subframe_dl0].send_harq_status; if(do_reset) @@ -484,17 +485,19 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, unsigned char subframe, - unsigned char *o_ACK) + unsigned char *o_ACK, + uint8_t cw_idx) { - return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 0); + return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 0); } uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, unsigned char subframe, - unsigned char *o_ACK) + unsigned char *o_ACK, + uint8_t cw_idx) { - return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 1); + return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 1); } diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index e061effadb..69d963173c 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -639,7 +639,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id uint8_t pucch_ack_payload[2]; if (get_ack(&ue->frame_parms, ue->dlsch[eNB_id][0]->harq_ack, - subframe_tx,pucch_ack_payload) > 0) + subframe_tx,pucch_ack_payload,0) > 0) { is_sr_an_subframe = 1; } @@ -737,6 +737,60 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id) } } +PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type, + lte_prefix_type_t cyclic_prefix_type, + uint8_t SR_payload, + uint8_t nb_cw, + uint8_t cqi_status, + uint8_t ri_status) +{ + if((cqi_status == 0) && (ri_status==0)) + { + // PUCCH Format 1 1a 1b + // 1- SR only ==> PUCCH format 1 + // 2- 1bit Ack/Nack with/without SR ==> PUCCH format 1a + // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b + if(nb_cw == 1) + { + return pucch_format1a; + } + if(nb_cw == 2) + { + return pucch_format1b; + } + if(SR_payload == 1) + { + return pucch_format1; + } + } + else + { + // PUCCH Format 2 2a 2b + // 1- CQI only or RI only ==> PUCCH format 2 + // 2- CQI or RI + 1bit Ack/Nack for normal CP ==> PUCCH format 2a + // 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b + // 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2 + if(nb_cw == 0) + { + return pucch_format2; + } + if(cyclic_prefix_type == NORMAL) + { + if(nb_cw == 1) + { + return pucch_format2a; + } + if(nb_cw == 2) + { + return pucch_format2b; + } + } + else + { + return pucch_format2; + } + } +} uint16_t get_n1_pucch(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, harq_status_t *harq_ack, @@ -1022,7 +1076,8 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt overflow = ulsch_start - 9*frame_parms->samples_per_tti; for (aa=0; aanb_antennas_tx; aa++) { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti)); + memset(&ue->common_vars.txdata[aa][ulsch_start],0, + 4*cmin(frame_parms->samples_per_tti-overflow,frame_parms->samples_per_tti)); if (overflow> 0) memset(&ue->common_vars.txdata[aa][0],0,4*overflow); @@ -1381,7 +1436,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ack_status = reset_ack(&ue->frame_parms, ue->dlsch[eNB_id][0]->harq_ack, subframe_tx, - ue->ulsch[eNB_id]->o_ACK); + ue->ulsch[eNB_id]->o_ACK,0); Nbundled = ack_status; first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb; nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; @@ -1394,7 +1449,14 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB // check if we received a PDSCH at subframe_tx - 4 // ==> send ACK/NACK on PUSCH - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status; + if( (ue->dlsch[eNB_id][0]->harq_ack[proc->subframe_rx].send_harq_status) == 1) + { + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1; + } + else + { + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 0; + } #if T_TRACER if(ue->ulsch[eNB_id]->o_ACK[0]) @@ -1421,7 +1483,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB #ifdef DEBUG_PHY_PROC LOG_D(PHY, - "[UE %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", + "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", Mod_id,harq_pid,frame_tx,subframe_tx, first_rb,nb_rb, ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, @@ -1684,17 +1746,79 @@ int16_t get_pucch2_ri(PHY_VARS_UE *ue,int eNB_id) { return(1); } + +void get_pucch_param(PHY_VARS_UE *ue, + UE_rxtx_proc_t *proc, + uint8_t *ack_payload, + PUCCH_FMT_t format, + uint8_t eNB_id, + uint8_t SR, + uint8_t cqi_report, + uint16_t *pucch_resource, + uint8_t *pucch_payload, + uint16_t *plength) +{ + + switch (format) { + case pucch_format1: + { + pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex; + pucch_payload[0] = 0; // payload is ignored in case of format1 + pucch_payload[1] = 0; // payload is ignored in case of format1 + } + break; + + case pucch_format1a: + case pucch_format1b: + { + pucch_resource[0] = get_n1_pucch(ue, + proc, + ue->dlsch[eNB_id][0]->harq_ack, + eNB_id, + ack_payload, + SR); + pucch_payload[0] = ack_payload[0]; + //pucch_payload[1] = ack_payload[1]; + pucch_payload[1] = 1; + } + break; + + case pucch_format2: + { + pucch_resource[0] = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex; + if(cqi_report) + { + pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,plength); + } + else + { + *plength = 1; + pucch_payload[0] = get_pucch2_ri(ue,eNB_id); + } + } + break; + + case pucch_format2a: + case pucch_format2b: + LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n"); + break; + } +} + void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) { - uint8_t pucch_ack_payload[2]; - uint8_t n1_pucch,n2_pucch; + uint8_t pucch_ack_payload[2]; + uint8_t n1_pucch,n2_pucch; + uint16_t pucch_resource; ANFBmode_t bundling_flag; PUCCH_FMT_t format; - uint8_t SR_payload; + uint8_t SR_payload; uint16_t CQI_payload; uint16_t RI_payload; + uint8_t pucch_payload[2]; + uint16_t len; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int frame_tx=proc->frame_tx; @@ -1704,6 +1828,11 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin int tx_amp; int16_t Po_PUCCH; uint8_t ack_status=0; + uint8_t ack_status_cw0=0; + uint8_t ack_status_cw1=0; + uint8_t nb_cw=0; + uint8_t cqi_status=0; + uint8_t ri_status=0; uint8_t ack_sr_generated = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN); @@ -1741,312 +1870,254 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin LOG_D(PHY,"[UE] PUCCH 1b\n"); } - // Check for SR and do ACK/NACK accordingly - if (is_SR_TXOp(ue,proc,eNB_id)==1) { - LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d: got SR_TXOp, Checking for SR for PUSCH from MAC\n", - Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx); - - if (ue->mac_enabled==1) { - SR_payload = mac_xface->ue_get_SR(Mod_id, - CC_id, - frame_tx, - eNB_id, - ue->pdcch_vars[eNB_id]->crnti, - subframe_tx); // subframe used for meas gap - } - else { - SR_payload = 1; - } - - if (SR_payload>0) { - ue->generate_ul_signal[eNB_id] = 1; - LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d got the SR for PUSCH is %d\n", - Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx,SR_payload); - } else { - ue->sr[subframe_tx]=0; - } - } else { - SR_payload=0; + // Part - I + // Collect feedback that should be transmitted at this subframe + // - SR + // - ACK/NACK + // - CQI + // - RI + + SR_payload = 0; + if (is_SR_TXOp(ue,proc,eNB_id)==1) + { + if (ue->mac_enabled==1) { + SR_payload = mac_xface->ue_get_SR(Mod_id, + CC_id, + frame_tx, + eNB_id, + ue->pdcch_vars[eNB_id]->crnti, + subframe_tx); // subframe used for meas gap + } + else { + SR_payload = 1; + } } - - ack_status = get_ack(&ue->frame_parms, - ue->dlsch[eNB_id][0]->harq_ack, - subframe_tx,pucch_ack_payload); - if (ack_status > 0) { - // we need to transmit ACK/NAK in this subframe - - ue->generate_ul_signal[eNB_id] = 1; - ack_sr_generated = 1; - if ((frame_parms->frame_type == TDD) && (SR_payload>0)) { - format = pucch_format1b; - } + ack_status_cw0 = reset_ack(&ue->frame_parms, + ue->dlsch[eNB_id][0]->harq_ack, + subframe_tx, + pucch_ack_payload, + 0); + + ack_status_cw1 = reset_ack(&ue->frame_parms, + ue->dlsch[eNB_id][1]->harq_ack, + subframe_tx, + pucch_ack_payload, + 1); + + nb_cw = ack_status_cw0 + ack_status_cw1; + + cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& + (is_cqi_TXOp(ue,proc,eNB_id)==1)); + + ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && + (is_ri_TXOp(ue,proc,eNB_id)==1)); + + // Part - II + // if nothing to report ==> exit function + if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0)) + { + LOG_I(PHY,"PUCCH No feedback AbsSubframe %d.%d Return \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); + return; + } + + // Part - III + // Decide which PUCCH format should be used if needed + format = get_pucch_format(frame_parms->frame_type, + frame_parms->Ncp, + SR_payload, + nb_cw, + cqi_status, + ri_status); + // Determine PUCCH resources and payload: mandatory for pucch encoding + get_pucch_param(ue, + proc, + pucch_ack_payload, + format, + eNB_id, + SR_payload, + cqi_status, + &pucch_resource, + &pucch_payload, + &len); + + LOG_I(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); + + + // Part - IV + // Generate PUCCH signal + ue->generate_ul_signal[eNB_id] = 1; + + switch (format) { + case pucch_format1: + case pucch_format1a: + case pucch_format1b: + { + if (ue->mac_enabled == 1) { + Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); + } + else { + Po_PUCCH = ue->tx_power_max_dBm; + } + ue->tx_power_dBm[subframe_tx] = Po_PUCCH; + ue->tx_total_RE[subframe_tx] = 12; - n1_pucch = get_n1_pucch(ue, - proc, - ue->dlsch[eNB_id][0]->harq_ack, - eNB_id, - pucch_ack_payload, - SR_payload); - - if (ue->mac_enabled == 1) { - Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); - } - else { - Po_PUCCH = ue->tx_power_max_dBm; - } - ue->tx_power_dBm[subframe_tx] = Po_PUCCH; - ue->tx_total_RE[subframe_tx] = 12; - #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - tx_amp = get_tx_amp(Po_PUCCH, - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 1); + tx_amp = get_tx_amp(Po_PUCCH, + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + 1); #else - tx_amp = AMP; + tx_amp = AMP; #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif - if (SR_payload>0) { - LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", - Mod_id, - ue->dlsch[eNB_id][0]->rnti, - frame_tx % 1024, subframe_tx, - (format == pucch_format1a? "1a": ( - format == pucch_format1b? "1b" : "??")), - pucch_ack_payload[0],pucch_ack_payload[1], - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, - Po_PUCCH, - tx_amp); - } else { - LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", - Mod_id, - ue->dlsch[eNB_id][0]->rnti, - frame_tx, subframe_tx,ue->rx_offset_diff, - (format == pucch_format1a? "1a": ( - format == pucch_format1b? "1b" : "??")), - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload, - Po_PUCCH, - tx_amp); - } + if(format == pucch_format1) + { + LOG_I(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", + Mod_id, + ue->dlsch[eNB_id][0]->rnti, + frame_tx, subframe_tx, + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, + isShortenPucch, + ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, + Po_PUCCH); + } + else + { + if (SR_payload>0) { + LOG_I(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", + Mod_id, + ue->dlsch[eNB_id][0]->rnti, + frame_tx % 1024, subframe_tx, + (format == pucch_format1a? "1a": ( + format == pucch_format1b? "1b" : "??")), + pucch_ack_payload[0],pucch_ack_payload[1], + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, + isShortenPucch, + pucch_resource, + Po_PUCCH, + tx_amp); + } else { + LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + Mod_id, + ue->dlsch[eNB_id][0]->rnti, + frame_tx%1024, subframe_tx,ue->rx_offset_diff, + (format == pucch_format1a? "1a": ( + format == pucch_format1b? "1b" : "??")), + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, + isShortenPucch, + pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload, + Po_PUCCH, + tx_amp); + } + } #if T_TRACER - if(pucch_ack_payload[0]) - { - LOG_I(PHY,"PUCCH ACK\n"); - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), - T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); - } - else - { - LOG_I(PHY,"PUCCH NACK\n"); - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), - T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); - } + if(pucch_payload[0]) + { + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), + T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); + } + else + { + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), + T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); + } #endif - - if (abstraction_flag == 0) { - - generate_pucch1x(ue->common_vars.txdataF, - &ue->frame_parms, - ue->ncs_cell, - format, - &ue->pucch_config_dedicated[eNB_id], - n1_pucch, - isShortenPucch, // shortened format - pucch_ack_payload, - tx_amp, - subframe_tx); - - } else { + + if (abstraction_flag == 0) { + + generate_pucch1x(ue->common_vars.txdataF, + &ue->frame_parms, + ue->ncs_cell, + format, + &ue->pucch_config_dedicated[eNB_id], + pucch_resource, + isShortenPucch, // shortened format + pucch_payload, + tx_amp, + subframe_tx); + + } else { #ifdef PHY_ABSTRACTION - LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload); - generate_pucch_emul(ue, - proc, - format, - ue->frame_parms.pucch_config_common.nCS_AN, - pucch_ack_payload, - SR_payload); + LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload); + generate_pucch_emul(ue, + proc, + format, + ue->frame_parms.pucch_config_common.nCS_AN, + pucch_payload, + SR_payload); #endif - } - } else if (SR_payload==1) { // no ACK/NAK but SR is triggered by MAC + } + } + break; - ack_sr_generated = 1; - if (ue->mac_enabled == 1) { - Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,pucch_format1); - } - else { - Po_PUCCH = ue->tx_power_max_dBm; - } - ue->tx_power_dBm[subframe_tx] = Po_PUCCH; - ue->tx_total_RE[subframe_tx] = 12; - -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - tx_amp = get_tx_amp(Po_PUCCH, - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 1); -#else - tx_amp = AMP; -#endif -#if T_TRACER - T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); -#endif - LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", - Mod_id, - ue->dlsch[eNB_id][0]->rnti, - frame_tx, subframe_tx, - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, - Po_PUCCH); - - if (abstraction_flag == 0) { - - generate_pucch1x(ue->common_vars.txdataF, - &ue->frame_parms, - ue->ncs_cell, - pucch_format1, - &ue->pucch_config_dedicated[eNB_id], - ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, - isShortenPucch, // shortened format - pucch_ack_payload, // this is ignored anyway, we just need a pointer - tx_amp, - subframe_tx); - } else { - LOG_D(PHY,"Calling generate_pucch_emul ...\n"); - generate_pucch_emul(ue, - proc, - pucch_format1, - ue->frame_parms.pucch_config_common.nCS_AN, - pucch_ack_payload, - SR_payload); - - } - } // SR_Payload==1 - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT); - - // PUCCH 2x - - if (ack_sr_generated == 0) { // we have not generated ACK/NAK/SR in this subframe - - n2_pucch = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex; - // only use format2 for now, i.e. now ACK/NAK - CQI multiplexing - format = pucch_format2; - - // Periodic CQI report - if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& - (is_cqi_TXOp(ue,proc,eNB_id)==1)){ + case pucch_format2: + { if (ue->mac_enabled == 1) { - Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); + Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); } else { - Po_PUCCH = ue->tx_power_max_dBm; + Po_PUCCH = ue->tx_power_max_dBm; } ue->tx_power_dBm[subframe_tx] = Po_PUCCH; ue->tx_total_RE[subframe_tx] = 12; - + #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) tx_amp = get_tx_amp(Po_PUCCH, - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 1); + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + 1); #else tx_amp = AMP; #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif - - int len; - // get the payload : < 12 bits, returned in len - CQI_payload = get_pucch2_cqi(ue,eNB_id,&len); - generate_pucch2x(ue->common_vars.txdataF, - &ue->frame_parms, - ue->ncs_cell, - format, - &ue->pucch_config_dedicated[eNB_id], - n2_pucch, - &CQI_payload, - len, // A - 0, // B2 not needed - tx_amp, - subframe_tx, - ue->pdcch_vars[eNB_id]->crnti); - ue->generate_ul_signal[eNB_id] = 1; - - LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (CQI %d), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", - Mod_id, - ue->dlsch[eNB_id][0]->rnti, - frame_tx, subframe_tx,CQI_payload, - n2_pucch, - Po_PUCCH, - isShortenPucch, - tx_amp); - - } - // Periodic RI report - else if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && - (is_ri_TXOp(ue,proc,eNB_id)==1)){ - - if (ue->mac_enabled == 1) { - Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); - } - else { - Po_PUCCH = ue->tx_power_max_dBm; - } - ue->tx_power_dBm[subframe_tx] = Po_PUCCH; - ue->tx_total_RE[subframe_tx] = 12; -#if T_TRACER - T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); -#endif -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - tx_amp = get_tx_amp(Po_PUCCH, - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 1); -#else - tx_amp = AMP; -#endif - LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", - Mod_id, - ue->dlsch[eNB_id][0]->rnti, - frame_tx, subframe_tx, - n2_pucch, - Po_PUCCH, - isShortenPucch, - tx_amp); - - RI_payload = get_pucch2_ri(ue,eNB_id); + LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", + Mod_id, + ue->dlsch[eNB_id][0]->rnti, + frame_tx%1024, subframe_tx, + n2_pucch, + Po_PUCCH, + isShortenPucch, + tx_amp); generate_pucch2x(ue->common_vars.txdataF, - &ue->frame_parms, - ue->ncs_cell, - format, - &ue->pucch_config_dedicated[eNB_id], - n2_pucch, - &RI_payload, - 1, // A - 0, // B2 not needed - tx_amp, - subframe_tx, - ue->pdcch_vars[eNB_id]->crnti); - - ue->generate_ul_signal[eNB_id] = 1; - } + &ue->frame_parms, + ue->ncs_cell, + format, + &ue->pucch_config_dedicated[eNB_id], + pucch_resource, + pucch_payload, + len, // A + 0, // B2 not needed + tx_amp, + subframe_tx, + ue->pdcch_vars[eNB_id]->crnti); + } + break; + + case pucch_format2a: + LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n", + Mod_id, + ue->dlsch[eNB_id][0]->rnti, + frame_tx%1024, subframe_tx); + break; + case pucch_format2b: + LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n", + Mod_id, + ue->dlsch[eNB_id][0]->rnti, + frame_tx%1024, subframe_tx); + break; + default: + break; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT); @@ -2186,14 +2257,13 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui reset_ack(&ue->frame_parms, ue->dlsch[eNB_id][0]->harq_ack, subframe_tx, - ue->ulsch[eNB_id]->o_ACK); + ue->ulsch[eNB_id]->o_ACK,0); + + reset_ack(&ue->frame_parms, + ue->dlsch_SI[eNB_id]->harq_ack, + subframe_tx, + ue->ulsch[eNB_id]->o_ACK,0); - if (ue->dlsch_SI[eNB_id]) - reset_ack(&ue->frame_parms, - ue->dlsch_SI[eNB_id]->harq_ack, - subframe_tx, - ue->ulsch[eNB_id]->o_ACK); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_tx); @@ -2606,19 +2676,19 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin #endif } else { - + /* LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n", ue->Mod_id,frame_rx, subframe_rx); - /* + LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset); write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1); - write_output("H00.m","h00",&(ue->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1); - write_output("H10.m","h10",&(ue->common_vars.common_vars_rx_data_per_thread[0].dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1); + write_output("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1); + write_output("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1); - write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1); + write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1); write_output("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1); write_output("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1); write_output("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4); @@ -2754,7 +2824,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #endif - LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt); + LOG_I(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt); ue->pdcch_vars[eNB_id]->dci_received += dci_cnt; @@ -2771,9 +2841,9 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (dci_alloc_rx[i].format != format0)) { - LOG_D(PHY,"[UE %d][DCI][PDSCH %x] frame %d, subframe %d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n", + LOG_I(PHY,"[UE %d][DCI][PDSCH %x] frame %d, subframe %d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n", ue->Mod_id,dci_alloc_rx[i].rnti, - frame_rx,subframe_rx, + frame_rx%1024,subframe_rx, dci_alloc_rx[i].format, ue->pdcch_vars[eNB_id]->num_pdcch_symbols, ue->pdcch_vars[eNB_id]->nCCE[subframe_rx], @@ -2802,8 +2872,10 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint // update TPC for PUCCH if((dci_alloc_rx[i].format == format1) || (dci_alloc_rx[i].format == format1A) || + (dci_alloc_rx[i].format == format1B) || (dci_alloc_rx[i].format == format2) || - (dci_alloc_rx[i].format == format2A)) + (dci_alloc_rx[i].format == format2A) || + (dci_alloc_rx[i].format == format2B)) { ue->dlsch[eNB_id][0]->g_pucch += ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->delta_PUCCH; } @@ -2970,14 +3042,17 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #endif } - } - /* else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) && + } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) && (dci_alloc_rx[i].format == format0)) { // UE could belong to more than one CBA group // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups] #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n", ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); + /* + if (((frame_rx%100) == 0) || (frame_rx < 20)) + dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); + */ #endif ue->ulsch_no_allocation_counter[eNB_id] = 0; @@ -3001,8 +3076,9 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint LOG_D(PHY,"[UE %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); #endif ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++; - } - */ + } + } + else { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti, diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c index e19d3ad8c4..5bc03bb58d 100644 --- a/openair1/SCHED/pucch_pc.c +++ b/openair1/SCHED/pucch_pc.c @@ -88,17 +88,17 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u } if (pucch_fmt!=pucch_format1) { - LOG_D(PHY,"[UE %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n", + LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe, + ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), ue->dlsch[eNB_id][0]->g_pucch); } else { - LOG_D(PHY,"[UE %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n", + LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe, + ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 8a8aaf73ba..8039fcfb75 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -1095,6 +1095,17 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo, (char*)radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo, sizeof(physicalConfigDedicated2->antennaInfo)); + + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode = + radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.codebookSubsetRestriction = + radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.codebookSubsetRestriction; + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection = + radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection; + + LOG_I(PHY,"New Transmission Mode %d \n",radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); + LOG_I(PHY,"Configured Transmission Mode %d \n",UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode); + } else { @@ -3131,13 +3142,13 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 ) sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig ); LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission : %d\n", sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission ); -#if 0 - /* TODO: test this - commented for the moment */ - if (sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) - LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts : %ld\n", - /* TODO: check that it's okay to access [0] */ - sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts[0] ); -#endif + + if(sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) + { + LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts : %ld\n", + /* TODO: check that it's okay to access [0] */ + sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts[0] ); + } } // uplinkPowerControlCommon diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 5342a1b665..b37d5bc1c4 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -209,6 +209,8 @@ int chain_offset=0; int phy_test = 0; uint8_t usim_test = 0; +uint8_t nb_antenna_tx = 1; +uint8_t nb_antenna_rx = 1; char ref[128] = "internal"; char channels[128] = "0"; @@ -379,6 +381,7 @@ void help (void) { printf(" --ue-rxgain set UE RX gain\n"); printf(" --ue-rxgain-off external UE amplifier offset\n"); printf(" --ue-txgain set UE TX gain\n"); + printf(" --ue-nb-ant-rx set UE number of rx antennas "); printf(" --ue-scan_carrier set UE to scan around carrier\n"); printf(" --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n"); printf(" --mmapped-dma sets flag for improved EXMIMO UE performance\n"); @@ -686,6 +689,8 @@ static void get_options (int argc, char **argv) LONG_OPTION_RXGAIN, LONG_OPTION_RXGAINOFF, LONG_OPTION_TXGAIN, + LONG_OPTION_NBRXANT, + LONG_OPTION_NBTXANT, LONG_OPTION_SCANCARRIER, LONG_OPTION_MAXPOWER, LONG_OPTION_DUMP_FRAME, @@ -714,7 +719,9 @@ static void get_options (int argc, char **argv) {"calib-prach-tx", no_argument, NULL, LONG_OPTION_CALIB_PRACH_TX}, {"ue-rxgain", required_argument, NULL, LONG_OPTION_RXGAIN}, {"ue-rxgain-off", required_argument, NULL, LONG_OPTION_RXGAINOFF}, - {"ue-txgain", required_argument, NULL, LONG_OPTION_TXGAIN}, + {"ue-txgain", required_argument, NULL, LONG_OPTION_TXGAIN}, + {"ue-nb-ant-rx", required_argument, NULL, LONG_OPTION_NBRXANT}, + {"ue-nb-ant-tx", required_argument, NULL, LONG_OPTION_NBTXANT}, {"ue-scan-carrier", no_argument, NULL, LONG_OPTION_SCANCARRIER}, {"ue-max-power", required_argument, NULL, LONG_OPTION_MAXPOWER}, {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME}, @@ -802,7 +809,12 @@ static void get_options (int argc, char **argv) tx_gain[0][i] = atof(optarg); break; - + case LONG_OPTION_NBRXANT: + nb_antenna_rx = atof(optarg); + break; + case LONG_OPTION_NBTXANT: + nb_antenna_tx = atof(optarg); + break; case LONG_OPTION_SCANCARRIER: UE_scan_carrier=1; @@ -1353,7 +1365,7 @@ void init_openair0() { openair0_cfg[card].clock_source = clock_source; - openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx)); + openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); for (i=0; i<4; i++) { @@ -1548,9 +1560,11 @@ int main( int argc, char **argv ) for (CC_id=0; CC_idnb_antennas_tx = 1; - frame_parms[CC_id]->nb_antennas_rx = 1; + frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; + frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later + + LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); } init_ul_hopping(frame_parms[CC_id]); From 58052152273b537207fccf85c86bfa3152fbd4f9 Mon Sep 17 00:00:00 2001 From: hbilel Date: Mon, 13 Feb 2017 16:46:28 +0100 Subject: [PATCH 276/571] [OAI-UE] fix freq offset correction during cell scan --- openair1/SCHED/phy_procedures_lte_ue.c | 4 ++-- targets/RT/USER/lte-ue.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 69d963173c..252ed1aedb 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1917,7 +1917,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // if nothing to report ==> exit function if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0)) { - LOG_I(PHY,"PUCCH No feedback AbsSubframe %d.%d Return \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); + LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d Return \n", frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); return; } @@ -2824,7 +2824,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #endif - LOG_I(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt); + LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt); ue->pdcch_vars[eNB_id]->dci_received += dci_cnt; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index ed93f44aa9..5c821a4176 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -455,12 +455,13 @@ static void *UE_thread_synch(void *arg) openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; if (freq_offset >= 0) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += UE->common_vars.freq_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); } else { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); } + LOG_I(PHY," new cell parameters and frequency-offset %f freq_offset %d UE->common_vars.freq_offset %d \n", openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i], freq_offset, UE->common_vars.freq_offset); openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; freq_offset=0; From aefb958a6fc5489360d32b47dc240cc690f6fcfc Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 13 Feb 2017 17:12:10 +0100 Subject: [PATCH 277/571] tx calibration for LimeSDR band 13 --- .../CONF/enb.band13.tm1.50PRB.lmssdr.conf | 159 +++++++++--------- .../CONF/enb.band13.tm1.lmssdr.conf | 12 +- .../CONF/enb.band7.tm1.50PRB.lmssdr.conf | 14 +- 3 files changed, 94 insertions(+), 91 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf index b81ac861f6..3eea96059b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf @@ -23,85 +23,89 @@ eNBs = component_carriers = ( { - frame_type = "FDD"; - tdd_config = 3; - tdd_config_s = 0; - prefix_type = "NORMAL"; - eutra_band = 13; - downlink_frequency = 751000000L; - uplink_frequency_offset = 31000000; - Nid_cell = 0; - N_RB_DL = 50; - Nid_cell_mbsfn = 0; - nb_antennas_tx = 1; - nb_antennas_rx = 1; - tx_gain = 90; - rx_gain = 125; - prach_root = 0; - prach_config_index = 0; - prach_high_speed = "DISABLE"; - prach_zero_correlation = 1; - prach_freq_offset = 2; - pucch_delta_shift = 1; - pucch_nRB_CQI = 1; - pucch_nCS_AN = 0; - pucch_n1_AN = 32; - pdsch_referenceSignalPower = -20; - pdsch_p_b = 0; - pusch_n_SB = 1; - pusch_enable64QAM = "DISABLE"; - pusch_hoppingMode = "interSubFrame"; - pusch_hoppingOffset = 0; - pusch_groupHoppingEnabled = "ENABLE"; - pusch_groupAssignment = 0; - pusch_sequenceHoppingEnabled = "DISABLE"; - pusch_nDMRS1 = 1; - phich_duration = "NORMAL"; - phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; - srs_SubframeConfig =; - srs_ackNackST =; - srs_MaxUpPts =;*/ + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 13; + downlink_frequency = 751000000L; + uplink_frequency_offset = 31000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 20; + rx_gain = 116; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -30; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; - pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; - msg3_delta_Preamble = 6; - pucch_deltaF_Format1 = "deltaF2"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; - pucch_deltaF_Format2b = "deltaF0"; + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; - rach_numberOfRA_Preambles = 64; - rach_preamblesGroupAConfig = "DISABLE"; - /* - rach_sizeOfRA_PreamblesGroupA = ; - rach_messageSizeGroupA = ; - rach_messagePowerOffsetGroupB = ; - */ - rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -108; - rach_preambleTransMax = 10; - rach_raResponseWindowSize = 10; - rach_macContentionResolutionTimer = 48; - rach_maxHARQ_Msg3Tx = 4; + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; - pcch_default_PagingCycle = 128; - pcch_nB = "oneT"; - bcch_modificationPeriodCoeff = 2; - ue_TimersAndConstants_t300 = 1000; - ue_TimersAndConstants_t301 = 1000; - ue_TimersAndConstants_t310 = 1000; - ue_TimersAndConstants_t311 = 10000; - ue_TimersAndConstants_n310 = 20; - ue_TimersAndConstants_n311 = 1; + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; } ); - srb1_parameters : { # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] @@ -131,9 +135,8 @@ eNBs = SCTP_OUTSTREAMS = 2; }; - ////////// MME parameters: - mme_ip_address = ( { ipv4 = "127.0.0.3"; + mme_ip_address = ( { ipv4 = "192.168.12.70"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -142,11 +145,11 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.150/24"; - ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.4/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.150/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf index 266e5aae25..02ff6b3e0b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf @@ -31,12 +31,12 @@ eNBs = downlink_frequency = 751000000L; uplink_frequency_offset = 31000000; Nid_cell = 0; - N_RB_DL = 25; + N_RB_DL = 50; Nid_cell_mbsfn = 0; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 90; - rx_gain = 107; + tx_gain = 70; + rx_gain = 116; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -46,7 +46,7 @@ eNBs = pucch_nRB_CQI = 1; pucch_nCS_AN = 0; pucch_n1_AN = 32; - pdsch_referenceSignalPower = -17; + pdsch_referenceSignalPower = -30; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; @@ -64,9 +64,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -90; + pusch_p0_Nominal = -96; pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; + pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf index e12acef703..22bcae3c80 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf @@ -39,8 +39,8 @@ eNBs = nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 100; - rx_gain = 111; + tx_gain = 70; + rx_gain = 116; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -136,7 +136,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "127.0.0.3"; + mme_ip_address = ( { ipv4 = "192.168.12.70"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -145,11 +145,11 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.150/24"; - ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.150/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; From 14aa96787af8f2f4dd2daa6b2daff913440c7c2f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Feb 2017 17:47:47 +0100 Subject: [PATCH 278/571] bugfix: eNB_id should have been UE_id --- targets/SIMU/USER/channel_sim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index a884fd5624..681500ce03 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -327,8 +327,8 @@ void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_N eNB_output_mask[UE_id]=0; - double *r_re_p[2] = {r_re_DL[eNB_id][0],r_re_DL[eNB_id][1]}; - double *r_im_p[2] = {r_im_DL[eNB_id][0],r_im_DL[eNB_id][1]}; + double *r_re_p[2] = {r_re_DL[UE_id][0],r_re_DL[UE_id][1]}; + double *r_im_p[2] = {r_im_DL[UE_id][0],r_im_DL[UE_id][1]}; #ifdef DEBUG_SIM rx_pwr = signal_energy_fp(r_re_p,r_im_p,nb_antennas_rx,frame_parms->ofdm_symbol_size,sf_offset)/(12.0*frame_parms->N_RB_DL); From b904ce7978edbea56ddee0898bac1f0ca31ded2f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Feb 2017 17:58:11 +0100 Subject: [PATCH 279/571] rewrite synchronisation in oaisim/channel simulation The idea is as follows. oaisim waits for all tasks to be done for a TTI. To do so it waits for last_rx_timestamp == current_rx_timestamp, for all UEs and eNBs. When it's done, it increases current_rx_timestamp by samples_per_tti, to inform UEs and eNBs that a new TTI is ready. In the functions [UE|eNB]_trx_read, we wait for a new TTI to be ready, that is we wait for current_rx_timestamp != last_rx_timestamp. The UE has also to wait for processing threads to be done. In the eNB it's not necessary because the processing is all done in one thread, that is: read subframe, process this subframe, emit subframe+4, and then back to read subframe. The code is not clean. We should not use usleep but semaphores. Also, do_[DL|UL]_sig should not read from rxdata and write to txdata, but use internal buffers. The functions [UE|eNB]_trx_read should call do_[DL|UL]_sig and then copy from the internal buffers of the channel simulator into rxdata. The functions [UE|eNB]_trx_write should write data passed into the internal buffers of the channel simulator. --- targets/SIMU/USER/oaisim.c | 44 ++++---- targets/SIMU/USER/oaisim_functions.c | 146 +++++++++++++++------------ 2 files changed, 103 insertions(+), 87 deletions(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index d5f49d9faf..723da842bb 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -457,7 +457,8 @@ l2l1_task_state_t l2l1_state = L2L1_WAITTING; extern openair0_timestamp current_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs]; extern openair0_timestamp current_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs]; - +extern openair0_timestamp last_eNB_rx_timestamp[NUMBER_OF_eNB_MAX][MAX_NUM_CCs]; +extern openair0_timestamp last_UE_rx_timestamp[NUMBER_OF_UE_MAX][MAX_NUM_CCs]; /*------------------------------------------------------------------------------*/ void * @@ -731,38 +732,41 @@ l2l1_task (void *args_p) clear_eNB_transport_info (oai_emulation.info.nb_enb_local); - CC_id=0; int all_done=0; while (all_done==0) { - pthread_mutex_lock(&subframe_mutex); - int subframe_eNB_mask_local = subframe_eNB_mask; - int subframe_UE_mask_local = subframe_UE_mask; - pthread_mutex_unlock(&subframe_mutex); - LOG_D(EMU,"Frame %d, Subframe %d: Checking masks %x,%x\n",frame,sf,subframe_eNB_mask,subframe_UE_mask); - if ((subframe_eNB_mask_local == ((1<frame_parms.samples_per_tti; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + current_eNB_rx_timestamp[eNB_inst][CC_id] += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti; } for (UE_inst = 0; UE_instframe_parms.samples_per_tti; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) + current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti; } for (eNB_inst = oai_emulation.info.first_enb_local; diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 130a339390..bcb6b7074c 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -998,13 +998,15 @@ int UE_trx_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { extern pthread_mutex_t subframe_mutex; extern int subframe_eNB_mask,subframe_UE_mask; -int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - +int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) +{ + int ret = nsamps; int eNB_id = device->Mod_id; int CC_id = device->CC_id; int subframe; - int sample_count=0; + int read_samples, max_samples; + openair0_timestamp last = last_eNB_rx_timestamp[eNB_id][CC_id]; *ptimestamp = last_eNB_rx_timestamp[eNB_id][CC_id]; @@ -1014,49 +1016,55 @@ int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void * (*ptimestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10); // if we're at a subframe boundary generate UL signals for this eNB - while (sample_count max_samples) + read_samples = max_samples; + + last += read_samples; + nsamps -= read_samples; + + if (current_eNB_rx_timestamp[eNB_id][CC_id] == last) { + subframe = (last/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10; + //subframe = (subframe+9) % 10; + + LOG_D(PHY,"eNB_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n", + subframe,(unsigned long long)*ptimestamp, + (unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id]); - subframe = (last_eNB_rx_timestamp[eNB_id][CC_id]/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10; - LOG_D(PHY,"eNB_trx_read generating UL subframe %d (Ts %llu, current TS %llu)\n", - subframe,(unsigned long long)*ptimestamp, - (unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id]); - - do_UL_sig(UE2eNB, - enb_data, - ue_data, - subframe, - 0, // abstraction_flag - &PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms, - 0, // frame is only used for abstraction - eNB_id, - CC_id); - - last_eNB_rx_timestamp[eNB_id][CC_id] += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti; - sample_count += PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti; + do_UL_sig(UE2eNB, + enb_data, + ue_data, + subframe, + 0, // abstraction_flag + &PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms, + 0, // frame is only used for abstraction + eNB_id, + CC_id); + + last_eNB_rx_timestamp[eNB_id][CC_id] = last; + } } + last_eNB_rx_timestamp[eNB_id][CC_id] = last; - - return(nsamps); + return ret; } -int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - +int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) +{ + int ret = nsamps; int UE_id = device->Mod_id; int CC_id = device->CC_id; int subframe; - int sample_count=0; - int read_size; + int read_samples, max_samples; + openair0_timestamp last = last_UE_rx_timestamp[UE_id][CC_id]; *ptimestamp = last_UE_rx_timestamp[UE_id][CC_id]; @@ -1065,14 +1073,19 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** (unsigned long long)last_UE_rx_timestamp[UE_id][CC_id], cc); - if (nsamps < PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti) - read_size = nsamps; - else - read_size = PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti; - - while (sample_countproc.proc_rxtx[i].instance_cnt_rxtx >= 0) ready = 0; + if (UE->proc.instance_cnt_synch >= 0) ready = 0; + if (ready) break; + usleep(500); + } + while (current_UE_rx_timestamp[UE_id][CC_id] == last) { LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); usleep(500); @@ -1080,40 +1093,39 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); - // tell top-level we are busy - pthread_mutex_lock(&subframe_mutex); - subframe_UE_mask|=(1< max_samples) + read_samples = max_samples; + last += read_samples; + nsamps -= read_samples; - // otherwise we have one subframe here so generate the received signal - subframe = (last_UE_rx_timestamp[UE_id][CC_id]/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10; - if ((last_UE_rx_timestamp[UE_id][CC_id]%PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti) > 0) - subframe++; + if (current_UE_rx_timestamp[UE_id][CC_id] == last) { + // we have one subframe here so generate the received signal + subframe = (last/PHY_vars_UE_g[UE_id][CC_id]->frame_parms.samples_per_tti)%10; + //subframe = (subframe+9) % 10; - last_UE_rx_timestamp[UE_id][CC_id] += read_size; - sample_count += read_size; - - if (subframe > 9) - return(nsamps); - - LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n", - subframe,(unsigned long long)*ptimestamp, - (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]); - do_DL_sig(eNB2UE, - enb_data, - ue_data, - subframe, - 0, //abstraction_flag, - &PHY_vars_UE_g[UE_id][CC_id]->frame_parms, - UE_id, - CC_id); + LOG_D(PHY,"UE_trx_read generating DL subframe %d (Ts %llu, current TS %llu)\n", + subframe,(unsigned long long)*ptimestamp, + (unsigned long long)current_UE_rx_timestamp[UE_id][CC_id]); + do_DL_sig(eNB2UE, + enb_data, + ue_data, + subframe, + 0, //abstraction_flag, + &PHY_vars_UE_g[UE_id][CC_id]->frame_parms, + UE_id, + CC_id); + last_UE_rx_timestamp[UE_id][CC_id] = last; + } } + last_UE_rx_timestamp[UE_id][CC_id] = last; - return(nsamps); + return ret; } int eNB_trx_write(openair0_device *device,openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { From 9ecae1837cc94bf9fddcc2c689fb0a62519c31b0 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Mon, 13 Feb 2017 18:15:07 +0100 Subject: [PATCH 280/571] [OAI-UE] fix ack/nack reporting on pusch --- openair1/SCHED/phy_procedures_lte_ue.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 252ed1aedb..75abe5d023 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1449,14 +1449,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB // check if we received a PDSCH at subframe_tx - 4 // ==> send ACK/NACK on PUSCH - if( (ue->dlsch[eNB_id][0]->harq_ack[proc->subframe_rx].send_harq_status) == 1) - { - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1; - } - else - { - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 0; - } + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1; #if T_TRACER if(ue->ulsch[eNB_id]->o_ACK[0]) @@ -1473,7 +1466,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } #endif - LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n", + LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", Mod_id, ue->ulsch[eNB_id]->rnti, frame_tx,subframe_tx, From f66f6e49cb936157a1b299add65911ef50c59105 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 14 Feb 2017 10:25:23 +0100 Subject: [PATCH 281/571] deal with empty subframes at UE side even in oaisim The memset was also too big. It should only clear one subframe. Only tested without abstraction. Abstraction does not work for the moment anyway, but just to keep that in mind. --- openair1/SCHED/phy_procedures_lte_ue.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index bfe4c82bdc..052cb21f47 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -986,8 +986,8 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; int ulsch_start; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int overflow=0; +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int k,l; int dummy_tx_buffer[3840*4] __attribute__((aligned(16))); #endif @@ -1015,14 +1015,15 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance; #endif //else EXMIMO -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) if (empty_subframe) { //#if 1 overflow = ulsch_start - 9*frame_parms->samples_per_tti; for (aa=0; aanb_antennas_tx; aa++) { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti)); + //memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti)); + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*cmin(frame_parms->samples_per_tti-overflow,frame_parms->samples_per_tti)); if (overflow> 0) memset(&ue->common_vars.txdata[aa][0],0,4*overflow); @@ -1043,7 +1044,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif*/ return; } -#endif +//#endif if ((frame_tx%100) == 0) LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n", From 614d6bbe2af5c34f3bace7a8cb5003f07a8931b2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 14 Feb 2017 10:58:06 +0100 Subject: [PATCH 282/571] ue_ip: use correct instance The problem was the following. Run oaisim with two UEs: sudo ../cmake_targets/oaisim_build_oai/build/oaisim -O enb.conf -u2 -s15 -AAWGN -y1 -b1 -Q0 Then wait for both UEs to be connected. The interfaces "oip1" and "oip2" are activated, with IP addresses 192.172.0.2 for the first UE and 192.172.0.3 for the second. Then on the EPC machine, do: ping 192.172.0.3 No reply. On the oaisim machine, we see that the packets are sent to "oip1" instead of "oip2". The fix may break softmodem UE. The inst was forced to "1" for some reason. To be checked. --- openair2/NETWORK_DRIVER/UE_IP/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 8696801597..1ea5df0d30 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -345,7 +345,7 @@ void ue_ip_common_wireless2ip(struct nlmsghdr *nlh_pP) ue_ip_common_class_wireless2ip(pdcph_p->data_size, (unsigned char *)NLMSG_DATA(nlh_pP) + UE_IP_PDCPH_SIZE, - 1, //pdcph_p->inst, + pdcph_p->inst, pdcph_p->rb_id); } From 09139ab01854ece4dc6fae3bee447a412bb9cdb9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 14 Feb 2017 15:38:51 +0100 Subject: [PATCH 283/571] fix build_oai - the option --UE was abused! Let's introduce --UE-conf-nvram and --UE-gen-nvram - the option name --UE-OUTPUT was not clear and is now replaced by --UE-gen-nvram - the new options are described when running ./build_oai -h - print_help has been modified (' replaced by ") to print $conf_nvram_path and $gen_nvram_path --- cmake_targets/build_oai | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 7c438aabd8..5551d232ee 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -57,17 +57,20 @@ CMAKE_BUILD_TYPE="" UE_AUTOTEST_TRACE="False" trap handle_ctrl_c INT +gen_nvram_path=$OPENAIR_DIR/targets/bin +conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf + function print_help() { - echo_info ' + echo_info " This program installs OpenAirInterface Software You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14 Options -h This help -c | --clean - Erase all files to make a rebuild from start" + Erase all files to make a rebuild from start -C | --clean-all - Erase all files made by previous compilations, installations" + Erase all files made by previous compilations, installations --clean-kernel Erase previously installed features in kernel: iptables, drivers, ... -I | --install-external-packages @@ -83,6 +86,10 @@ Options Makes the LTE softmodem --UE Makes the UE specific parts (ue_ip, usim, nvram) from the given configuration file +--UE-conf-nvram [configuration file] + Specify conf_nvram_path (default \"$conf_nvram_path\") +--UE-gen-nvram [output path] + Specify gen_nvram_path (default \"$gen_nvram_path\") --RRH Makes the RRH -a | --agent @@ -97,7 +104,7 @@ Options ETHERNET , None Adds this trasport protocol support in compilation --oaisim - Makes the oaisim simulator. Hardware will be defaulted to "None". + Makes the oaisim simulator. Hardware will be defaulted to \"None\". --phy_simulators Makes the unitary tests Layer 1 simulators --core_simulators @@ -140,15 +147,12 @@ Usage (first build): Usage (Regular): oaisim : ./build_oai --oaisim -x Eurecom EXMIMO + OAI ENB : ./build_oai --eNB -x - NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP' + NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP" } function main() { - local gen_nvram_path=$OPENAIR_DIR/targets/bin - local conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf - until [ -z "$1" ] do case "$1" in @@ -186,14 +190,11 @@ function main() { --UE) UE=1 echo_info "Will compile UE" - shift - if test -n "$1" - then - [ -f "$1" ] || echo_fatal "file invalid for --UE" - conf_nvram_path=$(readlink -f "$1") - shift 1 - fi;; - --UE-OUTPUT) + shift;; + --UE-conf-nvram) + conf_nvram_path=$(readlink -f "$1") + shift 2;; + --UE-gen-nvram) gen_nvram_path=$(readlink -f $2) shift 2;; --RRH) From 6c789a36bcc81b0c6c373160bd739f6d48d86a87 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 14 Feb 2017 16:18:54 +0100 Subject: [PATCH 284/571] minor: add a comment --- openair2/LAYER2/MAC/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index a879fb8146..8553c118dc 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -62,6 +62,7 @@ #endif //PHY_EMUL #include "SCHED/defs.h" +/* TODO: this abstraction_flag here is very hackish - find a proper solution */ extern uint8_t abstraction_flag; void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, From 4ecdfa05f13629ac61bca9026eb1d8391f63f3d4 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 14 Feb 2017 16:34:56 +0100 Subject: [PATCH 285/571] UE logging, Replace LOG_I by LOG_D --- openair1/SCHED/phy_procedures_lte_ue.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 75abe5d023..503ba84ea8 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1934,7 +1934,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin &pucch_payload, &len); - LOG_I(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); + LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); // Part - IV @@ -1969,7 +1969,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif if(format == pucch_format1) { - LOG_I(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", + LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", Mod_id, ue->dlsch[eNB_id][0]->rnti, frame_tx, subframe_tx, @@ -1981,7 +1981,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin else { if (SR_payload>0) { - LOG_I(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", + LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, @@ -1994,7 +1994,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin Po_PUCCH, tx_amp); } else { - LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, @@ -2073,7 +2073,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif - LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", + LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", Mod_id, ue->dlsch[eNB_id][0]->rnti, frame_tx%1024, subframe_tx, @@ -2834,7 +2834,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (dci_alloc_rx[i].format != format0)) { - LOG_I(PHY,"[UE %d][DCI][PDSCH %x] frame %d, subframe %d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n", + LOG_D(PHY,"[UE %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n", ue->Mod_id,dci_alloc_rx[i].rnti, frame_rx%1024,subframe_rx, dci_alloc_rx[i].format, From f52a42eda53bb04e53e72191f4c9a11aa17bf2a1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 14 Feb 2017 16:40:32 +0100 Subject: [PATCH 286/571] cleanup lte-softmodem.c For whatever reason, lte-softmodem.c was totally messed up... We took the version from the branch develop and added abstraction_flag, which is needed in openair2/LAYER2/MAC/main.c (this is not clean, previous commit added a comment for this). This has to be cleaned at some point. --- targets/RT/USER/lte-softmodem.c | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index f09d93bf36..ed3df3b1f3 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -121,27 +121,6 @@ extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openai extern void fill_ue_band_info(void); extern void init_UE(int); -struct timing_info_t { - //unsigned int frame, hw_slot, last_slot, next_slot; - RTIME time_min, time_max, time_avg, time_last, time_now; - //unsigned int mbox0, mbox1, mbox2, mbox_target; - unsigned int n_samples; -} timing_info; - -uint8_t abstraction_flag=0; - -openair0_config_t openair0_cfg[MAX_CARDS]; - -int32_t **rxdata; -int32_t **txdata; -int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); -int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]); - -uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] -uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] -double cpuf; - -void fill_ue_band_info(void); #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE @@ -306,7 +285,12 @@ double cpuf; char uecap_xer[1024],uecap_xer_in=0; +int oaisim_flag=0; +/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed + * this is very hackish - find a proper solution + */ +uint8_t abstraction_flag=0; /*---------------------BMC: timespec helpers -----------------------------*/ @@ -1416,12 +1400,7 @@ int main( int argc, char **argv ) #endif int CC_id; -<<<<<<< 3fdcf5b676124652c36f1b343370d6f94b246f5c uint8_t abstraction_flag=0; -======= - uint16_t Nid_cell = 0; - uint8_t cooperation_flag=0; ->>>>>>> openair2: fix abstraction mode for oaisim with MME uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; #if defined (XFORMS) From d65d91ddcc8f08a637f9eef9f72006e42687cd95 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 14 Feb 2017 18:18:34 +0100 Subject: [PATCH 287/571] gcc warning fix --- openair2/UTIL/LOG/log.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 5e5be23e0d..b31efbcf74 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -370,10 +370,10 @@ static inline uint64_t checkTCPU(int timeout, char * file, int line) { double microCycles=(double)(cpuf*1000); int duration=(int)((cur-last)/microCycles); if ( last!=0 && duration > timeout ) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - printf("%.3f %s:%d lte-ue delay %d (exceed %d), CPU for this period: %.2f\n", ts.tv_sec+ts.tv_nsec/(1000*1000*1000.0), file, line, - duration, timeout, (CPUTime-lastCPUTime)/1000.0 ); + //struct timespec ts; + //clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line, + duration, timeout, (long long)CPUTime-lastCPUTime ); } last=cur; lastCPUTime=CPUTime; From 23c75476984c2eb33e62fe566d53c6d109a135fa Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 14 Feb 2017 18:24:31 +0100 Subject: [PATCH 288/571] remove debug traces --- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 3 --- targets/RT/USER/lte-ue.c | 5 ----- 2 files changed, 8 deletions(-) diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index b2b386ba7d..dc2589de44 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -266,9 +266,6 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp s->rx_count += nsamps; s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; -#ifdef DEBUG_USRP - check(50); -#endif return samples_received; } diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 1292fef095..0a7c87a152 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -528,11 +528,9 @@ static void *UE_thread_rxn_txnp4(void *arg) { initRefTimes(t3); pickTime(current); updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); - check(2200); // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - check(100); if ((sf_type == SF_DL) || (UE->frame_parms.frame_type == FDD) || (sf_type == SF_S)) { @@ -555,7 +553,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { } phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); } - check(900); if (UE->mac_enabled==1) { ret = mac_xface->ue_scheduler(UE->Mod_id, @@ -585,7 +582,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); } } - check(350); // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || @@ -599,7 +595,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { if (UE->mode != loop_through_memory) phy_procedures_UE_S_TX(UE,0,0,no_relay); updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); - check(300); } From bfa8a28ccbf551f6c8397e5b9942baa299aea406 Mon Sep 17 00:00:00 2001 From: hbilel Date: Tue, 14 Feb 2017 18:31:57 +0100 Subject: [PATCH 289/571] [OAI-UE] fix pucch format2 regression --- openair1/PHY/LTE_TRANSPORT/pucch.c | 89 +++++++++++++++--------------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 795de17ea9..563f83bb7f 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -523,8 +523,29 @@ void generate_pucch2x(int32_t **txdataF, pucch2x_modulation(btilde,d,amp); // add extra symbol for 2a/2b - - + d[20]=0; + d[21]=0; + if (fmt==pucch_format2a) + d[20] = (B2 == 0) ? amp : -amp; + else if (fmt==pucch_format2b) { + switch (B2) { + case 0: + d[20] = amp; + break; + case 1: + d[21] = -amp; + break; + case 2: + d[21] = amp; + break; + case 3: + d[20] = -amp; + break; + default: + AssertFatal(1==0,"Illegal modulation symbol %d for PUCCH %s\n",B2,pucch_format_string[fmt]); + break; + } + } #ifdef DEBUG_PUCCH_TX @@ -552,7 +573,8 @@ void generate_pucch2x(int32_t **txdataF, n_cs = (ncs_cell[ns][l]+nprime)%12; alpha_ind = 0; - for (n=0; n<12; n++) { + for (n=0; n<12; n++) + { // this is r_uv^alpha(n) ref_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15); ref_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15); @@ -563,48 +585,25 @@ void generate_pucch2x(int32_t **txdataF, //LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n); } else { - if (l==1){ - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); - } - else if (fmt==pucch_format2a) { - d[20]=amp; - d[21]=amp; - if (B2 == 0) { - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); - } - else { - ((int16_t *)&zptr[n])[0] = -((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[1] = -((int32_t)amp*ref_im>>15); - } - //LOG_I(PHY,"slot %d ofdm# %d ==> dmrs[%d] \n",ns,l,n); - } - else if (fmt==pucch_format2b) { - switch (B2) { - case 0: // 1 - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); - break; - case 1: // -j - ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[0] = -((int32_t)amp*ref_im>>15); - break; - case 2: // -1 - ((int16_t *)&zptr[n])[0] = -((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[1] = -((int32_t)amp*ref_im>>15); - break; - case 3: // j - ((int16_t *)&zptr[n])[1] = -((int32_t)amp*ref_re>>15); - ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_im>>15); - break; - default: - AssertFatal(1==0,"Illegal modulation symbol %d for PUCCH %s\n",B2,pucch_format_string[fmt]); - break; - } - }// fmt==pucch_format2b - }// l==1 || l==5 - alpha_ind = (alpha_ind + n_cs)%12; + if ((l==1) || ( (l==5) && (fmt==pucch_format2) )) + { + ((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15); + ((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15); + } + // l == 5 && pucch format 2a + else if (fmt==pucch_format2a) + { + ((int16_t *)&zptr[n])[0] = ((int32_t)d[20]*ref_re>>15); + ((int16_t *)&zptr[n])[1] = ((int32_t)d[21]*ref_im>>15); + } + // l == 5 && pucch format 2b + else if (fmt==pucch_format2b) + { + ((int16_t *)&zptr[n])[0] = ((int32_t)d[20]*ref_re>>15); + ((int16_t *)&zptr[n])[1] = ((int32_t)d[21]*ref_im>>15); + } + } // l==1 || l==5 + alpha_ind = (alpha_ind + n_cs)%12; } // n zptr+=12; From 7c4630057fdf038783011afd75bdc8c46130c731 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 15 Feb 2017 14:28:07 +0100 Subject: [PATCH 290/571] fixing a wrongly placed } for correct exmimo initialization --- targets/RT/USER/lte-enb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index d70352b410..3c971314c6 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -2170,11 +2170,11 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst malloc_IF4p5_buffer(eNB); } - } - if (setup_eNB_buffers(PHY_vars_eNB_g[inst],&openair0_cfg[CC_id])!=0) { - printf("Exiting, cannot initialize eNodeB Buffers\n"); - exit(-1); + if (setup_eNB_buffers(PHY_vars_eNB_g[inst],&openair0_cfg[CC_id])!=0) { + printf("Exiting, cannot initialize eNodeB Buffers\n"); + exit(-1); + } } init_eNB_proc(inst); From 7b36af059778a40cbf9cfd41bfc40ead080cb5ab Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 15 Feb 2017 15:38:37 +0100 Subject: [PATCH 291/571] bugfix: variable was on the stack Guess what happens when we return from the function... --- openair3/NAS/UE/nas_ue_task.c | 3 +++ targets/COMMON/create_tasks.c | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 58e38fdbc2..2a42b38a72 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -271,6 +271,9 @@ void *nas_ue_task(void *args_p) } } } + + free(users); + return NULL; } nas_user_t *find_user_from_fd(nas_user_container_t *users, int fd) { diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index d786cde511..c28b9e839c 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -85,9 +85,10 @@ int create_tasks(uint32_t enb_nb, uint32_t ue_nb) # if defined(NAS_BUILT_IN_UE) if (ue_nb > 0) { - nas_user_container_t users; - users.count = ue_nb; - if (itti_create_task (TASK_NAS_UE, nas_ue_task, &users) < 0) { + nas_user_container_t *users = calloc(1, sizeof(*users)); + if (users == NULL) abort(); + users->count = ue_nb; + if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { LOG_E(NAS, "Create task for NAS UE failed\n"); return -1; } From 7d9945e88463fbfb43fd9a9346ea4c9695d69153 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 15 Feb 2017 17:21:02 +0100 Subject: [PATCH 292/571] bugfix: fix PDCP inst This commit is a continuation of 614d6bbe2af5c34f3bace7a8cb5003f07a8931b2 (ue_ip: use correct instance). Now in openair2/NETWORK_DRIVER/UE_IP/common.c the 'inst' is not forced to 1 anymore, we take the value 'pdcph_p->inst'. It turns out that 'pdcph_p->inst' is 0 instead of 1 when we run lte-softmodem as an UE. So let's modify PDCP to set 'inst' to 1 where it was set to 0 for the UE softmodem case, and skip the places where it is reset to 0, still for the UE softmodem case. This may break things, I am not sure. --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 3 +++ openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 4c67f80e20..2ebdb839de 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -816,6 +816,9 @@ pdcp_data_ind( ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id; #if defined(OAI_EMU) ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local; +#else + /* TODO: inst is 1 for the UE or do we keep 0? Seems to be 1 but not sure */ + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; #endif } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index e380bc6098..37b38121b9 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -167,7 +167,8 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); #else #if ! defined(OAI_EMU) - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ +// ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; #endif #endif @@ -571,7 +572,8 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/ #else // OAI_EMU - pdcp_read_header_g.inst = 0; + /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ +// pdcp_read_header_g.inst = 0; //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; From 63c0ed7042ca1c75fc95c5f4fba83d351aef7826 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 10:10:42 +0100 Subject: [PATCH 293/571] fix UE default configuration file - fix OPc key - clear EHPLMN_LIST, UE does not start the RA procedure when set to be fixed --- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index e12793c970..84ec59a36b 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -88,7 +88,7 @@ UE0: SIM: { MSIN="0100001111"; USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; - OPC="00000000000000000000000000000000"; + OPC="C42449363BBAD02B66D16BC975D77CC1"; MSISDN="33611123456"; }; @@ -108,5 +108,7 @@ UE0: FPLMN_LIST = (); # List of Equivalent HPLMNs - EHPLMN_LIST= ("20811", "20813"); +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); }; From 6397e66c2901c5561778013f7de1dc50fd43774d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 11:23:24 +0100 Subject: [PATCH 294/571] bugfix: fix PCDP inst (again) This commit follows 7d9945e88463fbfb43fd9a9346ea4c9695d69153. lte-softmodem UE in S1 and lte-softmodem UE in noS1 modes behave differently here. This commit fixes the issue for thoses cases. Other cases (eNB S1, eNB noS1, oaisim S1/noS1) have to be checked. --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 2ebdb839de..0c5e4cb9e1 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -817,8 +817,13 @@ pdcp_data_ind( #if defined(OAI_EMU) ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local; #else - /* TODO: inst is 1 for the UE or do we keep 0? Seems to be 1 but not sure */ +# if defined(ENABLE_USE_MME) + /* for the UE compiled in S1 mode, we need 1 here + * for the UE compiled in noS1 mode, we need 0 + * TODO: be sure of this + */ ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; +# endif #endif } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); From fbe109a66c799749ded9e8d180885ee4d2bd0a4b Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 16 Feb 2017 11:26:37 +0100 Subject: [PATCH 295/571] RLC/MAC UE interface changes for Tx and adapt to eNB --- openair2/COMMON/mac_rrc_primitives.h | 4 +- openair2/ENB_APP/flexran_agent_common.c | 6 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 6 + openair2/LAYER2/MAC/eNB_scheduler_mch.c | 3 +- .../MAC/flexran_agent_scheduler_dataplane.c | 3 + .../MAC/flexran_agent_scheduler_dlsch_ue.c | 3 +- openair2/LAYER2/MAC/pre_processor.c | 2 +- openair2/LAYER2/MAC/ra_procedures.c | 3 +- openair2/LAYER2/MAC/ue_procedures.c | 331 ++++++------------ openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 52 ++- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h | 14 + openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h | 5 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c | 6 + openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c | 4 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 12 +- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 24 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h | 1 + .../AM_v9.3.0/rlc_am_timer_poll_retransmit.c | 37 +- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c | 10 + openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h | 12 + openair2/LAYER2/RLC/rlc.h | 20 +- openair2/LAYER2/RLC/rlc_mac.c | 72 +++- 22 files changed, 322 insertions(+), 308 deletions(-) diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index dfa641ee66..c59791c1b6 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -388,9 +388,9 @@ typedef struct { struct PMCH_InfoList_r9 *pmch_InfoList #endif ); - unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, char*); + unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, const unsigned int,char*); void (*mac_rlc_data_ind)(module_id_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* ); - mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP, + mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, sub_frame_t subframeP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP, logical_chan_id_t channel_idP, tb_size_t tb_sizeP); signed int (*rrc_rlc_data_req)(module_id_t, rb_id_t, mui_t, confirm_t, sdu_size_t, char *); void (*rrc_rlc_register_rrc) (void (*rrc_data_indP)(module_id_t , rb_id_t , sdu_size_t , char* ), diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index f2d00145a0..073bb8029c 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -562,14 +562,16 @@ int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) { int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); + uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,subframe,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0); return rlc_status.bytes_in_buffer; } int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0); + uint16_t subframe = (uint16_t) flexran_get_current_subframe(mod_id); + mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0); return rlc_status.head_sdu_creation_time; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 41a136d6b1..6048bea9a8 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -821,6 +821,7 @@ schedule_ue_spec( rnti, module_idP, frameP, + subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, @@ -839,6 +840,7 @@ schedule_ue_spec( ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + TBS, //not used (char *)&dlsch_buffer[0]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), @@ -872,6 +874,7 @@ schedule_ue_spec( rnti, module_idP, frameP, + subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH+1, @@ -890,6 +893,7 @@ schedule_ue_spec( ENB_FLAG_YES, MBMS_FLAG_NO, DCCH+1, + TBS, //not used (char *)&dlsch_buffer[sdu_length_total]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), @@ -932,6 +936,7 @@ schedule_ue_spec( rnti, module_idP, frameP, + subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, @@ -949,6 +954,7 @@ schedule_ue_spec( ENB_FLAG_YES, MBMS_FLAG_NO, lcid, + TBS, //not used (char*)&dlsch_buffer[sdu_length_total]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(lcid), T_INT(sdu_lengths[num_sdus])); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 1dac7af704..90d797198e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -504,7 +504,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra module_idP,CC_id,frameP,MTCH,TBS, TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); - rlc_status = mac_rlc_status_ind(module_idP,0,frameP,module_idP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH, + rlc_status = mac_rlc_status_ind(module_idP,0,frameP,subframeP,module_idP,ENB_FLAG_YES,MBMS_FLAG_YES,MTCH, TBS-header_len_mcch-header_len_msi-sdu_length_total-header_len_mtch); LOG_D(MAC,"e-MBMS log channel %u frameP %d, subframeP %d, rlc_status.bytes_in_buffer is %d\n", MTCH,frameP,subframeP, rlc_status.bytes_in_buffer); @@ -521,6 +521,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, + 0, //not used (char*)&mch_buffer[sdu_length_total]); //sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,frameP, MBMS_FLAG_NO, MTCH+(MAX_NUM_RB*(NUMBER_OF_UE_MAX+1)), (char*)&mch_buffer[sdu_length_total]); LOG_I(MAC,"[eNB %d][MBMS USER-PLANE] CC_id %d Got %d bytes for MTCH %d\n",module_idP,CC_id,sdu_lengths[num_sdus],MTCH); diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c index 9c8b23df07..38f39e50e1 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dataplane.c @@ -174,6 +174,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, rnti, mod_id, frame, + subframe, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, @@ -193,6 +194,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, rnti, mod_id, frame, + subframe, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, @@ -209,6 +211,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, + rlc_size, //not used (char *)&dlsch_buffer[sdu_length_total]); LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[j]); diff --git a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c index 00027f04ce..5f1df67663 100644 --- a/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c +++ b/openair2/LAYER2/MAC/flexran_agent_scheduler_dlsch_ue.c @@ -160,7 +160,7 @@ void _store_dlsch_buffer (module_id_t Mod_id, for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels - rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); + rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,subframeP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; @@ -1241,6 +1241,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id, rnti, mod_id, frame, + subframe, ENB_FLAG_YES, MBMS_FLAG_NO, j, diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 6e73e353f0..74e0a43d7d 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -109,7 +109,7 @@ void store_dlsch_buffer (module_id_t Mod_id, for(i=0; i< MAX_NUM_LCID; i++) { // loop over all the logical channels - rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); + rlc_status = mac_rlc_status_ind(Mod_id,rnti, Mod_id,frameP,subframeP,ENB_FLAG_YES,MBMS_FLAG_NO,i,0 ); UE_template->dl_buffer_info[i] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel UE_template->dl_pdus_in_buffer[i] = rlc_status.pdus_in_buffer; UE_template->dl_buffer_head_sdu_creation_time[i] = rlc_status.head_sdu_creation_time ; diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index 43bc113798..210648401f 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -394,7 +394,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, } else if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]] > 0) { // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example) dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element - rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, + rlc_status = mac_rlc_status_ind(module_idP,UE_mac_inst[module_idP].crnti, eNB_indexP,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, DCCH, 6); @@ -409,6 +409,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP,ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, + 6, //not used (char *)&ulsch_buff[0]); LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]); diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 6d304051d4..c6d847c835 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -1265,13 +1265,13 @@ unsigned char generate_ulsch_header(uint8_t *mac_header, void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen, uint8_t *access_mode) { - mac_rlc_status_resp_t rlc_status; uint8_t total_rlc_pdu_header_len=0, rlc_pdu_header_len_last=0 ; uint16_t buflen_remain = 0; uint8_t bsr_len=0,bsr_ce_len=0,bsr_header_len=0; uint8_t phr_header_len=0, phr_ce_len=0,phr_len=0; uint8_t lcid=0,lcid_rlc_pdu_count=0; boolean_t is_lcid_processed = FALSE; + boolean_t is_all_lcid_processed = FALSE; uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t payload_offset=0,num_sdus=0; @@ -1291,6 +1291,7 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf int lcg_id_bsr_trunc = 0; int highest_priority = 16; int num_lcg_id_with_data = 0; + rlc_buffer_occupancy_t lcid_buffer_occupancy_old=0, lcid_buffer_occupancy_new=0; LOG_D(MAC,"[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", module_idP, frameP, subframe, buflen); @@ -1400,16 +1401,32 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf // check for UL bandwidth requests and add SR control element // Check for DCCH first -// TO DO: Unrool the loop to do it at least once to avoid the if num_sdu -for (lcid=DCCH; lcid < DTCH ; lcid++) { +// TO DO: Multiplex in the order defined by the logical channel prioritization +for (lcid=DCCH; (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE) ; lcid++) { if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) { - is_lcid_processed = FALSE; lcid_rlc_pdu_count = 0; + is_lcid_processed = FALSE; + lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind(module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + subframe, + ENB_FLAG_NO, + lcid); + + lcid_buffer_occupancy_new = lcid_buffer_occupancy_old; + + AssertFatal (lcid_buffer_occupancy_new == UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid], "LCID=%d RLC has BO %d bytes but MAC has stored %d bytes\n", + lcid,lcid_buffer_occupancy_new,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]); + + AssertFatal (lcid_buffer_occupancy_new <= UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], "LCID=%d RLC has more BO %d bytes than BSR = %d bytes\n", + lcid,lcid_buffer_occupancy_new,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]); + //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data //Adjust at the end of the loop - while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) { + while ((!is_lcid_processed) && (lcid_buffer_occupancy_new) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) { // Workaround for issue in OAI eNB or EPC which are not able to process SRB2 message multiplexed with SRB1 on the same MAC PDU if ((usim_test == 0) && (lcid == DCCH1) && (lcid_rlc_pdu_count == 0) && (num_sdus)) { @@ -1420,253 +1437,103 @@ for (lcid=DCCH; lcid < DTCH ; lcid++) { buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1); - rlc_status = mac_rlc_status_ind(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, // eNB_index - lcid, - buflen_remain); - // Workaround for BO issue in RLC AM ReTx : RLC BO can not be bigger than stored MAC BO - if (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] < rlc_status.bytes_in_buffer) { - - LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d\n", - module_idP,frameP,subframe, - lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count); - - // Skip multiplexing for the LCID - break; - } - - /* - AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d Frame %d Subrame %d\n", - lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count,frameP,subframe); - */ - - if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " + "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n", + module_idP,frameP, lcid,lcid_buffer_occupancy_new,buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]); - LOG_D(MAC, "[UE %d] Frame %d : UL-DCCH -> ULSCH, RLC SRB%d has %d bytes to " - "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n", - module_idP,frameP, lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + lcid, + buflen_remain, + (char *)&ulsch_buff[sdu_length_total]); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - lcid, - (char *)&ulsch_buff[sdu_length_total]); + AssertFatal (buflen_remain >= sdu_lengths[num_sdus], "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", + lcid,sdu_lengths[num_sdus],buflen_remain); - AssertFatal (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= sdu_lengths[num_sdus], "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", - lcid,sdu_lengths[num_sdus],UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]); + if (sdu_lengths[num_sdus]) + { + sdu_length_total += sdu_lengths[num_sdus]; + sdu_lcids[num_sdus] = lcid; + LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n",module_idP,sdu_lengths[num_sdus],lcid); + if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) { + //No more remaining TBS after this PDU + //exit the function + rlc_pdu_header_len_last = 1; + is_lcid_processed = TRUE; + is_all_lcid_processed = TRUE; + } + else { + rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ; + //Change to 1 byte if it does not fit in the TBS, ie last PDU + if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) { + rlc_pdu_header_len_last = 1; + is_lcid_processed = TRUE; + is_all_lcid_processed = TRUE; + } + } - sdu_length_total += sdu_lengths[num_sdus]; - sdu_lcids[num_sdus] = lcid; - LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for SRB%d\n",module_idP,sdu_lengths[num_sdus],lcid); - //header_len +=2; - // update LCID remain buffer - UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] -= sdu_lengths[num_sdus]; - /* Update BSR : substract transmitted data */ - if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] >= sdu_lengths[num_sdus]){ - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] -= sdu_lengths[num_sdus] ; - } - else { - LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Buffer occupancy =%d for LCGID%d is lower than data transmitted=%d for LCID%d\n", - module_idP,frameP,subframe, - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], - UE_mac_inst[module_idP].scheduling_info.LCGID[lcid], - sdu_lengths[num_sdus],lcid); - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0; - } + //Update number of SDU + num_sdus ++; - //Update the number of LCGID with data as BSR shall reflect status after BSR transmission - if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0)) - { - num_lcg_id_with_data --; - // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1 - if ((bsr_len) && (num_lcg_id_with_data == 1)) - { - bsr_ce_len = sizeof(BSR_SHORT); - bsr_len = bsr_ce_len + bsr_header_len; - } + //Update total MAC Header size for RLC PDUs and save last one + total_rlc_pdu_header_len += rlc_pdu_header_len_last; - } + lcid_rlc_pdu_count ++; + } + else + { + /* avoid infinite loop ... */ + is_lcid_processed = TRUE; + } - if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) { - //No more remaining TBS after this PDU - //exit the function - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - } - else { - rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ; + /* Get updated BO after multiplexing this PDU */ + lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + subframe, + ENB_FLAG_NO, + lcid); - //Change to 1 byte if it does not fit in the TBS, ie last PDU - if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) { - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - } - } - - //Update number of SDU - num_sdus ++; - - //Update total MAC Header size for RLC PDUs and save last one - total_rlc_pdu_header_len += rlc_pdu_header_len_last; - - } //end if (rlc_status.bytes_in_buffer > 0) - else { - // Switch to next LCID or exit the whole loop - is_lcid_processed = TRUE; - } - lcid_rlc_pdu_count ++; + is_lcid_processed = (is_lcid_processed) || (lcid_buffer_occupancy_new <= 0); } + //Update Buffer remain and BSR bytes after transmission + + AssertFatal (lcid_buffer_occupancy_new <= lcid_buffer_occupancy_old, "MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n", + lcid_buffer_occupancy_new,lcid_buffer_occupancy_old,lcid,lcid_rlc_pdu_count,frameP,subframe); + + UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new; + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] += (lcid_buffer_occupancy_new - lcid_buffer_occupancy_old); + + //Update the number of LCGID with data as BSR shall reflect status after BSR transmission + if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0)) + { + num_lcg_id_with_data --; + // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1 + if ((bsr_len) && (num_lcg_id_with_data == 1)) + { + bsr_ce_len = sizeof(BSR_SHORT); + bsr_len = bsr_ce_len + bsr_header_len; + } + } + + UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_EMPTY; } -} - - -// Now Check for DTCH first -// TO DO: do it according to Logical Channel Prioritization if at least 2 DTCH -for (lcid=DTCH; lcid < MAX_NUM_LCID ; lcid++) { -if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) { - - is_lcid_processed = FALSE; - lcid_rlc_pdu_count = 0; - - //Multiplex all available DTCH RLC PDUs considering to multiplex the last PDU each time for maximize the data - //Adjust at the end of the loop - while ((!is_lcid_processed) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) { - - buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1); - - rlc_status = mac_rlc_status_ind(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, // eNB_index - lcid, - buflen_remain); - - // Workaround for BO issue in RLC AM ReTx : RLC BO can not be bigger than stored MAC BO - if (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] < rlc_status.bytes_in_buffer) { - - LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d\n", - module_idP,frameP,subframe, - lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count); - - // Skip multiplexing for the LCID - break; - } - - /* - AssertFatal ( UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= rlc_status.bytes_in_buffer, "Inconsistent BO! for LCID=%d MAC=%d RLC=%d RLC PDU nb=%d Frame %d Subrame %d\n", - lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],rlc_status.bytes_in_buffer,lcid_rlc_pdu_count,frameP,subframe); - */ - - if (rlc_status.bytes_in_buffer > 0) { - - - LOG_D(MAC, "[UE %d] Frame %d : UL-DTCH -> ULSCH, RLC LCID%d has %d bytes to " - "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n", - module_idP,frameP, lcid,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid],buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]); - - - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - lcid, - (char *)&ulsch_buff[sdu_length_total]); - - AssertFatal (sdu_lengths[num_sdus] < MAX_ULSCH_PAYLOAD_BYTES, "LCID=%d RLC PDU size = %d is too big\n", - lcid,sdu_lengths[num_sdus]); - - - AssertFatal (UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] >= sdu_lengths[num_sdus], "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", - lcid,sdu_lengths[num_sdus],UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]); - - - - sdu_length_total += sdu_lengths[num_sdus]; - sdu_lcids[num_sdus] = lcid; - LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LCID%d\n",module_idP,sdu_lengths[num_sdus],lcid); - //header_len +=2; - // update LCID remain buffer - UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] -= sdu_lengths[num_sdus]; - /* Update BSR : substract transmitted data */ - if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] >= sdu_lengths[num_sdus]){ - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] -= sdu_lengths[num_sdus] ; - } - else { - LOG_I(MAC, "[UE %d] Frame %d Subframe%d: WARNING Buffer occupancy =%d for LCGID%d is lower than data transmitted=%d for LCID%d\n", - module_idP,frameP,subframe, - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], - UE_mac_inst[module_idP].scheduling_info.LCGID[lcid], - sdu_lengths[num_sdus],lcid); - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] = 0; - } - - //Update the number of LCGID with data as BSR shall reflect status after BSR transmission - if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0)) - { - num_lcg_id_with_data --; - // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1 - if ((bsr_len) && (num_lcg_id_with_data == 1)) - { - bsr_ce_len = sizeof(BSR_SHORT); - bsr_len = bsr_ce_len + bsr_header_len; - } - - } - - if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) { - //No more remaining TBS after this PDU - //exit the function - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - } - else { - rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ; - - //Change to 1 byte if it does not fit in the TBS, ie last PDU - if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) { - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - } - } - - //Update number of SDU - num_sdus ++; - - //Update total MAC Header size for RLC PDUs and save last one - total_rlc_pdu_header_len += rlc_pdu_header_len_last; - - } //end if (rlc_status.bytes_in_buffer > 0) - else { - // Switch to next LCID or exit the whole loop - is_lcid_processed = TRUE; - } - lcid_rlc_pdu_count ++; } - UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_EMPTY; - } -} - //lcgid= get_bsr_lcgid(module_idP); // Compute BSR Values and update Nb LCGID with data after multiplexing num_lcg_id_with_data = 0; @@ -2396,7 +2263,7 @@ boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subfra lcgid_buffer_remain[lcgid] += UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]; } - rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, + rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 4d16a368fe..5dfaddb28d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -186,9 +186,9 @@ rlc_am_get_buffer_occupancy_in_bytes ( #if TRACE_RLC_AM_BO - if ((rlc_pP->status_buffer_occupancy + rlc_pP->retransmission_buffer_occupancy + rlc_pP->sdu_buffer_occupancy + max_li_overhead + header_overhead) > 0) { + if ((rlc_pP->status_buffer_occupancy + rlc_pP->retrans_num_bytes_to_retransmit + rlc_pP->sdu_buffer_occupancy + max_li_overhead + header_overhead) > 0) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : STATUS BUFFER %d bytes \n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->status_buffer_occupancy); - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : RETRANS BUFFER %d bytes \n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->retransmission_buffer_occupancy); + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : RETRANS BUFFER %d bytes \n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->retrans_num_bytes_to_retransmit); LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : SDU BUFFER %d bytes + li_overhead %d bytes header_overhead %d bytes (nb sdu not segmented %d)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->sdu_buffer_occupancy, @@ -669,13 +669,13 @@ rlc_am_mac_status_indication ( */ if (rlc->input_sdus == NULL) return status_resp; - if (rlc->last_frame_status_indication != ctxt_pP->frame) { + if (rlc->last_absolute_subframe_status_indication != (PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP))) { rlc_am_check_timer_poll_retransmit(ctxt_pP, rlc); rlc_am_check_timer_reordering(ctxt_pP, rlc); rlc_am_check_timer_status_prohibit(ctxt_pP, rlc); } - rlc->last_frame_status_indication = ctxt_pP->frame; + rlc->last_absolute_subframe_status_indication = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP); rlc->nb_bytes_requested_by_mac = tb_sizeP; @@ -701,31 +701,14 @@ rlc_am_mac_status_indication ( } } else { - if (rlc_am_is_timer_poll_retransmit_timed_out(ctxt_pP, rlc)) { - if ((status_resp.buffer_occupancy_in_bytes == 0) && (rlc->input_sdus[rlc->current_sdu_index].mem_block == NULL) && (rlc->nb_sdu > 0)) { - // force BO to be > 0 - rlc_sn_t sn = (rlc->vt_s - 1) & RLC_AM_SN_MASK; - rlc_sn_t sn_end = (rlc->vt_a - 1) & RLC_AM_SN_MASK; - - /* Look for the first retransmittable PDU starting from vtS - 1 */ - while (sn != sn_end) { - AssertFatal (rlc->tx_data_pdu_buffer[sn].mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n", - sn, rlc->vt_a,rlc->vt_s,rlc->channel_id); - if ((rlc->tx_data_pdu_buffer[sn].flags.ack == 0) && (rlc->tx_data_pdu_buffer[sn].flags.max_retransmit == 0)) { - rlc->retrans_num_bytes_to_retransmit = rlc->tx_data_pdu_buffer[sn].header_and_payload_size; - rlc->tx_data_pdu_buffer[sn].flags.retransmit = 1; - status_resp.buffer_occupancy_in_bytes = rlc->tx_data_pdu_buffer[sn].header_and_payload_size; - status_resp.buffer_occupancy_in_pdus = rlc->nb_sdu; - status_resp.head_sdu_remaining_size_to_send = status_resp.buffer_occupancy_in_bytes; - // TODO head_sdu_is_segmented - break; - } - else - { - sn = RLC_AM_PREV_SN(sn); - } - } - } + /* Not so many possibilities ... */ + /* either buffer_occupancy_in_bytes = 0 and that's it */ + /* or we have segmented all received SDUs and buffer occupancy is then made of retransmissions and/or status pdu pending */ + /* then consider only retransmission buffer for the specific BO values used by eNB scheduler (not used up to now...) */ + if (rlc->retrans_num_bytes_to_retransmit) { + status_resp.buffer_occupancy_in_pdus = rlc->retrans_num_pdus; + status_resp.head_sdu_remaining_size_to_send = rlc->retrans_num_bytes_to_retransmit; + status_resp.head_sdu_is_segmented = 1; } } #if MESSAGE_CHART_GENERATOR_RLC_MAC @@ -770,6 +753,17 @@ rlc_am_mac_status_indication ( #endif return status_resp; } + +//----------------------------------------------------------------------------- +void +rlc_am_set_nb_bytes_requested_by_mac ( + void * const rlc_pP, + const tb_size_t tb_sizeP +) +{ + ((rlc_am_entity_t *) rlc_pP)->nb_bytes_requested_by_mac = tb_sizeP; +} + //----------------------------------------------------------------------------- struct mac_data_req rlc_am_mac_data_request ( diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h index 61c6a043cc..f64c13e850 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h @@ -277,6 +277,13 @@ protected_rlc_am( void rlc_am_rx (const protocol_ctxt_t* const ctxtP,void * */ public_rlc_am( struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP, void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP);) +/*! \fn void rlc_am_set_nb_bytes_requested_by_mac (void * const rlc_pP,const tb_size_t tb_sizeP) +* \brief Set available TBS for RLC Tx just before am_mac_data_request. Used for UE only. +* \param[in] rlc_pP RLC AM protocol instance pointer. +* \param[in] tb_sizeP Available Tx Transport Block size in bytes. +*/ +public_rlc_am( void rlc_am_set_nb_bytes_requested_by_mac (void * const rlc_pP,const tb_size_t tb_sizeP);) + /*! \fn struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP) * \brief Gives PDUs to lower layer MAC. * \param[in] ctxt_pP Running context. @@ -293,6 +300,13 @@ public_rlc_am( struct mac_data_req rlc_am_mac_data_request (const protocol_ct */ public_rlc_am( void rlc_am_mac_data_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind data_indP);) +/*! \fn uint32_t rlc_am_get_buffer_occupancy_in_bytes (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP) +* \brief Get Tx Buffer Occupancy. +* \param[in] ctxt_pP Running context. +* \param[in] rlc_pP RLC AM protocol instance pointer. +*/ +public_rlc_am( uint32_t rlc_am_get_buffer_occupancy_in_bytes (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP);) + /*! \fn void rlc_am_data_req (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, mem_block_t *sduP) * \brief Interface with higher layers, buffer higher layer SDUS for transmission. * \param[in] ctxt_pP Running context. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h index 87150f115c..682a781818 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h @@ -57,7 +57,6 @@ typedef struct rlc_am_entity_s { boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ rlc_buffer_occupancy_t sdu_buffer_occupancy; /*!< \brief Number of bytes of unsegmented SDUs. */ - rlc_buffer_occupancy_t retransmission_buffer_occupancy; /*!< \brief Number of bytes of PDUs in retransmission buffer waiting for a ACK. */ rlc_buffer_occupancy_t status_buffer_occupancy; /*!< \brief Number of bytes of control PDUs waiting for transmission. */ rlc_am_control_pdu_info_t control_pdu_info; @@ -76,7 +75,7 @@ typedef struct rlc_am_entity_s { rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer; /*!< \brief Transmission PDU data buffer. Used also for retransmissions */ signed int retrans_num_pdus; /*!< \brief Number of PDUs in the retransmission buffer. */ - signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. */ + signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. Only payload is taken into account */ boolean_t force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ //--------------------------------------------------------------------- @@ -181,7 +180,7 @@ typedef struct rlc_am_entity_s { uint8_t status_requested; /*!< \brief Status bitmap requested by peer. */ rlc_sn_t sn_status_triggered_delayed; /*!< \brief SN of the last received poll for which Status is delayed until SN is out of Rx Window. */ - frame_t last_frame_status_indication; /*!< \brief The last frame number a MAC status indication has been received by RLC. */ + uint32_t last_absolute_subframe_status_indication; /*!< \brief The last absolute subframe number a MAC status indication has been received by RLC. */ //----------------------------- // buffer occupancy measurements sent to MAC //----------------------------- diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c index 4122fd0e66..820b06c233 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c @@ -41,17 +41,23 @@ void rlc_am_free_in_sdu( const unsigned int index_in_bufferP) { if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) { + /* BugFix: SDU shall have been already freed during initial PDU segmentation or concatenation !! */ + AssertFatal(rlcP->input_sdus[index_in_bufferP].mem_block == NULL, "RLC AM Tx SDU Conf: Data Part is not empty index=%d LcId=%d\n", + index_in_bufferP,rlcP->channel_id); + /* if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) { free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block, __func__); rlcP->input_sdus[index_in_bufferP].mem_block = NULL; rlcP->nb_sdu_no_segmented -= 1; rlcP->input_sdus[index_in_bufferP].sdu_remaining_size = 0; } + */ rlcP->nb_sdu -= 1; memset(&rlcP->input_sdus[index_in_bufferP], 0, sizeof(rlc_am_tx_sdu_management_t)); rlcP->input_sdus[index_in_bufferP].flags.transmitted_successfully = 1; + // TODO : understand why. This should not happen if (rlcP->current_sdu_index == index_in_bufferP) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index b93f331676..ce5afe7c59 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -79,7 +79,7 @@ rlc_am_init( //rlc_pP->vr_h = 0; rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; - rlc_pP->last_frame_status_indication = 123456; // any value > 1 + rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->initialized = TRUE; @@ -135,7 +135,7 @@ rlc_am_reestablish( rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; rlc_pP->status_requested = RLC_AM_STATUS_NOT_TRIGGERED; - rlc_pP->last_frame_status_indication = 123456; // any value > 1 + rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->initialized = TRUE; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 4db9893f8a..d2941b061d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -51,8 +51,8 @@ void rlc_am_nack_pdu ( mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; - int pdu_sdu_index; - int sdu_index; + //int pdu_sdu_index; + //int sdu_index; if (mb_p != NULL) { assert(so_startP <= so_endP); @@ -84,10 +84,10 @@ void rlc_am_nack_pdu ( rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 1; - /* TODO : before incrementing retx_count_next, this must be a new occurrence of retransmission */ + /* TODO : before incrementing retx_count_next, one have to check this must be a new occurrence of retransmission */ if (rlc_pP->tx_data_pdu_buffer[snP].retx_count == rlc_pP->tx_data_pdu_buffer[snP].retx_count_next){ rlc_pP->tx_data_pdu_buffer[snP].retx_count_next ++; - rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->tx_data_pdu_buffer[snP].header_and_payload_size; + rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->tx_data_pdu_buffer[snP].payload_size; } /* TODO: Move this part in UL SCH processing */ @@ -148,7 +148,7 @@ void rlc_am_ack_pdu ( rlc_pP->tx_data_pdu_buffer[snP].retx_count); if (rlc_pP->tx_data_pdu_buffer[snP].retx_count >= 0) { - rlc_pP->retrans_num_bytes_to_retransmit -= rlc_pP->tx_data_pdu_buffer[snP].header_and_payload_size; + rlc_pP->retrans_num_bytes_to_retransmit -= rlc_pP->tx_data_pdu_buffer[snP].payload_size; } for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP].nb_sdus; pdu_sdu_index++) { @@ -845,7 +845,6 @@ void rlc_am_retransmit_any_pdu( //rlc_pP->c_pdu_without_poll = 0; //rlc_pP->c_byte_without_poll = 0; //rlc_pP->poll_sn = (rlc_pP->vt_s -1) & RLC_AM_SN_MASK; - rlc_am_start_timer_poll_retransmit(ctxt_pP, rlc_pP); rlc_pP->stat_tx_data_pdu += 1; rlc_pP->stat_tx_retransmit_pdu += 1; rlc_pP->stat_tx_data_bytes += ((struct mac_tb_req*)(pdu_p->data))->tb_size; @@ -879,7 +878,6 @@ void rlc_am_retransmit_any_pdu( rlc_pP->c_pdu_without_poll = 0; rlc_pP->c_byte_without_poll = 0; //rlc_pP->poll_sn = (rlc_pP->vt_s -1) & RLC_AM_SN_MASK; - rlc_am_start_timer_poll_retransmit(ctxt_pP, rlc_pP); rlc_pP->stat_tx_data_pdu += 1; rlc_pP->stat_tx_retransmit_pdu += 1; rlc_pP->stat_tx_data_bytes += ((struct mac_tb_req*)(pdu_p->data))->tb_size; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index f75b481dbb..84d587d53b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -308,14 +308,12 @@ rlc_am_receive_process_control_pdu( assert(ack_sn < RLC_AM_SN_MODULO); assert(rlc_pP->control_pdu_info.num_nack < RLC_AM_MAX_NACK_IN_STATUS_PDU); - if (rlc_am_in_tx_window(ctxt_pP, rlc_pP, ack_sn) > 0) { - + /* Nv1495998 : ackSn can be equal to current vtA only in case the status pdu contains a list of nack_sn with same value = vtA with SOStart/SOEnd */ + /* and meaning the report is not complete due to not enough ressources to fill all SOStart/SOEnd of this NACK_SN */ + if (RLC_AM_DIFF_SN(rlc_pP->vt_s,rlc_pP->vt_a) >= RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a)) + { if (rlc_pP->control_pdu_info.num_nack == 0) { while (sn_cursor != ack_sn) { - if (sn_cursor == rlc_pP->poll_sn) { - rlc_am_stop_and_reset_timer_poll_retransmit(ctxt_pP, rlc_pP); - } - rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor); sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK; } @@ -324,10 +322,6 @@ rlc_am_receive_process_control_pdu( nack_sn = rlc_pP->control_pdu_info.nack_list[nack_index].nack_sn; while (sn_cursor != ack_sn) { - if (sn_cursor == rlc_pP->poll_sn) { - rlc_am_stop_and_reset_timer_poll_retransmit(ctxt_pP, rlc_pP); - } - if (sn_cursor != nack_sn) { rlc_am_ack_pdu(ctxt_pP, rlc_pP, @@ -357,6 +351,16 @@ rlc_am_receive_process_control_pdu( } } } + + /* Check for Stopping TpollReTx */ + if ((rlc_pP->poll_sn != RLC_SN_UNDEFINED) && + (RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a) > RLC_AM_DIFF_SN(rlc_pP->poll_sn,rlc_pP->vt_a))) { + rlc_am_stop_and_reset_timer_poll_retransmit(ctxt_pP, rlc_pP); + rlc_pP->poll_sn = RLC_SN_UNDEFINED; + } + + /* Update vtA */ + } else { LOG_N(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN OUT OF WINDOW\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h index e201e909c5..e2658f2c14 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h @@ -110,6 +110,7 @@ typedef struct rlc_am_tx_data_pdu_management { sdu_size_t hole_so_start [RLC_AM_MAX_HOLES_REPORT_PER_PDU]; /*!< \brief Array containing the start segment offsets for marking a hole (negative acknowledged area) in the PDU. */ sdu_size_t hole_so_stop [RLC_AM_MAX_HOLES_REPORT_PER_PDU]; /*!< \brief Array containing the stop segment offsets for marking a hole (negative acknowledged area) in the PDU. */ uint8_t num_holes; /*!< \brief Number of registereg holes in hole_so_start[], hole_so_stop[]. */ + uint8_t retx_hole_index; /*!< \brief Next index of registered holes to retransmit. */ sdu_size_t header_and_payload_size; /*!< \brief Size of the PDU in bytes, including header and payload. */ sdu_size_t payload_size; /*!< \brief Size of the PDU payload in bytes. */ rlc_sn_t sn; /*!< \brief Sequence number of the PDU. */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c index aa3fdb909a..d7079bba9b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c @@ -77,10 +77,32 @@ rlc_am_check_timer_poll_retransmit( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T_POLL_RETRANSMIT] TIME-OUT\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + /* Check for any retransmittable PDU if Buffer Occupancy empty or window stall */ + if (((rlc_pP->sdu_buffer_occupancy == 0) && (rlc_pP->retrans_num_bytes_to_retransmit == 0)) || + (rlc_pP->vt_s == rlc_pP->vt_ms)) { + // force BO to be > 0 + rlc_sn_t sn = RLC_AM_PREV_SN(rlc_pP->vt_s); + rlc_sn_t sn_end = RLC_AM_PREV_SN(rlc_pP->vt_a); + + /* Look for the first retransmittable PDU starting from vtS - 1 */ + while (sn != sn_end) { + AssertFatal (rlc_pP->tx_data_pdu_buffer[sn].mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n", + sn, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); + if ((rlc_pP->tx_data_pdu_buffer[sn].flags.ack == 0) && (rlc_pP->tx_data_pdu_buffer[sn].flags.max_retransmit == 0)) { + rlc_pP->tx_data_pdu_buffer[sn].flags.retransmit = 1; + rlc_pP->retrans_num_pdus += 1; + rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->tx_data_pdu_buffer[sn].payload_size; + } + else + { + sn = RLC_AM_PREV_SN(sn); + } + } + } + rlc_pP->force_poll= TRUE; - //#warning TO DO rlc_am_check_timer_poll_retransmit - rlc_pP->t_poll_retransmit.ms_time_out = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) + rlc_pP->t_poll_retransmit.ms_duration; + //BugFix : new ms_time_out is computed when next poll is transmitter } } } @@ -119,9 +141,9 @@ rlc_am_start_timer_poll_retransmit( rlc_am_entity_t * const rlc_pP ) { - rlc_pP->t_poll_retransmit.timed_out = 0; + /* Stop timer if it was previously running */ + rlc_am_stop_and_reset_timer_poll_retransmit(ctxt_pP,rlc_pP); - if (rlc_pP->t_poll_retransmit.running == 0) { if (rlc_pP->t_poll_retransmit.ms_duration > 0) { rlc_pP->t_poll_retransmit.running = 1; rlc_pP->t_poll_retransmit.ms_time_out = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP) + rlc_pP->t_poll_retransmit.ms_duration; @@ -138,14 +160,7 @@ rlc_am_start_timer_poll_retransmit( LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T_POLL_RETRANSMIT] NOT STARTED, CAUSE CONFIGURED 0 ms\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); } - } else { -#if MESSAGE_CHART_GENERATOR_RLC_MAC - MSC_LOG_EVENT((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\ - "0 "PROTOCOL_RLC_AM_MSC_FMT" t_poll_retransmit not restarted (TO %u ms)",\ - PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP), rlc_pP->t_poll_retransmit.ms_time_out); -#endif - } } //----------------------------------------------------------------------------- void diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c index 51440d0bfa..de83717cb7 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c @@ -520,6 +520,16 @@ rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP return status_resp; } +//----------------------------------------------------------------------------- +void +rlc_um_set_nb_bytes_requested_by_mac ( + void * rlc_pP, + const tb_size_t tb_sizeP +) +{ + ((rlc_um_entity_t *) rlc_pP)->nb_bytes_requested_by_mac = tb_sizeP; +} + //----------------------------------------------------------------------------- struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP) diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h index 5951eaf149..fe3646b309 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h @@ -188,6 +188,13 @@ protected_rlc_um( void rlc_um_rx (const protocol_ctxt_t* const ctxt_pP, rlc_ */ public_rlc_um( struct mac_status_resp rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP, const eNB_flag_t enb_flagP);) +/*! \fn void rlc_um_set_nb_bytes_requested_by_mac (rlc_um_entity_t * const rlc_pP, const tb_size_t tb_sizeP) +* \brief Set available TBS size for MAC Tx. +* \param[in] rlc_pP RLC UM protocol instance pointer. +* \param[in] tb_sizeP remaining TBS in bytes. +*/ +public_rlc_um( void rlc_um_set_nb_bytes_requested_by_mac (rlc_um_entity_t * const rlc_pP, const tb_size_t tb_sizeP);) + /*! \fn struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP) * \brief Gives PDUs to lower layer MAC. * \param[in] ctxt_pP Running context. @@ -205,6 +212,11 @@ public_rlc_um( struct mac_data_req rlc_um_mac_data_request (const protocol_ct */ public_rlc_um( void rlc_um_mac_data_indication (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP, struct mac_data_ind data_indP);) +/*! \fn uint32_t rlc_um_get_buffer_occupancy (rlc_um_entity_t *rlc_pP) +* \brief Gets Tx Buffer Occupancy. +* \param[in] rlc_pP RLC UM protocol instance pointer.) +*/ +public_rlc_um( uint32_t rlc_um_get_buffer_occupancy (rlc_um_entity_t *rlc_pP);) /*! \fn void rlc_um_data_req (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP, mem_block_t *sduP) * \brief Interface with higher layers, buffer higher layer SDUS for transmission. diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 3fd5b8c3bc..9a53e37422 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -436,10 +436,11 @@ public_rlc_rrc(void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_d * \param [in] eNB_flagP Flag to indicate eNB (1) or UE (0) * \param [in] MBMS_flagP Flag to indicate whether this is the MBMS service (1) or not (0) * \param [in] rb_idP Radio bearer identifier. +* \param [in] tb_sizeP Available Tx TBS in bytes. For UE only. * \param [in,out] bufferP Memory area to fill with the bytes requested by MAC. * \return A status about the processing, OK or error code. */ -public_rlc_mac(tbs_size_t mac_rlc_data_req (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, char*);) +public_rlc_mac(tbs_size_t mac_rlc_data_req (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, const tb_size_t,char*);) /*! \fn void mac_rlc_data_ind (const module_id_t mod_idP, const rnti_t rntiP, const frame_t frameP, const eNB_flag_t eNB_flagP, const MBMS_flag_t MBMS_flagP, logical_chan_id_t rb_idP, uint32_t frameP, char* bufferP, tb_size_t tb_sizeP, num_tb_t num_tbP, crc_t *crcs) * \brief Interface with MAC layer, deserialize the transport blocks sent by MAC, then map data indication to the RLC instance corresponding to the radio bearer identifier. @@ -457,18 +458,31 @@ public_rlc_mac(tbs_size_t mac_rlc_data_req (const module_id_t, co public_rlc_mac(void mac_rlc_data_ind (const module_id_t, const rnti_t, const eNB_index_t,const frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* );) -/*! \fn mac_rlc_status_resp_t mac_rlc_status_ind (const module_id_t mod_idP, const rnti_t rntiP, const frame_t frameP, const eNB_flag_t eNB_flagP, const MBMS_flag_t MBMS_flagP, logical_chan_id_t rb_idP, tb_size_t tb_sizeP) +/*! \fn mac_rlc_status_resp_t mac_rlc_status_ind (const module_id_t mod_idP, const rnti_t rntiP, const frame_t frameP, const sub_frame_t subframeP, const eNB_flag_t eNB_flagP, const MBMS_flag_t MBMS_flagP, logical_chan_id_t rb_idP, tb_size_t tb_sizeP) * \brief Interface with MAC layer, request and set the number of bytes scheduled for transmission by the RLC instance corresponding to the radio bearer identifier. * \param[in] mod_idP Virtualized module identifier. * \param[in] rntiP UE identifier. * \param[in] frameP Frame index. +* \param[in] subframeP SubFrame index. * \param[in] eNB_flagP Flag to indicate eNB operation (1 true, 0 false) * \param[in] MBMS_flagP Flag to indicate whether this is the MBMS service (1) or not (0) * \param[in] rb_idP Radio bearer identifier. * \param[in] tb_sizeP Size of a transport block set in bytes. * \return The maximum number of bytes that the RLC instance can send in the next transmission sequence. */ -public_rlc_mac(mac_rlc_status_resp_t mac_rlc_status_ind (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, tb_size_t );) +public_rlc_mac(mac_rlc_status_resp_t mac_rlc_status_ind (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, tb_size_t );) + +/*! \fn rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, const frame_t frameP, const sub_frame_t subframeP,const eNB_flag_t enb_flagP, const logical_chan_id_t channel_idP) +* \brief Interface with MAC layer, UE only: request and get the number of bytes scheduled for transmission by the RLC instance corresponding to the radio bearer identifier. +* \param[in] mod_idP Virtualized module identifier. +* \param[in] rntiP UE identifier. +* \param[in] frameP Frame index. +* \param[in] subframeP SubFrame index. +* \param[in] eNB_flagP Flag to indicate eNB operation (1 true, 0 false) +* \param[in] channel_idP Logical Channel identifier. +* \return The maximum number of bytes that the RLC instance can send in the next transmission sequence. +*/ +public_rlc_mac(rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const eNB_flag_t, const logical_chan_id_t );) //----------------------------------------------------------------------------- // RLC methods //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index d43a90ed6a..2eeea2e8c5 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -125,6 +125,7 @@ tbs_size_t mac_rlc_data_req( const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, char *buffer_pP) { //----------------------------------------------------------------------------- @@ -189,12 +190,14 @@ tbs_size_t mac_rlc_data_req( break; case RLC_MODE_AM: - data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am); + if (!enb_flagP) rlc_am_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.am,tb_sizeP); + data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am); ret_tb_size =mac_rlc_serialize_tb(buffer_pP, data_request.data); break; case RLC_MODE_UM: - data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um); + if (!enb_flagP) rlc_um_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.um,tb_sizeP); + data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um); ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data); break; @@ -320,6 +323,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( const rnti_t rntiP, const eNB_index_t eNB_index, const frame_t frameP, + const sub_frame_t subframeP, const eNB_flag_t enb_flagP, const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, @@ -337,7 +341,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( srb_flag_t srb_flag = (channel_idP <= 2) ? SRB_FLAG_YES : SRB_FLAG_NO; protocol_ctxt_t ctxt; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0, eNB_index); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, subframeP, eNB_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_STATUS_IND,VCD_FUNCTION_IN); memset (&mac_rlc_status_resp, 0, sizeof(mac_rlc_status_resp_t)); @@ -430,3 +434,65 @@ mac_rlc_status_resp_t mac_rlc_status_ind( return mac_rlc_status_resp; } +//----------------------------------------------------------------------------- +rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const logical_chan_id_t channel_idP) +{ + //----------------------------------------------------------------------------- + rlc_buffer_occupancy_t mac_rlc_buffer_occupancy_resp = 0; + rlc_mode_t rlc_mode = RLC_MODE_NONE; + rlc_union_t *rlc_union_p = NULL; + hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; + hashtable_rc_t h_rc; + srb_flag_t srb_flag = (channel_idP <= 2) ? SRB_FLAG_YES : SRB_FLAG_NO; + protocol_ctxt_t ctxt; + + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0, eNB_index); + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_GET_BUFFER_OCCUPANCY_IND,VCD_FUNCTION_IN); + + + /* Assumptions : for UE only */ + /* At each TTI, Buffer Occupancy is first computed in mac_rlc_status_ind called by MAC ue_scheduler() function */ + /* Then this function is called during MAC multiplexing ue_get_sdu(), and it may be call several times for the same bearer if it is in AM mode and there are several PDU types to transmit */ + AssertFatal(enb_flagP == FALSE,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP); + + + key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag); + + + h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p); + + if (h_rc == HASH_TABLE_OK) { + rlc_mode = rlc_union_p->mode; + } else { + rlc_mode = RLC_MODE_NONE; + //LOG_W(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP); + //LOG_D(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP); + } + + switch (rlc_mode) { + case RLC_MODE_AM: + mac_rlc_buffer_occupancy_resp = rlc_am_get_buffer_occupancy_in_bytes(&ctxt, &rlc_union_p->rlc.am); + break; + + case RLC_MODE_UM: + mac_rlc_buffer_occupancy_resp = rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um); + break; + + default: + mac_rlc_buffer_occupancy_resp = 0 ; + } + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_GET_BUFFER_OCCUPANCY_IND,VCD_FUNCTION_OUT); + + return mac_rlc_buffer_occupancy_resp; +} + + From be0541aa8c2d7a1eacd0164bf717fa4588c2fd8d Mon Sep 17 00:00:00 2001 From: laurent Date: Thu, 16 Feb 2017 11:38:38 +0100 Subject: [PATCH 296/571] remove a race --- .../GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf | 8 ++++---- targets/RT/USER/lte-ue.c | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index 27ec283115..752ab6d123 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -31,16 +31,16 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2660000000L; + downlink_frequency = 2630000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; - N_RB_DL = 25; + N_RB_DL = 50; Nid_cell_mbsfn = 0; nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 80; - rx_gain = 90; + tx_gain = 90; + rx_gain = 110; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index decc793411..b4e02f1874 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -625,7 +625,9 @@ void *UE_thread(void *arg) { rxp, UE->frame_parms.samples_per_tti*10, UE->frame_parms.nb_antennas_rx), ""); + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); instance_cnt_synch = ++UE->proc.instance_cnt_synch; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if (instance_cnt_synch == 0) { AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); } else { From 1f3b1ff8ffe732fda105bf2301137dfe23f7af3e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 12:53:25 +0100 Subject: [PATCH 297/571] integration fix: remove XER_PRINT from RRC --- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 5840006a37..4537303fca 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -99,7 +99,7 @@ int errno; # endif #endif -#define XER_PRINT +//#define XER_PRINT extern Enb_properties_array_t enb_properties; typedef struct xer_sprint_string_s { From 36bd7e1d75fe5d4c2fd5c6e60c433b1384f393e1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 14:01:15 +0100 Subject: [PATCH 298/571] integration fix: remove comment --- openair1/PHY/TOOLS/cadd_vv.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/openair1/PHY/TOOLS/cadd_vv.c b/openair1/PHY/TOOLS/cadd_vv.c index f270f147d2..a08564daf3 100644 --- a/openair1/PHY/TOOLS/cadd_vv.c +++ b/openair1/PHY/TOOLS/cadd_vv.c @@ -1,29 +1,3 @@ -/******************************************************************************* - 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 WITTOOLHOUT 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 . - - 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 /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with From bcfeb7af32fb21df66ad3b7c324c96ae95e6ccc0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 14:04:56 +0100 Subject: [PATCH 299/571] integration fix: put correct licensing information --- openair1/PHY/TOOLS/lte_phy_scope_tm4.c | 44 +++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index 9187f6e7ba..60c5ace2c5 100755 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -1,24 +1,24 @@ -/******************************************************************************* - 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 . - 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 - *******************************************************************************/ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + /* Form definition file generated by fdesign */ #include #include "lte_phy_scope.h" @@ -797,4 +797,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, for (arx=0;arx Date: Thu, 16 Feb 2017 14:16:29 +0100 Subject: [PATCH 300/571] integration fix: put correct licensing information --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 48 +++++++++++-------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 59091c1e38..2ee5804823 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -1,31 +1,23 @@ -/******************************************************************************* - 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 . - - 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 - - *******************************************************************************/ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file dlsim.c \brief Top-level DL simulator From 70c84ef835c13c78b53b5210d56b6c10655e7dcc Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 14:19:04 +0100 Subject: [PATCH 301/571] integration fix: put correct licensing information --- openair1/SIMULATION/TOOLS/random_channel.c | 26 +--------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 86b919e699..abf7ab8954 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -17,31 +17,7 @@ *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org - - 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 . - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - - *******************************************************************************/ + */ #include #include From 31c85b22ea2e5297b552c584eb8ba01a9c023887 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 14:35:19 +0100 Subject: [PATCH 302/571] integration fix: remove ^M from file command run: dos2unix openair1/SIMULATION/TOOLS/taus.c --- openair1/SIMULATION/TOOLS/taus.c | 242 +++++++++++++++---------------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c index bee2a291a1..e8a13da076 100644 --- a/openair1/SIMULATION/TOOLS/taus.c +++ b/openair1/SIMULATION/TOOLS/taus.c @@ -19,124 +19,124 @@ * contact@openairinterface.org */ -#ifdef USER_MODE -#include -#include -#else -#include -#include -#endif -#ifdef RTAI_ENABLED -#include -#include -#define time(x) (unsigned int)(rt_get_time_ns()) -#endif - -unsigned int s0, s1, s2, b; - -//---------------------------------------------- -// -/*! -*/ -// - -unsigned int taus(void) -{ - - b = (((s0 << 13) ^ s0) >> 19); - s0 = (((s0 & 0xFFFFFFFE) << 12)^ b); - b = (((s1 << 2) ^ s1) >> 25); - s1 = (((s1 & 0xFFFFFFF8) << 4)^ b); - b = (((s2 << 3) ^ s2) >> 11); - s2 = (((s2 & 0xFFFFFFF0) << 17)^ b); - return s0 ^ s1 ^ s2; -} -#if 1 -void set_taus_seed(unsigned int seed_init) -{ - -#ifdef USER_MODE - struct drand48_data buffer; - unsigned long result = 0; -#endif - - if (seed_init == 0) { - s0 = (unsigned int)time(NULL); - s1 = (unsigned int)time(NULL); - s2 = (unsigned int)time(NULL); - } else { -#ifndef USER_MODE - s0 = (unsigned int)0x1e23d852; - s1 = (unsigned int)0x81f38a1c; - s2 = (unsigned int)0xfe1a133e; -#else - /* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ - srand48_r((long int)seed_init, &buffer); - mrand48_r(&buffer, (long int *)&result); - s0 = result; - mrand48_r(&buffer, (long int *)&result); - s1 = result; - mrand48_r(&buffer, (long int *)&result); - s2 = result; -#endif - } -} -#endif - -#if 0 - void set_taus_seed(unsigned int seed_init) -{ - -#ifdef USER_MODE - struct drand48_data buffer; - unsigned long result = 0; -#endif - s0 = (unsigned int)0x1e23d852; - s1 = (unsigned int)0x81f38a1c; - s2 = (unsigned int)0xfe1a133e; - - return; - - if (seed_init == 0) { - s0 = (unsigned int)time(NULL); - s1 = (unsigned int)time(NULL); - s2 = (unsigned int)time(NULL); - } else { -#ifndef USER_MODE - s0 = (unsigned int)0x1e23d852; - s1 = (unsigned int)0x81f38a1c; - s2 = (unsigned int)0xfe1a133e; -#else - // Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ - srand48_r((long int)seed_init, &buffer); - mrand48_r(&buffer, (long int *)&result); - s0 = result; - mrand48_r(&buffer, (long int *)&result); - s1 = result; - mrand48_r(&buffer, (long int *)&result); - s2 = result; -#endif - } -} -#endif - -#ifdef MAIN - -main() -{ - - unsigned int i,rand; - - set_taus_seed(); - - for (i=0; i<10; i++) { - - rand = taus(); - printf("%u\n",rand); - - } -} -#endif //MAIN - - - +#ifdef USER_MODE +#include +#include +#else +#include +#include +#endif +#ifdef RTAI_ENABLED +#include +#include +#define time(x) (unsigned int)(rt_get_time_ns()) +#endif + +unsigned int s0, s1, s2, b; + +//---------------------------------------------- +// +/*! +*/ +// + +unsigned int taus(void) +{ + + b = (((s0 << 13) ^ s0) >> 19); + s0 = (((s0 & 0xFFFFFFFE) << 12)^ b); + b = (((s1 << 2) ^ s1) >> 25); + s1 = (((s1 & 0xFFFFFFF8) << 4)^ b); + b = (((s2 << 3) ^ s2) >> 11); + s2 = (((s2 & 0xFFFFFFF0) << 17)^ b); + return s0 ^ s1 ^ s2; +} +#if 1 +void set_taus_seed(unsigned int seed_init) +{ + +#ifdef USER_MODE + struct drand48_data buffer; + unsigned long result = 0; +#endif + + if (seed_init == 0) { + s0 = (unsigned int)time(NULL); + s1 = (unsigned int)time(NULL); + s2 = (unsigned int)time(NULL); + } else { +#ifndef USER_MODE + s0 = (unsigned int)0x1e23d852; + s1 = (unsigned int)0x81f38a1c; + s2 = (unsigned int)0xfe1a133e; +#else + /* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ + srand48_r((long int)seed_init, &buffer); + mrand48_r(&buffer, (long int *)&result); + s0 = result; + mrand48_r(&buffer, (long int *)&result); + s1 = result; + mrand48_r(&buffer, (long int *)&result); + s2 = result; +#endif + } +} +#endif + +#if 0 + void set_taus_seed(unsigned int seed_init) +{ + +#ifdef USER_MODE + struct drand48_data buffer; + unsigned long result = 0; +#endif + s0 = (unsigned int)0x1e23d852; + s1 = (unsigned int)0x81f38a1c; + s2 = (unsigned int)0xfe1a133e; + + return; + + if (seed_init == 0) { + s0 = (unsigned int)time(NULL); + s1 = (unsigned int)time(NULL); + s2 = (unsigned int)time(NULL); + } else { +#ifndef USER_MODE + s0 = (unsigned int)0x1e23d852; + s1 = (unsigned int)0x81f38a1c; + s2 = (unsigned int)0xfe1a133e; +#else + // Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ + srand48_r((long int)seed_init, &buffer); + mrand48_r(&buffer, (long int *)&result); + s0 = result; + mrand48_r(&buffer, (long int *)&result); + s1 = result; + mrand48_r(&buffer, (long int *)&result); + s2 = result; +#endif + } +} +#endif + +#ifdef MAIN + +main() +{ + + unsigned int i,rand; + + set_taus_seed(); + + for (i=0; i<10; i++) { + + rand = taus(); + printf("%u\n",rand); + + } +} +#endif //MAIN + + + From e7e48144e1e5ba14f17ca1274148fc8abaa74f95 Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 16 Feb 2017 15:03:26 +0100 Subject: [PATCH 303/571] Remove RLC header size from UE L2 buffer occupancy --- openair2/LAYER2/MAC/ue_procedures.c | 2 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 55 +++++++++++++++----------- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h | 10 +++-- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c | 31 ++++++--------- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h | 5 ++- openair2/LAYER2/RLC/rlc_mac.c | 6 +-- 6 files changed, 56 insertions(+), 53 deletions(-) diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index c6d847c835..ddd7490040 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -2265,7 +2265,7 @@ boolean_t update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subfra rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, - 0); + 0xFFFF); //TBS is not used in RLC at this step, set a special value for debug lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 5dfaddb28d..ad9810cfff 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -152,9 +152,6 @@ rlc_am_get_buffer_occupancy_in_bytes ( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP) { - uint32_t max_li_overhead; - uint32_t header_overhead; - // priority of control trafic rlc_pP->status_buffer_occupancy = 0; if ((rlc_pP->status_requested) && !(rlc_pP->status_requested & RLC_AM_STATUS_NO_TX_MASK)) { @@ -168,21 +165,6 @@ rlc_am_get_buffer_occupancy_in_bytes ( #endif } - // data traffic - if (rlc_pP->nb_sdu_no_segmented <= 1) { - max_li_overhead = 0; - } else { - /* This computation assumes there is no SDU with size greater than 2047 bytes, otherwise a new PDU must be built except for LI15 configuration from Rel12*/ - uint32_t num_li = rlc_pP->nb_sdu_no_segmented - 1; - max_li_overhead = num_li + (num_li >> 1) + (num_li & 1); - } - - if (rlc_pP->sdu_buffer_occupancy == 0) { - header_overhead = 0; - } else { - header_overhead = 2; - } - #if TRACE_RLC_AM_BO @@ -192,13 +174,13 @@ rlc_am_get_buffer_occupancy_in_bytes ( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : SDU BUFFER %d bytes + li_overhead %d bytes header_overhead %d bytes (nb sdu not segmented %d)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->sdu_buffer_occupancy, - max_li_overhead, - header_overhead, + 0, + 0, rlc_pP->nb_sdu_no_segmented); } #endif - return rlc_pP->status_buffer_occupancy + rlc_pP->retrans_num_bytes_to_retransmit + rlc_pP->sdu_buffer_occupancy + max_li_overhead + header_overhead; + return rlc_pP->status_buffer_occupancy + rlc_pP->retrans_num_bytes_to_retransmit + rlc_pP->sdu_buffer_occupancy; } //----------------------------------------------------------------------------- void @@ -645,7 +627,8 @@ rlc_am_mac_status_indication ( const protocol_ctxt_t* const ctxt_pP, void * const rlc_pP, const uint16_t tb_sizeP, - struct mac_status_ind tx_statusP) + struct mac_status_ind tx_statusP, + const eNB_flag_t enb_flagP) { struct mac_status_resp status_resp; uint16_t sdu_size = 0; @@ -681,6 +664,26 @@ rlc_am_mac_status_indication ( status_resp.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes(ctxt_pP, rlc); + // For eNB scheduler : Add Max RLC header size for new PDU + // For UE : do not add RLC header part to be compliant with BSR definition in 36.321 + if (enb_flagP == ENB_FLAG_YES) { + uint32_t max_li_overhead = 0; + uint32_t header_overhead = 0; + + if (rlc->nb_sdu_no_segmented > 1) { + /* This computation assumes there is no SDU with size greater than 2047 bytes, otherwise a new PDU must be built except for LI15 configuration from Rel12*/ + uint32_t num_li = rlc->nb_sdu_no_segmented - 1; + max_li_overhead = num_li + (num_li >> 1) + (num_li & 1); + } + + if (rlc->sdu_buffer_occupancy > 0) { + header_overhead = 2; + } + + status_resp.buffer_occupancy_in_bytes += (header_overhead + max_li_overhead); + } + + if ((rlc->input_sdus[rlc->current_sdu_index].mem_block != NULL) && (status_resp.buffer_occupancy_in_bytes)) { //status_resp.buffer_occupancy_in_bytes += ((rlc_am_entity_t *) rlc)->tx_header_min_length_in_bytes; @@ -768,7 +771,8 @@ rlc_am_set_nb_bytes_requested_by_mac ( struct mac_data_req rlc_am_mac_data_request ( const protocol_ctxt_t* const ctxt_pP, - void * const rlc_pP + void * const rlc_pP, + const eNB_flag_t enb_flagP ) { struct mac_data_req data_req; @@ -806,7 +810,10 @@ rlc_am_mac_data_request ( data_req.data.nb_elements); } - data_req.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes(ctxt_pP, l_rlc_p); + if (enb_flagP) { + // redundant in UE MAC Tx processing and not used in eNB ... + data_req.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes(ctxt_pP, l_rlc_p); + } data_req.rlc_info.rlc_protocol_state = l_rlc_p->protocol_state; #if TRACE_RLC_AM_PDU || MESSAGE_CHART_GENERATOR diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h index f64c13e850..4619a07315 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h @@ -267,15 +267,16 @@ private_rlc_am( void rlc_am_get_pdus (const protocol_ctxt_t* const ctxtP,v */ protected_rlc_am( void rlc_am_rx (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind);) -/*! \fn struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP) +/*! \fn struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP) * \brief Request the maximum number of bytes that can be served by RLC instance to MAC and fix the amount of bytes requested by MAC for next RLC transmission. * \param[in] ctxt_pP Running context. * \param[in] rlc_pP RLC AM protocol instance pointer. * \param[in] tbs_sizeP Number of bytes requested by MAC for next transmission. * \param[in] tx_statusP Transmission status given by MAC on previous MAC transmission of the PDU. +* \param[in] enb_flagP eNB or UE flag indication. * \return The maximum number of bytes that can be served by RLC instance to MAC. */ -public_rlc_am( struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP, void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP);) +public_rlc_am( struct mac_status_resp rlc_am_mac_status_indication (const protocol_ctxt_t* const ctxtP, void * const rlc_pP, uint16_t tbs_sizeP, struct mac_status_ind tx_statusP,const eNB_flag_t enb_flagP);) /*! \fn void rlc_am_set_nb_bytes_requested_by_mac (void * const rlc_pP,const tb_size_t tb_sizeP) * \brief Set available TBS for RLC Tx just before am_mac_data_request. Used for UE only. @@ -284,13 +285,14 @@ public_rlc_am( struct mac_status_resp rlc_am_mac_status_indication (const pro */ public_rlc_am( void rlc_am_set_nb_bytes_requested_by_mac (void * const rlc_pP,const tb_size_t tb_sizeP);) -/*! \fn struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP) +/*! \fn struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP,const eNB_flag_t enb_flagP) * \brief Gives PDUs to lower layer MAC. * \param[in] ctxt_pP Running context. * \param[in] rlc_pP RLC AM protocol instance pointer. +* \param[in] enb_flagP eNB or UE flag * \return A PDU of the previously requested number of bytes, and the updated maximum number of bytes that can be served by RLC instance to MAC for next RLC transmission. */ -public_rlc_am( struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP);) +public_rlc_am( struct mac_data_req rlc_am_mac_data_request (const protocol_ctxt_t* const ctxtP,void * const rlc_pP,const eNB_flag_t enb_flagP);) /*! \fn void rlc_am_mac_data_indication (const protocol_ctxt_t* const ctxtP,void * const rlc_pP, struct mac_data_ind data_indP) * \brief Receive PDUs from lower layer MAC. diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c index de83717cb7..e3322d9410 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c @@ -434,7 +434,6 @@ rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP int32_t diff_time=0; rlc_um_entity_t *rlc_p = NULL; mem_block_t *mb_p = NULL; - unsigned int max_li_overhead = 0; status_resp.buffer_occupancy_in_pdus = 0; status_resp.buffer_occupancy_in_bytes = 0; @@ -454,20 +453,11 @@ rlc_um_mac_status_indication (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP if ((status_resp.buffer_occupancy_in_bytes > 0) && ((mb_p = list_get_head(&rlc_p->input_sdus)) != NULL)) { - //Fix on full Header size - if (enb_flagP == ENB_FLAG_NO) - { - // compute Length Indicator overhead to inform MAC of maximum full RLC PDU size according to stored SDUs - // For UE scheduler - // Could be useful for eNB: to be checked - if (rlc_p->input_sdus.nb_elements <= 1) { - max_li_overhead = 0; - } else { - unsigned int num_li = rlc_p->input_sdus.nb_elements - 1; - max_li_overhead = num_li + (num_li >> 1) + (num_li & 1); - } - } - status_resp.buffer_occupancy_in_bytes += (rlc_p->tx_header_min_length_in_bytes + max_li_overhead); + if (enb_flagP == ENB_FLAG_YES) { + /* For eNB: add minimum RLC UM header size for the scheduler */ + /* For UE : RLC header part is not taken into account for BSR reporting (cf 36.321) */ + status_resp.buffer_occupancy_in_bytes += rlc_p->tx_header_min_length_in_bytes; + } status_resp.buffer_occupancy_in_pdus = rlc_p->input_sdus.nb_elements; diff_time = ctxt_pP->frame - ((struct rlc_um_tx_sdu_management *)mb_p->data)->sdu_creation_time; @@ -532,7 +522,7 @@ rlc_um_set_nb_bytes_requested_by_mac ( //----------------------------------------------------------------------------- struct mac_data_req -rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP) +rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP,const eNB_flag_t enb_flagP) { struct mac_data_req data_req; int16_t tb_size_in_bytes; @@ -554,10 +544,13 @@ rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP) list_add_list (&l_rlc_p->pdus_to_mac_layer, &data_req.data); - data_req.buffer_occupancy_in_bytes = rlc_um_get_buffer_occupancy (l_rlc_p); + if (enb_flagP) { + // redundant in UE MAC Tx processing and not used in eNB scheduler ... + data_req.buffer_occupancy_in_bytes = rlc_um_get_buffer_occupancy (l_rlc_p); - if (data_req.buffer_occupancy_in_bytes > 0) { - data_req.buffer_occupancy_in_bytes += l_rlc_p->tx_header_min_length_in_bytes; + if (data_req.buffer_occupancy_in_bytes > 0) { + data_req.buffer_occupancy_in_bytes += l_rlc_p->tx_header_min_length_in_bytes; + } } data_req.rlc_info.rlc_protocol_state = l_rlc_p->protocol_state; diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h index fe3646b309..87cf2e2f37 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h @@ -195,13 +195,14 @@ public_rlc_um( struct mac_status_resp rlc_um_mac_status_indication (const pro */ public_rlc_um( void rlc_um_set_nb_bytes_requested_by_mac (rlc_um_entity_t * const rlc_pP, const tb_size_t tb_sizeP);) -/*! \fn struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP) +/*! \fn struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP,const eNB_flag_t enb_flagP) * \brief Gives PDUs to lower layer MAC. * \param[in] ctxt_pP Running context. * \param[in] rlc_pP RLC UM protocol instance pointer. +* \param[in] enb_flagP eNB or UE flag. * \return A PDU of the previously requested number of bytes, and the updated maximum number of bytes that can be served by RLC instance to MAC for next RLC transmission. */ -public_rlc_um( struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP);) +public_rlc_um( struct mac_data_req rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP,const eNB_flag_t enb_flagP);) /*! \fn void rlc_um_mac_data_indication (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t * const rlc_pP,struct mac_data_ind data_indP) diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index 2eeea2e8c5..b4061ad29f 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -191,13 +191,13 @@ tbs_size_t mac_rlc_data_req( case RLC_MODE_AM: if (!enb_flagP) rlc_am_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.am,tb_sizeP); - data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am); + data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am,enb_flagP); ret_tb_size =mac_rlc_serialize_tb(buffer_pP, data_request.data); break; case RLC_MODE_UM: if (!enb_flagP) rlc_um_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.um,tb_sizeP); - data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um); + data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um,enb_flagP); ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data); break; @@ -401,7 +401,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( break; case RLC_MODE_AM: - status_resp = rlc_am_mac_status_indication(&ctxt, &rlc_union_p->rlc.am, tb_sizeP, tx_status); + status_resp = rlc_am_mac_status_indication(&ctxt, &rlc_union_p->rlc.am, tb_sizeP, tx_status,enb_flagP); mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes; mac_rlc_status_resp.head_sdu_creation_time = status_resp.head_sdu_creation_time; mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send; From 9535e7a276c2fe45822b4fb1cf55cc67d6a2ede5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 15:35:07 +0100 Subject: [PATCH 304/571] bugfix: make some functions thread safe Those functions modify a global char array (a string). Let's pass a buffer to those functions, so that it's thread safe. The caller has been modified, with hopefully a buffer big enough (still bigger than what was there before, so should not break more than it did). --- openair3/NAS/UE/ESM/PdnConnectivity.c | 7 ++++--- openair3/NAS/UE/ESM/esmData.h | 11 +++-------- openair3/NAS/UE/ESM/esm_ip.c | 22 +++++++++------------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index c51d08cdbc..f0a245e83e 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -357,6 +357,7 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ int rc; int pid = RETURNerror; char apn_first_char[4]; + char str[128]; if (isprint(apn->value[0])) { apn_first_char[0] = '\0'; @@ -366,9 +367,9 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ LOG_TRACE(INFO, "ESM-PROC - PDN connectivity accepted by the network " "(pti=%d) APN = %s\"%s\", IP address = %s", pti, apn_first_char, isprint(apn->value[0]) ? &apn->value[0] : &apn->value[1], - (pdn_type == ESM_PDN_TYPE_IPV4)? esm_data_get_ipv4_addr(pdn_addr) : - (pdn_type == ESM_PDN_TYPE_IPV6)? esm_data_get_ipv6_addr(pdn_addr) : - esm_data_get_ipv4v6_addr(pdn_addr)); + (pdn_type == ESM_PDN_TYPE_IPV4)? esm_data_get_ipv4_addr(pdn_addr, str) : + (pdn_type == ESM_PDN_TYPE_IPV6)? esm_data_get_ipv6_addr(pdn_addr, str) : + esm_data_get_ipv4v6_addr(pdn_addr, str)); /* Stop T3482 timer if running */ esm_pt_stop_timer(esm_pt_data, pti); diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 02bc0dd930..7da659e801 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -204,13 +204,8 @@ typedef esm_data_context_t esm_data_t; /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -// FIXME prototype and buffer allocation -extern char ip_addr_str[100]; - -extern char *esm_data_get_ipv4_addr(const OctetString *ip_addr); - -extern char *esm_data_get_ipv6_addr(const OctetString *ip_addr); - -extern char *esm_data_get_ipv4v6_addr(const OctetString *ip_addr); +char *esm_data_get_ipv4_addr(const OctetString *ip_addr, char *ret); +char *esm_data_get_ipv6_addr(const OctetString *ip_addr, char *ret); +char *esm_data_get_ipv4v6_addr(const OctetString *ip_addr, char *ret); #endif /* __ESMDATA_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_ip.c b/openair3/NAS/UE/ESM/esm_ip.c index 2638221a8f..0743307f6e 100644 --- a/openair3/NAS/UE/ESM/esm_ip.c +++ b/openair3/NAS/UE/ESM/esm_ip.c @@ -22,47 +22,43 @@ #include "emmData.h" #include "esmData.h" -// FIXME don't work for reentrant calls -char ip_addr_str[100]; - -// FIXME can't be extern and inline at same time ! -inline char *esm_data_get_ipv4_addr(const OctetString *ip_addr) +char *esm_data_get_ipv4_addr(const OctetString *ip_addr, char *ret) { if (ip_addr->length > 0) { - sprintf(ip_addr_str, "%u.%u.%u.%u", + sprintf(ret, "%u.%u.%u.%u", ip_addr->value[0], ip_addr->value[1], ip_addr->value[2], ip_addr->value[3]); - return ip_addr_str; + return ret; } return (NULL); } -inline char *esm_data_get_ipv6_addr(const OctetString *ip_addr) +char *esm_data_get_ipv6_addr(const OctetString *ip_addr, char *ret) { if (ip_addr->length > 0) { - sprintf(ip_addr_str, "%x%.2x:%x%.2x:%x%.2x:%x%.2x", + sprintf(ret, "%x%.2x:%x%.2x:%x%.2x:%x%.2x", ip_addr->value[0], ip_addr->value[1], ip_addr->value[2], ip_addr->value[3], ip_addr->value[4], ip_addr->value[5], ip_addr->value[6], ip_addr->value[7]); - return ip_addr_str; + return ret; } return (NULL); } -inline char *esm_data_get_ipv4v6_addr(const OctetString *ip_addr) +char *esm_data_get_ipv4v6_addr(const OctetString *ip_addr, char *ret) { if (ip_addr->length > 0) { - sprintf(ip_addr_str, "%u.%u.%u.%u / %x%.2x:%x%.2x:%x%.2x:%x%.2x", + sprintf(ret, "%u.%u.%u.%u / %x%.2x:%x%.2x:%x%.2x:%x%.2x", ip_addr->value[0], ip_addr->value[1], ip_addr->value[2], ip_addr->value[3], ip_addr->value[4], ip_addr->value[5], ip_addr->value[6], ip_addr->value[7], ip_addr->value[8], ip_addr->value[9], ip_addr->value[10], ip_addr->value[11]); - return ip_addr_str; + return ret; } return (NULL); From 9a5d17d967b50fe7cf14804860a6d0d134c8cb3b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Feb 2017 15:37:56 +0100 Subject: [PATCH 305/571] bugfix: do not allocate memory Memory was allocated which was "lost" because the address of the block was put in a pointer that is overwritten just after. Discussing with Elena, the current commit is the correct way to do things. --- openair1/SIMULATION/TOOLS/random_channel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index abf7ab8954..ea8781e216 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -119,8 +119,9 @@ void fill_channel_desc(channel_desc_t *chan_desc, else { chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*)); for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); + //chan_desc->R_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; + /* all chan_desc share the same R_sqrt, coming from caller */ chan_desc->R_sqrt[i] = R_sqrt[0]; } } From 3dd1faadd409f150149ac79dd09963039a3c2015 Mon Sep 17 00:00:00 2001 From: pyroclaste Date: Fri, 17 Feb 2017 11:38:44 +0100 Subject: [PATCH 306/571] Add the compression for IF5 and RTT measurements for FH and RF --- openair1/PHY/LTE_TRANSPORT/if4_tools.c | 80 +++-- openair1/PHY/LTE_TRANSPORT/if5_tools.c | 320 ++++++++++++++---- openair1/PHY/LTE_TRANSPORT/if5_tools.h | 2 + openair1/PHY/TOOLS/alaw_lut.h | 12 +- openair1/SCHED/phy_procedures_lte_eNb.c | 11 +- openair2/ENB_APP/enb_config.c | 163 +++++---- openair2/ENB_APP/enb_config.h | 1 + openair2/UTIL/LOG/vcd_signal_dumper.c | 9 +- openair2/UTIL/LOG/vcd_signal_dumper.h | 7 + targets/ARCH/COMMON/common_lib.h | 2 + targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c | 115 +++++-- targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c | 63 ++-- .../ETHERNET/USERSPACE/LIB/ethernet_lib.c | 65 +++- .../ETHERNET/USERSPACE/LIB/ethernet_lib.h | 14 +- targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h | 12 + .../CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf | 1 + .../CONF/rcc.band7.tm1.if4p5.100PRB.conf | 3 +- .../rcc.band7.tm1.if4p5.100PRB.usrpb210.conf | 1 + .../CONF/rcc.band7.tm1.if4p5.25PRB.lo.conf | 192 +++++++++++ .../rcc.band7.tm1.if4p5.25PRB.usrpb210.conf | 1 + .../CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf | 192 +++++++++++ .../rcc.band7.tm1.if4p5.50PRB.usrpb210.conf | 3 +- .../rcc.band7.tm1.if5.100PRB.usrpb210.conf | 3 +- .../rcc.band7.tm1.if5.25PRB.usrpb210.conf | 1 + .../rcc.band7.tm1.if5.50PRB.usrpb210.conf | 1 + .../CONF/rcc.band7.tm1.if5.usrpb210.conf | 3 +- .../CONF/rcc.band7.tm1.usrpb210.conf | 3 +- .../rru.band7.tm1.if4p5.100PRB.usrpb210.conf | 1 + .../rru.band7.tm1.if4p5.25PRB.oaisim.conf | 194 +++++++++++ .../rru.band7.tm1.if4p5.25PRB.usrpb210.conf | 1 + .../rru.band7.tm1.if4p5.50PRB.oaisim.conf | 194 +++++++++++ ....band7.tm1.if4p5.50PRB.usrpb210-conga.conf | 1 + .../rru.band7.tm1.if4p5.50PRB.usrpb210.conf | 1 + .../CONF/rru.band7.tm1.if4p5.usrpb210.conf | 1 + .../rru.band7.tm1.if5.100PRB.usrpb210.conf | 1 + .../rru.band7.tm1.if5.25PRB.usrpb210.conf | 1 + .../rru.band7.tm1.if5.50PRB.usrpb210.conf | 1 + .../CONF/rru.band7.tm1.if5.usrpb210.conf | 1 + .../CONF/rru.band7.tm1.usrpb210.conf | 1 + targets/RT/USER/lte-enb.c | 51 ++- 40 files changed, 1477 insertions(+), 252 deletions(-) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.lo.conf create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.oaisim.conf create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.oaisim.conf diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index 924eef11b9..635fabd54d 100755 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -39,6 +39,11 @@ #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "UTIL/LOG/vcd_signal_dumper.h" + + +const uint8_t lin2alaw_if4p5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; +const uint16_t alaw2lin_if4p5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; + void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type, int k) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; int32_t **txdataF = (eNB->CC_id==0) ? eNB->common_vars.txdataF[0] : PHY_vars_eNB_g[0][0]->common_vars.txdataF[0]; @@ -79,19 +84,21 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type gen_IF4p5_dl_header(packet_header, frame, subframe); for (symbol_id=0; symbol_idCC_id==1) LOG_I(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,frame,subframe,symbol_id); for (element_id=0; element_idCC_id][blockoffsetF+element_id]; - data_block[element_id] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); + data_block[element_id] = ((uint16_t) lin2alaw_if4p5[*i]) | (lin2alaw_if4p5[*(i+1)]<<8); i = (uint16_t*) &txdataF[eNB->CC_id][slotoffsetF+element_id]; - data_block[element_id+db_halflength] = ((uint16_t) lin2alaw[*i]) | (lin2alaw[*(i+1)]<<8); + data_block[element_id+db_halflength] = ((uint16_t) lin2alaw_if4p5[*i]) | (lin2alaw_if4p5[*(i+1)]<<8); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); packet_header->frame_status &= ~(0x000f<<26); packet_header->frame_status |= (symbol_id&0x000f)<<26; - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, symbol_id, &tx_buffer, @@ -100,7 +107,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type IF4p5_PDLFFT)) < 0) { perror("ETHERNET write for IF4p5_PDLFFT\n"); } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); slotoffsetF += fp->ofdm_symbol_size; blockoffsetF += fp->ofdm_symbol_size; } @@ -127,19 +134,23 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type gen_IF4p5_ul_header(packet_header, packet_type, frame, subframe); if (packet_type == IF4p5_PULFFT) { - for (symbol_id=fp->symbols_per_tti-nsym; symbol_idsymbols_per_tti; symbol_id++) { + for (symbol_id=fp->symbols_per_tti-nsym; symbol_idsymbols_per_tti; symbol_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF4_SYMBOL, symbol_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); LOG_D(PHY,"IF4p5_PULFFT: frame %d, subframe %d, symbol %d\n",frame,subframe,symbol_id); for (element_id=0; element_idframe_status &= ~(0x000f<<26); packet_header->frame_status |= (symbol_id&0x000f)<<26; - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, symbol_id, &tx_buffer, @@ -148,7 +159,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type IF4p5_PULFFT)) < 0) { perror("ETHERNET write for IF4p5_PULFFT\n"); } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); slotoffsetF += fp->ofdm_symbol_size; blockoffsetF += fp->ofdm_symbol_size; } @@ -186,7 +197,7 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type (&rxsigF[0][k]), PRACH_BLOCK_SIZE_BYTES); } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice, symbol_id, &tx_buffer_prach, @@ -194,7 +205,8 @@ void send_IF4p5(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type 1, IF4p5_PRACH)) < 0) { perror("ETHERNET write for IF4p5_PRACH\n"); - } + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); } else { AssertFatal(1==0, "send_IF4p5 - Unknown packet_type %x", packet_type); } @@ -227,7 +239,8 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t IF4p5_header_t *packet_header=NULL; uint16_t *data_block=NULL, *i=NULL; - + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); if (eNB->ifdevice.trx_read_func(&eNB->ifdevice, (int64_t*) packet_type, &rx_buffer, @@ -235,6 +248,7 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t 0) < 0) { perror("ETHERNET read"); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); if (eth->flags == ETH_RAW_IF4p5_MODE) { packet_header = (IF4p5_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES); @@ -254,41 +268,45 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t if (*packet_type == IF4p5_PDLFFT) { *symbol_number = ((packet_header->frame_status)>>26)&0x000f; - + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF4_SYMBOL, *symbol_number ); LOG_D(PHY,"DL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number); slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1; blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; - + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); for (element_id=0; element_id>8) ]; + *i = alaw2lin_if4p5[ (data_block[element_id] & 0xff) ]; + *(i+1) = alaw2lin_if4p5[ (data_block[element_id]>>8) ]; i = (uint16_t*) &txdataF[0][slotoffsetF+element_id]; - *i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ]; - *(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ]; + *i = alaw2lin_if4p5[ (data_block[element_id+db_halflength] & 0xff) ]; + *(i+1) = alaw2lin_if4p5[ (data_block[element_id+db_halflength]>>8) ]; } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); } else if (*packet_type == IF4p5_PULFFT) { *symbol_number = ((packet_header->frame_status)>>26)&0x000f; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF4_SYMBOL, *symbol_number ); + if (eNB->CC_id==0) LOG_D(PHY,"UL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number); - if (eNB->CC_id==1) LOG_I(PHY,"UL_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe,*symbol_number); - - slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size) + 1; - blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength - 1; - + slotoffsetF = (*symbol_number)*(fp->ofdm_symbol_size); + blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); for (element_id=0; element_id>8) ]; + *i = alaw2lin_if4p5[ (data_block[element_id] & 0xff) ]; + *(i+1) = alaw2lin_if4p5[ (data_block[element_id]>>8) ]; i = (uint16_t*) &rxdataF[0][slotoffsetF+element_id]; - *i = alaw2lin[ (data_block[element_id+db_halflength] & 0xff) ]; - *(i+1) = alaw2lin[ (data_block[element_id+db_halflength]>>8) ]; + *i = alaw2lin_if4p5[ (data_block[element_id+db_halflength] & 0xff) ]; + *(i+1) = alaw2lin_if4p5[ (data_block[element_id+db_halflength]>>8) ]; + + //if (element_id==0) LOG_I(PHY,"recv_if4p5: symbol %d rxdata0 = (%u,%u)\n",*symbol_number,*i,*(i+1)); } - - } else if (*packet_type == IF4p5_PRACH) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); + } else if (*packet_type == IF4p5_PRACH) { + LOG_D(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe); if (eNB->CC_id==1) LOG_I(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe); // FIX: hard coded prach samples length diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index 5b1c834705..85e6b7429c 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -31,13 +31,20 @@ */ #include "PHY/defs.h" +#include "PHY/TOOLS/alaw_lut.h" -#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +//#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "UTIL/LOG/vcd_signal_dumper.h" //#define DEBUG_DL_MOBIPASS //#define DEBUG_UL_MOBIPASS #define SUBFRAME_SKIP_NUM_MOBIPASS 8 +const uint8_t lin2alaw_if5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; + +const uint16_t alaw2lin_if5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; + +struct timespec start_comp, start_decomp, end_comp, end_decomp; int dummy_cnt = 0; int subframe_skip_extra = 0; int start_flag = 1; @@ -47,55 +54,128 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; int32_t *tx_buffer=NULL; - int8_t dummy_buffer[fp->samples_per_tti*2]; - uint16_t packet_id=0, i=0; + void *alaw_buffer = eNB->ifbuffer.tx[subframe&1]; + uint16_t *data_block = NULL; + uint16_t *j = NULL; + uint16_t packet_id=0, i=0, element_id=0; uint32_t spp_eth = (uint32_t) eNB->ifdevice.openair0_cfg->samples_per_packet; uint32_t spsf = (uint32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); - + eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); if (packet_type == IF5_RRH_GW_DL) { - - for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti]; - - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); - eNB->ifdevice.trx_write_func(&eNB->ifdevice, - (proc_timestamp + packet_id*spp_eth), - (void**)txp, - spp_eth, - fp->nb_antennas_tx, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); + if (eth->compression == ALAW_COMPRESS) { + if (eth->flags == ETH_RAW_MODE) { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); + } else { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); + } + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_comp); + for (i=0; i < fp->nb_antennas_tx; i++) { + for (element_id=0; element_id< spp_eth; element_id++){ + j = (uint16_t*) &eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; + data_block[element_id] = ((uint16_t) lin2alaw_if5[*j]) | (lin2alaw_if5[*(j+1)]<<8); + } + } + clock_gettime( CLOCK_MONOTONIC, &end_comp); + LOG_D(HW,"[SF %d] Compress_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_comp); + eNB->ifdevice.trx_write_func(&eNB->ifdevice, + (proc_timestamp + packet_id*spp_eth), + (void**)&data_block, + spp_eth, + fp->nb_antennas_tx, + 0); + clock_gettime( CLOCK_MONOTONIC, &end_comp); + LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); + } + } else if (eth->compression == NO_COMPRESS) { for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] += spp_eth; + txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti]; + + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_comp); + eNB->ifdevice.trx_write_func(&eNB->ifdevice, + (proc_timestamp + packet_id*spp_eth), + (void**)txp, + spp_eth, + fp->nb_antennas_tx, + 0); + clock_gettime( CLOCK_MONOTONIC, &end_comp); + LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); + for (i=0; i < fp->nb_antennas_tx; i++) + txp[i] += spp_eth; + } } - } else if (packet_type == IF5_RRH_GW_UL) { - - for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; - - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); - eNB->ifdevice.trx_write_func(&eNB->ifdevice, - (proc_timestamp + packet_id*spp_eth), - (void**)rxp, - spp_eth, - fp->nb_antennas_rx, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); + if (eth->compression == ALAW_COMPRESS) { + if (eth->flags == ETH_RAW_MODE) { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); + } else { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); + } + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_comp); + for (i=0; i < fp->nb_antennas_rx; i++) { + for (element_id=0; element_id< spp_eth; element_id++){ + j = (uint16_t*) &eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; + data_block[element_id] = ((uint16_t) lin2alaw_if5[*j]) | (lin2alaw_if5[*(j+1)]<<8); + if (packet_id == 0 && element_id == 0) { + //printf("(UL_Tx)Ori: %u(%d, %d); ALAW: %u; SF %u\n",eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id],*j,*(j+1),data_block[element_id],subframe); + } + } + } + clock_gettime( CLOCK_MONOTONIC, &end_comp); + LOG_D(HW,"[SF %d] Compress_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_comp); + eNB->ifdevice.trx_write_func(&eNB->ifdevice, + (proc_timestamp + packet_id*spp_eth), + (void**)&data_block, + spp_eth, + fp->nb_antennas_rx, + 0); + clock_gettime( CLOCK_MONOTONIC, &end_comp); + LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); + } + } else if (eth->compression == NO_COMPRESS) { for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] += spp_eth; - - } + rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_comp); + eNB->ifdevice.trx_write_func(&eNB->ifdevice, + (proc_timestamp + packet_id*spp_eth), + (void**)rxp, + spp_eth, + fp->nb_antennas_rx, + 0); + clock_gettime( CLOCK_MONOTONIC, &end_comp); + LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); + for (i=0; i < fp->nb_antennas_rx; i++) + rxp[i] += spp_eth; + + } + } } else if (packet_type == IF5_MOBIPASS) { uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; @@ -179,56 +259,129 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; - uint16_t packet_id=0, i=0; + uint16_t packet_id=0, i=0, element_id=0; int8_t dummy_buffer_rx[fp->samples_per_tti*2]; uint8_t rxe; int32_t spp_eth = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_packet; int32_t spsf = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10; - + void *alaw_buffer = eNB->ifbuffer.rx; + uint16_t *data_block = NULL; + uint16_t *j = NULL; openair0_timestamp timestamp[spsf / spp_eth]; + eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 ); if (packet_type == IF5_RRH_GW_DL) { - - for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti]; - - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + if (eth->compression == ALAW_COMPRESS) { + if (eth->flags == ETH_RAW_MODE) { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); + } else { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); + } + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_decomp); + eNB->ifdevice.trx_read_func(&eNB->ifdevice, + ×tamp[packet_id], + (void**)&data_block, + spp_eth, + fp->nb_antennas_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); - eNB->ifdevice.trx_read_func(&eNB->ifdevice, - ×tamp[packet_id], - (void**)txp, - spp_eth, - fp->nb_antennas_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); + clock_gettime( CLOCK_MONOTONIC, &end_decomp); + LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_decomp); + for (i=0; i < fp->nb_antennas_tx; i++) { + for (element_id=0; element_id< spp_eth; element_id++) { + j = (uint16_t*) &eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; + *j = alaw2lin_if5[ (data_block[element_id] & 0xff) ]; + *(j+1) = alaw2lin_if5[ (data_block[element_id]>>8) ]; + } + } + clock_gettime( CLOCK_MONOTONIC, &end_decomp); + LOG_D(HW,"[SF %d] Decomperss_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); + } + } else if (eth->compression == NO_COMPRESS) { for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] += spp_eth; - - } + txp[i] = (void*)&eNB->common_vars.txdata[0][i][subframe*fp->samples_per_tti]; + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_decomp); + eNB->ifdevice.trx_read_func(&eNB->ifdevice, + ×tamp[packet_id], + (void**)txp, + spp_eth, + fp->nb_antennas_tx); + clock_gettime( CLOCK_MONOTONIC, &end_decomp); + LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); + for (i=0; i < fp->nb_antennas_tx; i++) + txp[i] += spp_eth; + + } + } *proc_timestamp = timestamp[0]; } else if (packet_type == IF5_RRH_GW_UL) { - - for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; - - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); - eNB->ifdevice.trx_read_func(&eNB->ifdevice, - ×tamp[packet_id], - (void**)rxp, - spp_eth, - fp->nb_antennas_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); + if (eth->compression == ALAW_COMPRESS) { + if (eth->flags == ETH_RAW_MODE) { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); + } else { + data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); + } + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_decomp); + eNB->ifdevice.trx_read_func(&eNB->ifdevice, + ×tamp[packet_id], + (void**)&data_block, + spp_eth, + fp->nb_antennas_rx); + clock_gettime( CLOCK_MONOTONIC, &end_decomp); + LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_decomp); + for (i=0; i < fp->nb_antennas_rx; i++) { + for (element_id=0; element_id< spp_eth; element_id++) { + j = (uint16_t*) &eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id]; + *j = alaw2lin_if5[ (data_block[element_id] & 0xff) ]; + *(j+1) = alaw2lin_if5[ (data_block[element_id]>>8) ]; + } + } + clock_gettime( CLOCK_MONOTONIC, &end_decomp); + LOG_D(HW,"[SF %d] Decomperss_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); + } + } else if (eth->compression == NO_COMPRESS) { for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] += spp_eth; + rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti]; + + for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_decomp); + eNB->ifdevice.trx_read_func(&eNB->ifdevice, + ×tamp[packet_id], + (void**)rxp, + spp_eth, + fp->nb_antennas_rx); + clock_gettime( CLOCK_MONOTONIC, &end_decomp); + LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); + for (i=0; i < fp->nb_antennas_rx; i++) + rxp[i] += spp_eth; + } } - *proc_timestamp = timestamp[0]; } else if (packet_type == IF5_MOBIPASS) { @@ -363,3 +516,30 @@ if (eNB->CC_id>0) { return; } + +void malloc_IF5_buffer(PHY_VARS_eNB *eNB) { + // Keep the size large enough, 3840 is the number of samples in a packet for 20MHz BW + int i; + eth_state_t *eth = (eth_state_t*) (eNB->ifdevice.priv); + if (eth->compression == ALAW_COMPRESS) { + if (eth->flags == ETH_RAW_MODE) { + for (i=0;i<10;i++) + eNB->ifbuffer.tx[i] = malloc(RAW_PACKET_SIZE_BYTES_ALAW(3840)); + eNB->ifbuffer.rx = malloc(RAW_PACKET_SIZE_BYTES_ALAW(3840)); + } else { + for (i=0;i<10;i++) + eNB->ifbuffer.tx[i] = malloc(UDP_PACKET_SIZE_BYTES_ALAW(3840)); + eNB->ifbuffer.rx = malloc(UDP_PACKET_SIZE_BYTES_ALAW(3840)); + } + } else if (eth->compression == NO_COMPRESS) { + if (eth->flags == ETH_RAW_MODE) { + for (i=0;i<10;i++) + eNB->ifbuffer.tx[i] = malloc(RAW_PACKET_SIZE_BYTES(3840)); + eNB->ifbuffer.rx = malloc(RAW_PACKET_SIZE_BYTES(3840)); + } else { + for (i=0;i<10;i++) + eNB->ifbuffer.tx[i] = malloc(UDP_PACKET_SIZE_BYTES(3840)); + eNB->ifbuffer.rx = malloc(UDP_PACKET_SIZE_BYTES(3840)); + } + } +} diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.h b/openair1/PHY/LTE_TRANSPORT/if5_tools.h index b6ebe8c841..88852de58b 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.h +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.h @@ -59,3 +59,5 @@ typedef struct IF5_mobipass_header IF5_mobipass_header_t; void send_IF5(PHY_VARS_eNB*, openair0_timestamp, int, uint8_t*, uint16_t); void recv_IF5(PHY_VARS_eNB*, openair0_timestamp*, int, uint16_t); + +void malloc_IF5_buffer(PHY_VARS_eNB*); diff --git a/openair1/PHY/TOOLS/alaw_lut.h b/openair1/PHY/TOOLS/alaw_lut.h index 7e6b93c9f0..abf4b142cb 100644 --- a/openair1/PHY/TOOLS/alaw_lut.h +++ b/openair1/PHY/TOOLS/alaw_lut.h @@ -32,8 +32,16 @@ // Linear to ALaw // 16 bit signed integer (typecasted as uint16_t) to 8 bit unsigned integer -const uint8_t lin2alaw[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; +extern const uint8_t lin2alaw_if4p5[65536]; +//const uint8_t lin2alaw[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; // ALaw to Linear // 8 bit unsigned integer to 16 bit signed integer (typecasted as uint16_t) -const uint16_t alaw2lin[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; +extern const uint16_t alaw2lin_if4p5[256]; +//const uint16_t alaw2lin[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; + + +extern const uint8_t lin2alaw_if5[65536]; +//const uint8_t lin2alaw_if5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85}; +extern const uint16_t alaw2lin_if5[256]; +//const uint16_t alaw2lin_if5[256] = {60032, 60288, 59520, 59776, 61056, 61312, 60544, 60800, 57984, 58240, 57472, 57728, 59008, 59264, 58496, 58752, 62784, 62912, 62528, 62656, 63296, 63424, 63040, 63168, 61760, 61888, 61504, 61632, 62272, 62400, 62016, 62144, 43520, 44544, 41472, 42496, 47616, 48640, 45568, 46592, 35328, 36352, 33280, 34304, 39424, 40448, 37376, 38400, 54528, 55040, 53504, 54016, 56576, 57088, 55552, 56064, 50432, 50944, 49408, 49920, 52480, 52992, 51456, 51968, 65192, 65208, 65160, 65176, 65256, 65272, 65224, 65240, 65064, 65080, 65032, 65048, 65128, 65144, 65096, 65112, 65448, 65464, 65416, 65432, 65512, 65528, 65480, 65496, 65320, 65336, 65288, 65304, 65384, 65400, 65352, 65368, 64160, 64224, 64032, 64096, 64416, 64480, 64288, 64352, 63648, 63712, 63520, 63584, 63904, 63968, 63776, 63840, 64848, 64880, 64784, 64816, 64976, 65008, 64912, 64944, 64592, 64624, 64528, 64560, 64720, 64752, 64656, 64688, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848}; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index cad508c7c2..e33220eb58 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -78,7 +78,8 @@ void exit_fun(const char* s); extern int exit_openair; - +struct timespec start_fh, start_fh_prev; +int start_fh_sf, start_fh_prev_sf; // Fix per CC openair rf/if device update // extern openair0_device openair0; @@ -2751,6 +2752,10 @@ void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) { if (eNB->node_function == NGFI_RRU_IF4p5) { /// **** send_IF4 of rxdataF to RCC (no prach now) **** /// send_IF4p5(eNB, proc_rxtx->frame_rx, proc_rxtx->subframe_rx, IF4p5_PULFFT, 0); + start_fh_prev = start_fh; + start_fh_prev_sf = start_fh_sf; + clock_gettime( CLOCK_MONOTONIC, &start_fh); + start_fh_sf = proc_rxtx->subframe_rx; } } @@ -2762,6 +2767,10 @@ void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) { /// **** send_IF5 of rxdata to BBU **** /// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); send_IF5(eNB, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL); + start_fh_prev = start_fh; + start_fh_prev_sf = start_fh_sf; + clock_gettime( CLOCK_MONOTONIC, &start_fh); + start_fh_sf = proc->subframe_rx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); } diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2a48aefbaf..36b9e03935 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -208,6 +208,7 @@ #define ENB_CONFIG_STRING_RRH_GW_IQ_TXSHIFT "iq_txshift" #define ENB_CONFIG_STRING_RRH_GW_TX_SAMPLE_ADVANCE "tx_sample_advance" #define ENB_CONFIG_STRING_RRH_GW_TX_SCHEDULING_ADVANCE "tx_scheduling_advance" +#define ENB_CONFIG_STRING_RRH_GW_IF_COMPRESSION "if_compression" #define ENB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity" #define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none" @@ -338,6 +339,7 @@ void enb_config_display(void) } else { printf( "\tRF target : \tNONE:\n"); } + printf( "\tif_compression : \t%s Compression:\n",(enb_properties.properties[i]->rrh_gw_config[j].if_compress == 1)? "ALAW" : "None"); } } @@ -657,6 +659,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) char* ipv6 = NULL; char* active = NULL; char* preference = NULL; + char* if_compression = NULL; char* tr_preference = NULL; char* rf_preference = NULL; @@ -2327,82 +2330,91 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) // RRH Config setting_rrh_gws = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_RRH_GW_CONFIG); if ( setting_rrh_gws != NULL) { - num_rrh_gw = config_setting_length(setting_rrh_gws); - enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0; + num_rrh_gw = config_setting_length(setting_rrh_gws); + enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0; - for (j = 0; j < num_rrh_gw; j++) { - setting_rrh_gw = config_setting_get_elem(setting_rrh_gws, j); - - if ( !( - config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME, (const char **)&if_name) - && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS, (const char **)&ipv4) - && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS , (const char **)&ipv4_remote) - && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT, &local_port) - && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT, &remote_port) - && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_ACTIVE, (const char **)&active) - && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TRANSPORT_PREFERENCE, (const char **)&tr_preference) - && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_RF_TARGET_PREFERENCE, (const char **)&rf_preference) - && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_IQ_TXSHIFT, &iq_txshift) - && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SAMPLE_ADVANCE, &tx_sample_advance) - && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SCHEDULING_ADVANCE, &tx_scheduling_advance) - ) - ) { - AssertFatal (0, - "Failed to parse eNB configuration file %s, %u th enb %u the RRH GW address !\n", - lib_config_file_name_pP, i, j); - continue; // FIXME will prevent segfaults below, not sure what happens at function exit... - } - - enb_properties.properties[enb_properties_index]->nb_rrh_gw += 1; - - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rrh_gw_if_name = strdup(if_name); - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address = strdup(ipv4); - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = strdup(ipv4_remote); - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port = local_port; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port = remote_port; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].iq_txshift = iq_txshift; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_sample_advance = tx_sample_advance; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_scheduling_advance= tx_scheduling_advance; - - if (strcmp(active, "yes") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 1; - } - - if (strcmp(tr_preference, "udp") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1; - } else if (strcmp(tr_preference, "raw") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1; - } else if (strcmp(tr_preference, "udp_if4p5") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udpif4p5 = 1; - } else if (strcmp(tr_preference, "raw_if4p5") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif4p5 = 1; - } else if (strcmp(tr_preference, "raw_if5_mobipass") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif5_mobipass = 1; - } else {//if (strcmp(preference, "no") == 0) - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1; - } - - if (strcmp(rf_preference, "exmimo") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1; - } else if (strcmp(rf_preference, "usrp_b200") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1; - } else if (strcmp(rf_preference, "usrp_x300") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1; - } else if (strcmp(rf_preference, "bladerf") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1; - } else if (strcmp(rf_preference, "lmsdr") == 0) { - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1; - } else {//if (strcmp(preference, "no") == 0) + for (j = 0; j < num_rrh_gw; j++) { + setting_rrh_gw = config_setting_get_elem(setting_rrh_gws, j); - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1; - enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1; - - } - } + if ( !( + config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME, (const char **)&if_name) + && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS, (const char **)&ipv4) + && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS , (const char **)&ipv4_remote) + && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT, &local_port) + && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT, &remote_port) + && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_ACTIVE, (const char **)&active) + && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TRANSPORT_PREFERENCE, (const char **)&tr_preference) + && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_RF_TARGET_PREFERENCE, (const char **)&rf_preference) + && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_IQ_TXSHIFT, &iq_txshift) + && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SAMPLE_ADVANCE, &tx_sample_advance) + && config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SCHEDULING_ADVANCE, &tx_scheduling_advance) + && config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_IF_COMPRESSION, (const char **)&if_compression) + ) + ) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, %u th enb %u the RRH GW address !\n", + lib_config_file_name_pP, i, j); + continue; // FIXME will prevent segfaults below, not sure what happens at function exit... + } + + enb_properties.properties[enb_properties_index]->nb_rrh_gw += 1; + + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rrh_gw_if_name = strdup(if_name); + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address = strdup(ipv4); + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = strdup(ipv4_remote); + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port = local_port; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port = remote_port; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].iq_txshift = iq_txshift; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_sample_advance = tx_sample_advance; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_scheduling_advance= tx_scheduling_advance; + + if (strcmp(active, "yes") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 1; + } + + if (strcmp(tr_preference, "udp") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1; + } else if (strcmp(tr_preference, "raw") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1; + } else if (strcmp(tr_preference, "udp_if4p5") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udpif4p5 = 1; + } else if (strcmp(tr_preference, "raw_if4p5") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif4p5 = 1; + } else if (strcmp(tr_preference, "raw_if5_mobipass") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif5_mobipass = 1; + } else {//if (strcmp(preference, "no") == 0) + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1; + } + + if (strcmp(rf_preference, "exmimo") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1; + } else if (strcmp(rf_preference, "usrp_b200") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1; + } else if (strcmp(rf_preference, "usrp_x300") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1; + } else if (strcmp(rf_preference, "bladerf") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1; + } else if (strcmp(rf_preference, "lmsdr") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1; + } else {//if (strcmp(preference, "no") == 0) + + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1; + + } + + if (strcmp(if_compression, "alaw") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 1; + } else if (strcmp(if_compression, "none") == 0) { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 0; + } else { + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 0; + } + } } else { enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0; enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rrh_gw_if_name = "none"; @@ -2421,8 +2433,9 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 0; enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 0; enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 0; + enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 0; } - + // SCTP SETTING enb_properties.properties[enb_properties_index]->sctp_out_streams = SCTP_OUT_STREAMS; enb_properties.properties[enb_properties_index]->sctp_in_streams = SCTP_IN_STREAMS; diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index fd53395311..343a3c26ec 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -85,6 +85,7 @@ typedef struct rrh_gw_config_s { uint8_t udpif4p5; uint8_t rawif4p5; uint8_t rawif5_mobipass; + uint8_t if_compress; int tx_scheduling_advance; int tx_sample_advance; int iq_txshift; diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c index 96f173833a..88508adac3 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.c +++ b/openair2/UTIL/LOG/vcd_signal_dumper.c @@ -181,6 +181,10 @@ const char* eurecomVariablesNames[] = { "ue0_trx_write_ns", "ue0_trx_read_ns_missing", "ue0_trx_write_ns_missing" + "send_if4_symbol", + "recv_if4_symbol", + "send_if5_pkt_id", + "recv_if5_pkt_id" }; const char* eurecomFunctionsNames[] = { @@ -375,7 +379,10 @@ const char* eurecomFunctionsNames[] = { "send_if4", "recv_if4", "send_if5", - "recv_if5" + "recv_if5", + + "compress_if", + "decompress_if" }; struct vcd_module_s vcd_modules[VCD_SIGNAL_DUMPER_MODULE_END] = { diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h index e1bcff39fc..fde3d429ea 100644 --- a/openair2/UTIL/LOG/vcd_signal_dumper.h +++ b/openair2/UTIL/LOG/vcd_signal_dumper.h @@ -147,6 +147,10 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN5, VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN6, VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN7, + VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF4_SYMBOL, + VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF4_SYMBOL, + VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, + VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_SIZE, VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_ERR, VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS, @@ -354,6 +358,9 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, + VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, + VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, + VCD_SIGNAL_DUMPER_FUNCTIONS_LAST, VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST, } vcd_signal_dump_functions; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 2eb0a506be..be69a7027a 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -242,6 +242,8 @@ typedef struct { uint8_t iq_txshift; //! transport type preference (RAW/UDP) uint8_t transp_preference; + //! compression enable (0: No comp/ 1: A-LAW) + uint8_t if_compress; //! radio front end preference (EXMIMO,USRP, BALDERF,LMSSDR) uint8_t rf_preference; } eth_params_t; diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c index 5815f2b1a6..0e2a5ceb36 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -145,21 +145,28 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi memcpy(buff2,(void*)ð->eh,MAC_HEADER_SIZE_BYTES); *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t))=1+(i<<1); *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp; + + int sent_byte; + if (eth->compression = ALAW_COMPRESS) { + sent_byte = RAW_PACKET_SIZE_BYTES_ALAW(nsamps); + } else { + sent_byte = RAW_PACKET_SIZE_BYTES(nsamps); + } /*printf("[RRH]write mod_%d %d , len %d, buff %p \n", Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/ - while(bytes_sent < RAW_PACKET_SIZE_BYTES(nsamps)) { + while(bytes_sent < sent_byte) { #if DEBUG printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n", (void *)(buff2+bytes_sent), - RAW_PACKET_SIZE_BYTES(nsamps) - bytes_sent, + sent_byte - bytes_sent, bytes_sent); #endif /* Send packet */ bytes_sent += send(eth->sockfd, buff2, - RAW_PACKET_SIZE_BYTES(nsamps), + sent_byte, sendto_flag); if ( bytes_sent == -1) { eth->num_tx_errors++; @@ -172,7 +179,7 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)), *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)), bytes_sent); - dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, RAW_PACKET_SIZE_BYTES(nsamps), TX_FLAG); + dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, sent_byte, TX_FLAG); #endif eth->tx_actual_nsamps=bytes_sent>>2; eth->tx_count++; @@ -240,6 +247,8 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi int i=0; eth_state_t *eth = (eth_state_t*)device->priv; int rcvfrom_flag =0; + int block_cnt=0; + int again_cnt=0; eth->rx_nsamps=nsamps; @@ -247,25 +256,54 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi /* buff[i] points to the position in rx buffer where the payload to be received will be placed buff2 points to the position in rx buffer where the packet header will be placed */ void *buff2 = (void*)(buff[i]-APP_HEADER_SIZE_BYTES-MAC_HEADER_SIZE_BYTES); - + /* we don't want to ovewrite with the header info the previous rx buffer data so we store it*/ struct ether_header temp = *(struct ether_header *)buff2; int32_t temp0 = *(int32_t *)(buff2 + MAC_HEADER_SIZE_BYTES); openair0_timestamp temp1 = *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)); - + bytes_received=0; + int receive_bytes; + if (eth->compression == ALAW_COMPRESS) { + receive_bytes = RAW_PACKET_SIZE_BYTES_ALAW(nsamps); + } else { + receive_bytes = RAW_PACKET_SIZE_BYTES(nsamps); + } - while(bytes_received < RAW_PACKET_SIZE_BYTES(nsamps)) { + while(bytes_received < receive_bytes) { + again: bytes_received +=recv(eth->sockfd, buff2, - RAW_PACKET_SIZE_BYTES(nsamps), + receive_bytes, rcvfrom_flag); - + if (bytes_received ==-1) { eth->num_rx_errors++; - perror("ETHERNET IF5 READ: "); - if (errno == EAGAIN) continue; - exit(-1); + if (errno == EAGAIN) { + again_cnt++; + usleep(10); + if (again_cnt == 1000) { + perror("ETHERNET IF5 READ (EAGAIN): "); + exit(-1); + } else { + printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n"); + goto again; + } + } else if (errno == EWOULDBLOCK) { + block_cnt++; + usleep(10); + if (block_cnt == 1000) { + perror("ETHERNET IF5 READ (EWOULDBLOCK): "); + exit(-1); + } else { + printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); + goto again; + } + } else { + perror("ETHERNET IF5 READ"); + printf("(%s):\n", strerror(errno)); + exit(-1); + } } else { /* store the timestamp value from packet's header */ *timestamp = *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)); @@ -280,7 +318,7 @@ int trx_eth_read_raw(openair0_device *device, openair0_timestamp *timestamp, voi *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)), *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)), bytes_received); - dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, RAW_PACKET_SIZE_BYTES(nsamps),RX_FLAG); + dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, receive_bytes, RX_FLAG); #endif @@ -303,19 +341,43 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t; IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0] + MAC_HEADER_SIZE_BYTES); + int block_cnt=0; + int again_cnt=0; -#ifdef DEBUG - printf("Reading from device %p, eth %p, sockfd %d\n",device,eth,eth->sockfd); -#endif - - bytes_received = recv(eth->sockfd, - buff[0], - packet_size, - MSG_PEEK); - if (bytes_received ==-1) { - eth->num_rx_errors++; - perror("ETHERNET IF4p5 READ (header): "); - exit(-1); + while (bytes_received < packet_size) { + again: + bytes_received = recv(eth->sockfd, + buff[0], + packet_size, + MSG_PEEK); + if (bytes_received ==-1) { + eth->num_rx_errors++; + if (errno == EAGAIN) { + again_cnt++; + usleep(10); + if (again_cnt == 1000) { + perror("ETHERNET IF4p5 READ (EAGAIN): "); + exit(-1); + } else { + printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n"); + goto again; + } + } else if (errno == EWOULDBLOCK) { + block_cnt++; + usleep(10); + if (block_cnt == 1000) { + perror("ETHERNET IF4p5 READ (EWOULDBLOCK): "); + exit(-1); + } else { + printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); + goto again; + } + } else { + perror("ETHERNET IF4p5 READ"); + printf("(%s):\n", strerror(errno)); + exit(-1); + } + } } #ifdef DEBUG for (int i=0;isockfd, diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c index 898382cf6a..270b081c0d 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -260,22 +260,30 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi // eth->pck_header.seq_num = pck_seq_num; //eth->pck_header.antenna_id = 1+(i<<1); //eth->pck_header.timestamp = timestamp; - *(uint16_t *)buff2 = pck_seq_num; + *(uint16_t *)buff2 = eth->pck_seq_num; *(uint16_t *)(buff2 + sizeof(uint16_t)) = 1+(i<<1); *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, pck_seq_num); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, eth->pck_seq_num); + + int sent_byte; + if (eth->compression == ALAW_COMPRESS) { + sent_byte = UDP_PACKET_SIZE_BYTES_ALAW(nsamps); + } else { + sent_byte = UDP_PACKET_SIZE_BYTES(nsamps); + } - while(bytes_sent < UDP_PACKET_SIZE_BYTES(nsamps)) { + //while(bytes_sent < sent_byte) { + //printf("eth->pck_seq_num: %d\n", eth->pck_seq_num); #if DEBUG printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n", (void *)(buff2+bytes_sent), - UDP_PACKET_SIZE_BYTES(nsamps) - bytes_sent, + sent_byte - bytes_sent, bytes_sent); #endif /* Send packet */ bytes_sent += sendto(eth->sockfd, buff2, - UDP_PACKET_SIZE_BYTES(nsamps), + sent_byte, sendto_flag, (struct sockaddr*)ð->dest_addr, eth->addr_len); @@ -291,14 +299,15 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi *(int16_t *)(buff2 + sizeof(int16_t)), *(openair0_timestamp *)(buff2 + sizeof(int32_t)), bytes_sent); - dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, UDP_PACKET_SIZE_BYTES(nsamps), TX_FLAG); + dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, sent_byte, TX_FLAG); #endif eth->tx_actual_nsamps=bytes_sent>>2; eth->tx_count++; - pck_seq_num++; - if ( pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame) ) pck_seq_num = 1; + eth->pck_seq_num++; + if ( eth->pck_seq_num > MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame) ) eth->pck_seq_num = 1; } - } + //} + /* tx buffer values restored */ *(int32_t *)buff2 = temp0; *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1; @@ -332,19 +341,24 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi bytes_received=0; block_cnt=0; + int receive_bytes; + if (eth->compression == ALAW_COMPRESS) { + receive_bytes = UDP_PACKET_SIZE_BYTES_ALAW(nsamps); + } else { + receive_bytes = UDP_PACKET_SIZE_BYTES(nsamps); + } - - while(bytes_received < UDP_PACKET_SIZE_BYTES(nsamps)) { + while(bytes_received < receive_bytes) { again: #if DEBUG printf("------- RX------: buff2 current position=%d remaining_bytes=%d bytes_recv=%d \n", (void *)(buff2+bytes_received), - UDP_PACKET_SIZE_BYTES(nsamps) - bytes_received, + receive_bytes - bytes_received, bytes_received); #endif bytes_received +=recvfrom(eth->sockfd, buff2, - UDP_PACKET_SIZE_BYTES(nsamps), + receive_bytes, rcvfrom_flag, (struct sockaddr *)ð->dest_addr, (socklen_t *)ð->addr_len); @@ -379,28 +393,29 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi *(int16_t *)(buff2 + sizeof(int16_t)), *(openair0_timestamp *)(buff2 + sizeof(int32_t)), bytes_received); - dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, UDP_PACKET_SIZE_BYTES(nsamps),RX_FLAG); + dump_packet((device->host_type == BBU_HOST)? "BBU":"RRH", buff2, receive_bytes, RX_FLAG); #endif /* store the timestamp value from packet's header */ *timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t)); /* store the sequence number of the previous packet received */ - if (pck_seq_num_cur == 0) { - pck_seq_num_prev = *(uint16_t *)buff2; + if (eth->pck_seq_num_cur == 0) { + eth->pck_seq_num_prev = *(uint16_t *)buff2; } else { - pck_seq_num_prev = pck_seq_num_cur; + eth->pck_seq_num_prev = eth->pck_seq_num_cur; } /* get the packet sequence number from packet's header */ - pck_seq_num_cur = *(uint16_t *)buff2; - //printf("cur=%d prev=%d buff=%d\n",pck_seq_num_cur,pck_seq_num_prev,*(uint16_t *)(buff2)); - if ( ( pck_seq_num_cur != (pck_seq_num_prev + 1) ) && !((pck_seq_num_prev==MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame)) && (pck_seq_num_cur==1 )) && !((pck_seq_num_prev==1) && (pck_seq_num_cur==1))) { - printf("out of order packet received1! %d|%d|%d\n",pck_seq_num_cur,pck_seq_num_prev,(int)*timestamp); + eth->pck_seq_num_cur = *(uint16_t *)buff2; + if ( ( eth->pck_seq_num_cur != (eth->pck_seq_num_prev + 1) ) && !((eth->pck_seq_num_prev==MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame)) && (eth->pck_seq_num_cur==1 )) && !((eth->pck_seq_num_prev==1) && (eth->pck_seq_num_cur==1))) { + //#if DEBUG + printf("Out of order packet received: current_packet=%d previous_packet=%d timestamp=%llu\n",eth->pck_seq_num_cur,eth->pck_seq_num_prev,*timestamp); + //#endif } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,pck_seq_num_cur); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,pck_seq_num_prev); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,eth->pck_seq_num_cur); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,eth->pck_seq_num_prev); eth->rx_actual_nsamps=bytes_received>>2; eth->rx_count++; - } + } } /* tx buffer values restored */ diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index 6f93ba4853..ac454067e3 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -41,16 +41,24 @@ #include #include #include +#include +#include #include "common_lib.h" #include "ethernet_lib.h" + +int num_devices_eth = 0; +struct sockaddr_in dest_addr[MAX_INST]; +int dest_addr_len[MAX_INST]; + + int trx_eth_start(openair0_device *device) { eth_state_t *eth = (eth_state_t*)device->priv; /* initialize socket */ - if (eth->flags == ETH_RAW_MODE) { + if (eth->flags == ETH_RAW_MODE) { printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n"); if (eth_socket_init_raw(device)!=0) return -1; /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ @@ -60,10 +68,14 @@ int trx_eth_start(openair0_device *device) { if(eth_get_dev_conf_raw(device)!=0) return -1; } /* adjust MTU wrt number of samples per packet */ - if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1; + if(eth->compression == ALAW_COMPRESS) { + if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES_ALAW(device->openair0_cfg->samples_per_packet))!=0) return -1; + } else { + if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1; + } if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; } else if (eth->flags == ETH_RAW_IF4p5_MODE) { - + printf("Setting ETHERNET to ETH_RAW_IF4p5_MODE\n"); if (eth_socket_init_raw(device)!=0) return -1; /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/ @@ -74,11 +86,11 @@ int trx_eth_start(openair0_device *device) { } /* adjust MTU wrt number of samples per packet */ if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; - + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; } else if (eth->flags == ETH_UDP_IF4p5_MODE) { printf("Setting ETHERNET to UDP_IF4p5_MODE\n"); - if (eth_socket_init_udp(device)!=0) return -1; + if (eth_socket_init_udp(device)!=0) return -1; if (device->host_type == BBU_HOST) { if(eth_set_dev_conf_udp(device)!=0) return -1; } else { @@ -102,7 +114,9 @@ int trx_eth_start(openair0_device *device) { /* apply additional configuration */ if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1; if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1; - + if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 200000000)!=0) return -1; + if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 200000000)!=0) return -1; + return 0; } @@ -183,10 +197,12 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value) { eth_state_t *eth = (eth_state_t*)device->priv; struct timeval timeout; struct ifreq ifr; - char system_cmd[256]; - // char* if_name=DEFAULT_IF; - // struct in_addr ia; - // struct if_nameindex *ids; + char system_cmd[256]; + int rname[] = { CTL_NET, NET_CORE, NET_CORE_RMEM_MAX }; + int wname[] = { CTL_NET, NET_CORE, NET_CORE_WMEM_MAX }; + int namelen=3; + int newval[1]; + int newlen=sizeof(newval); int ret=0; // int i=0; @@ -309,7 +325,25 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value) { perror("[ETHERNET] Can't set ring parameters\n"); } break; - + case KERNEL_RCV_BUF_MAX_SIZE: + newval[0] = value; + ret=sysctl(rname, namelen, NULL, 0, newval, newlen); + if (ret) { + fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno)); + } else{ + printf("[ETHERNET] Kernel network receive buffer max size is set to %u\n",newval[0]); + } + break; + case KERNEL_SND_BUF_MAX_SIZE: + newval[0] = value; + ret=sysctl(wname, namelen, NULL, 0, newval, newlen); + if (ret) { + fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno)); + } else{ + printf("[ETHERNET] Kernel network send buffer max size is set to %u\n",newval[0]); + } + break; + default: break; } @@ -337,6 +371,15 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference); eth->flags = ETH_RAW_MODE; } + + if (eth_params->if_compress == 0) { + eth->compression = NO_COMPRESS; + } else if (eth_params->if_compress == 1) { + eth->compression = ALAW_COMPRESS; + } else { + printf("transport_init: Unknown compression scheme %d - default to ALAW", eth_params->if_compress); + eth->compression = ALAW_COMPRESS; + } printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == BBU_HOST) ? "BBU": "RRH")); device->Mod_id = 0;//num_devices_eth++; diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h index 9f555beaa9..50a5738007 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h @@ -78,6 +78,8 @@ typedef struct { unsigned int tx_timeout_ms; /*!\brief runtime flags */ uint32_t flags; + /*!\compression enalbe */ + uint32_t compression; /*!\ time offset between transmiter timestamp and receiver timestamp */ double tdiff; /*!\ calibration */ @@ -98,7 +100,7 @@ typedef struct { int num_seq_errors; /*!\brief number of errors in interface's receiver */ int num_rx_errors; - /*!\brief umber of errors in interface's transmitter */ + /*!\brief number of errors in interface's transmitter */ int num_tx_errors; /*!\brief current TX timestamp */ @@ -117,6 +119,12 @@ typedef struct { uint64_t tx_count; /*!\brief number of packets received */ uint64_t rx_count; + /*!\brief TX sequence number*/ + uint16_t pck_seq_num; + /*!\brief Current RX sequence number*/ + uint16_t pck_seq_num_cur; + /*!\brief Previous RX sequence number */ + uint16_t pck_seq_num_prev; struct ether_header eh; @@ -155,6 +163,10 @@ typedef enum { COALESCE_PAR, /*!\brief pause parameters of ethernet device */ PAUSE_PAR, + /*!\brief kernel network receive buffer maximun size */ + KERNEL_RCV_BUF_MAX_SIZE, + /*!\brief kernel network send buffer maximun size */ + KERNEL_SND_BUF_MAX_SIZE, MAX_OPT } eth_opt_t; diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h index 5fdb962b09..93a92361c6 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h @@ -47,6 +47,14 @@ #define ETH_RAW_IF5_MOBIPASS 4 #endif +// COMMOM HEADER LENGTHS + +#define NO_COMPRESS 0 +#define ALAW_COMPRESS 1 + +#define UDP_HEADER_SIZE_BYTES 8 +#define IPV4_HEADER_SIZE_BYTES 60 // This is the maximum IPv4 header length + // Time domain RRH packet sizes #define MAC_HEADER_SIZE_BYTES (sizeof(struct ether_header)) #define MAX_PACKET_SEQ_NUM(spp,spf) (spf/spp) @@ -54,6 +62,10 @@ #define UDP_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps)) #define RAW_PACKET_SIZE_BYTES(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES(nsamps)) +#define PAYLOAD_SIZE_BYTES_ALAW(nsamps) (nsamps<<1) +#define UDP_PACKET_SIZE_BYTES_ALAW(nsamps) (APP_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES_ALAW(nsamps)) +#define RAW_PACKET_SIZE_BYTES_ALAW(nsamps) (APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES + PAYLOAD_SIZE_BYTES_ALAW(nsamps)) + // Packet sizes for IF4p5 interface format #define DATA_BLOCK_SIZE_BYTES(scaled_nblocks) (sizeof(uint16_t)*scaled_nblocks) #define PRACH_HARD_CODED_NUM_SAMPLES (839*2) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf index 1afa860c16..ca17b85c0b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf @@ -254,6 +254,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; }, //second config for Ercom { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.conf index e52a36542f..f16fc611be 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.conf @@ -166,7 +166,8 @@ eNBs = rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; - tx_scheduling_advance = 9; + tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.usrpb210.conf index cdaf13e01a..446b3ceea3 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.100PRB.usrpb210.conf @@ -168,6 +168,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.lo.conf new file mode 100644 index 0000000000..0ebb1d13fc --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.lo.conf @@ -0,0 +1,192 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.3"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.1"; + local_address = "127.0.0.2"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.usrpb210.conf index f9ebec3ab5..c4b457be34 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.25PRB.usrpb210.conf @@ -167,6 +167,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf new file mode 100644 index 0000000000..fc51979ffa --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -0,0 +1,192 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.3"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.1"; + local_address = "127.0.0.2"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.usrpb210.conf index 4ad5767ce9..ef13b69135 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.usrpb210.conf @@ -167,7 +167,8 @@ eNBs = rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; - tx_scheduling_advance = 9; + tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.100PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.100PRB.usrpb210.conf index ee2b1cb021..4b785da4e5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.100PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.100PRB.usrpb210.conf @@ -170,7 +170,8 @@ eNBs = rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; - tx_scheduling_advance = 9; + tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.25PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.25PRB.usrpb210.conf index 7541fa1ee1..c261d4a2fc 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.25PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.25PRB.usrpb210.conf @@ -167,6 +167,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.50PRB.usrpb210.conf index 1044726c26..bca8e4e3ad 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.50PRB.usrpb210.conf @@ -171,6 +171,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf index 868e499de6..4f0fdd1e3b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf @@ -167,7 +167,8 @@ eNBs = rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; - tx_scheduling_advance = 9; + tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.usrpb210.conf index 9692f6bae0..2c5ae24c8c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.usrpb210.conf @@ -166,7 +166,8 @@ eNBs = rf_preference = "usrp_b200"; iq_txshift = 4; tx_sample_advance = 80; - tx_scheduling_advance = 9; + tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf index aa731c8d8a..97351b9a6e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.100PRB.usrpb210.conf @@ -169,6 +169,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.oaisim.conf new file mode 100644 index 0000000000..bcb5c5f238 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.oaisim.conf @@ -0,0 +1,194 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RRU_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 120; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -95; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.2"; + local_address = "127.0.0.1"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.usrpb210.conf index c97b215c77..3ed4bb5884 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.25PRB.usrpb210.conf @@ -169,6 +169,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.oaisim.conf new file mode 100644 index 0000000000..c728ad6b0c --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.oaisim.conf @@ -0,0 +1,194 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "93"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RRU_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 120; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -95; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "lo"; + remote_address = "127.0.0.2"; + local_address = "127.0.0.1"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210-conga.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210-conga.conf index 7f490f0ad3..58bf27945d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210-conga.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210-conga.conf @@ -168,6 +168,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf index d40b901785..f1179ebd2f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.50PRB.usrpb210.conf @@ -169,6 +169,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.usrpb210.conf index 77b6034920..c523188338 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if4p5.usrpb210.conf @@ -167,6 +167,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.100PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.100PRB.usrpb210.conf index f6bbe9ff58..da88c88e0b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.100PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.100PRB.usrpb210.conf @@ -166,6 +166,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.25PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.25PRB.usrpb210.conf index 71e435e2f4..e7207edd49 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.25PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.25PRB.usrpb210.conf @@ -169,6 +169,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.50PRB.usrpb210.conf index 6c309df4db..1ab0b8d486 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.50PRB.usrpb210.conf @@ -166,6 +166,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf index 805bb1aba8..7c0a846654 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf @@ -168,6 +168,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.usrpb210.conf index dac1608948..61885a5e06 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.usrpb210.conf @@ -167,6 +167,7 @@ eNBs = iq_txshift = 4; tx_sample_advance = 80; tx_scheduling_advance = 9; + if_compression = "alaw"; } ); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 0605dff2ab..14b6a1cb9a 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -161,6 +161,29 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst void stop_eNB(int nb_inst); +static int recv_if_count = 0; +struct timespec start_rf_new, start_rf_prev, start_rf_prev2, end_rf; +openair0_timestamp start_rf_new_ts, start_rf_prev_ts, start_rf_prev2_ts, end_rf_ts; +extern struct timespec start_fh, start_fh_prev; +extern int start_fh_sf, start_fh_prev_sf; +struct timespec end_fh; +int end_fh_sf; +int clock_difftime_ns(struct timespec start, struct timespec end) +{ + struct timespec temp; + int temp_ns; + + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + temp_ns = (temp.tv_sec) * 1000000000 + (temp.tv_nsec); + return temp_ns; +} + static inline void thread_top_init(char *thread_name, int affinity, uint64_t runtime, @@ -401,6 +424,7 @@ void do_OFDM_mod_rt(int subframe,PHY_VARS_eNB *phy_vars_eNB) } } } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 ); } @@ -747,13 +771,18 @@ void fh_if5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { openair0_timestamp timestamp_tx; recv_IF5(eNB, ×tamp_tx, *subframe, IF5_RRH_GW_DL); - //printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); + clock_gettime( CLOCK_MONOTONIC, &end_fh); + end_fh_sf = *subframe; + recv_if_count = recv_if_count + 1; + LOG_D(HW,"[From SF %d to SF %d] RTT_FH: %d\n", start_fh_prev_sf, end_fh_sf, clock_difftime_ns(start_fh_prev, end_fh)); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); subframe_tx = (timestamp_tx/fp->samples_per_tti)%10; frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB, frame_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB, subframe_tx ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB, subframe_tx ); if (proc->first_tx != 0) { *subframe = subframe_tx; @@ -828,7 +857,7 @@ void fh_if4p5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { exit_fun("Exiting"); } } while (proc->symbol_mask[*subframe] != symbol_mask_full); - + *frame = frame_tx; @@ -912,6 +941,7 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { // Transmit TX buffer based on timestamp from RX // printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers lte_subframe_t SF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10); @@ -949,7 +979,13 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { siglen, fp->nb_antennas_tx, flags); - + clock_gettime( CLOCK_MONOTONIC, &end_rf); + end_rf_ts = proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance; + if (recv_if_count != 0 ) { + recv_if_count = recv_if_count-1; + LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %d; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); + LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %d; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); @@ -973,6 +1009,13 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { rxp, fp->samples_per_tti, fp->nb_antennas_rx); + start_rf_prev2= start_rf_prev; + start_rf_prev2_ts= start_rf_prev_ts; + start_rf_prev = start_rf_new; + start_rf_prev_ts = start_rf_new_ts; + clock_gettime( CLOCK_MONOTONIC, &start_rf_new); + start_rf_new_ts = ts; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); proc->timestamp_rx = ts-eNB->ts_offset; From 76574a1ac0166a98b923cd01b02b0928965153dd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 12:29:31 +0100 Subject: [PATCH 307/571] Revert "fix nettle" This reverts commit d31634c358f35548f14daf1645268a741d21b371. Laurent Thomas had a problem on one machine with the build_oai way of checking for nettle. The problem with the alternative solution of including nettle/bignum.h is that it is very unclear. The problem with nettle is that the file nettle/config.h does not exist for version 2. It was introduced in version 3. We want to support both versions, but there is an API incompatibility. So we need an #if #else mechanism. The file nettle/bignum.h is present in both versions 2 and 3 and it includes nettle/version.h in the version 3. So by including this file, we can check for the existence of NETTLE_VERSION_MAJOR (that comes from nettle/config.h) in the code. But as you can see, the reasoning is way too complex. So it's better to keep the check in cmake_targets/CMakeLists.txt. As long as we support version 2 this will be the way to go. It is possible to force a given version in specific non-generic customized environments. --- cmake_targets/CMakeLists.txt | 12 ++++++++++++ openair2/UTIL/OSA/osa_stream_eea.c | 3 +-- openair3/SECU/nas_stream_eea2.c | 3 +-- openair3/TEST/test_aes128_ctr_decrypt.c | 3 +-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 81ea1980dc..e4d3acf4b1 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1664,6 +1664,18 @@ endif() message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") +string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) +string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) +message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") +message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") + +if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") + message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) +endif() + +add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") +add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") + pkg_search_module(XPM xpm) if(NOT ${XPM_FOUND}) message("PACKAGE xpm not found: some targets will fail") diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c index 9e8a3a88b3..6aef6d2588 100644 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ b/openair2/UTIL/OSA/osa_stream_eea.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "UTIL/LOG/log.h" @@ -192,7 +191,7 @@ int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) } #endif -#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 +#if NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index e9f2e7c41a..37f2e298fb 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "assertions.h" #include "conversions.h" @@ -79,7 +78,7 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) } #endif -#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 +#if NETTLE_VERSION_MAJOR < 3 nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, stream_cipher->key); #else diff --git a/openair3/TEST/test_aes128_ctr_decrypt.c b/openair3/TEST/test_aes128_ctr_decrypt.c index 98987a8d97..a30dc6c2f2 100644 --- a/openair3/TEST/test_aes128_ctr_decrypt.c +++ b/openair3/TEST/test_aes128_ctr_decrypt.c @@ -31,7 +31,6 @@ #include #include #include -#include static void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, @@ -42,7 +41,7 @@ void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, uint8_t *data = malloc(length); uint8_t *ctr = malloc(cipher->block_size); -#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 +#if NETTLE_VERSION_MAJOR < 3 cipher->set_encrypt_key(ctx, key_length, key); #else cipher->set_encrypt_key(ctx, key); From f58c7b1be94752e9170726906db9724c2122cbb3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 12:41:13 +0100 Subject: [PATCH 308/571] integration fix: restore enb.band7.tm1.usrpb210.conf Many variables were changed that should not have been changed. --- .../CONF/enb.band7.tm1.usrpb210.conf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index 3b673b8eae..5ef5a4f50b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -31,16 +31,16 @@ eNBs = tdd_config_s = 0; prefix_type = "NORMAL"; eutra_band = 7; - downlink_frequency = 2630000000L; + downlink_frequency = 2660000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; - N_RB_DL = 50; + N_RB_DL = 25; Nid_cell_mbsfn = 0; nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 110; + rx_gain = 125; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -68,9 +68,9 @@ eNBs = srs_ackNackST =; srs_MaxUpPts =;*/ - pusch_p0_Nominal = -100; + pusch_p0_Nominal = -90; pusch_alpha = "AL1"; - pucch_p0_Nominal = -106; + pucch_p0_Nominal = -96; msg3_delta_Preamble = 6; pucch_deltaF_Format1 = "deltaF2"; pucch_deltaF_Format1b = "deltaF3"; @@ -148,9 +148,9 @@ eNBs = { ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.212/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.147/24"; ENB_INTERFACE_NAME_FOR_S1U = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.212/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.147/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; From e3186c17414c1a22fc41ec43731476522c1032e2 Mon Sep 17 00:00:00 2001 From: Anta Huang Date: Fri, 17 Feb 2017 13:56:00 +0100 Subject: [PATCH 309/571] Issue #211 - enhance build script for snapping package - build script has ability to indicate location for downloading uhd images - one simple wrapper to set environment variables and initiate another program (supposed to be lte-softmodem) --- cmake_targets/build_oai | 10 +++++++++- cmake_targets/snap_environment.sh | 3 +++ cmake_targets/tools/build_helper | 6 +++++- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100755 cmake_targets/snap_environment.sh diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 2272a338be..6d22fe9ba4 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -292,6 +292,10 @@ function main() { UE_AUTOTEST_TRACE="True" echo_info "Enabling autotest specific trace for UE" shift 1;; + --uhd-images-dir) + UHD_IMAGES_DIR=$2 + echo_info "Downloading UHD images in the indicated location" + shift 2;; -h | --help) print_help exit 1;; @@ -362,6 +366,10 @@ function main() { echo_info "Flags for Deadline scheduler: $DEADLINE_SCHEDULER_FLAG_USER" echo_info "Flags for CPU Affinity: $CPU_AFFINITY_FLAG_USER" + if [ -n "$UHD_IMAGES_DIR" ] && [ -z "$INSTALL_EXTERNAL" ]; then + echo_error "UHD images download settings will not be applied without -I present" + exit + fi ############################################ # setting and printing OAI envs, we should check here ############################################ @@ -399,7 +407,7 @@ function main() { echo_info "installing packages for USRP support" check_install_usrp_uhd_driver if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then - install_usrp_uhd_driver + install_usrp_uhd_driver $UHD_IMAGES_DIR fi fi if [ "$HW" == "OAI_BLADERF" ] ; then diff --git a/cmake_targets/snap_environment.sh b/cmake_targets/snap_environment.sh new file mode 100755 index 0000000000..1c0725d8b5 --- /dev/null +++ b/cmake_targets/snap_environment.sh @@ -0,0 +1,3 @@ +#!/bin/sh +export UHD_IMAGES_DIR=$SNAP/uhd_images +exec $@ diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index f73078afc5..c52c175c05 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -216,7 +216,11 @@ install_usrp_uhd_driver() { # We move uhd-host apart because it depends on linux kernel version # On newer kernels, it fails to install $SUDO apt-get -y install uhd-host - $SUDO uhd_images_downloader + if [ -z $1 ]; then + $SUDO uhd_images_downloader + else + $SUDO uhd_images_downloader -i $1 + fi } check_install_bladerf_driver(){ From 122953d9868ca88d4191f80a36ff4e14ed3fca79 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 14:25:26 +0100 Subject: [PATCH 310/571] redo commit 157707b0422201ef1cd9b505578c9a11d6e19604 git show 157707b0422201ef1cd9b505578c9a11d6e19604 to see what it's about --- targets/RT/USER/lte-ue.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index e6eea65375..79903a74e7 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -189,12 +189,14 @@ void init_UE(int nb_inst) { } printf("UE threads created by %ld\n", gettid()); -#ifdef USE_MME +#if 0 +#if defined(ENABLE_USE_MME) + extern volatile int start_UE; while (start_UE == 0) { sleep(1); } #endif - +#endif } /*! From 7c11cf96465bcbd1a7674e2fa080c8c03ecfd35b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 14:39:00 +0100 Subject: [PATCH 311/571] redo commit 58052152273b537207fccf85c86bfa3152fbd4f9 git show -p 58052152273b537207fccf85c86bfa3152fbd4f9 to see what it's about --- targets/RT/USER/lte-ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 79903a74e7..06ddcba0a7 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -329,9 +329,9 @@ static void *UE_thread_synch(void *arg) { for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; if (freq_offset >= 0) - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += UE->common_vars.freq_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); else - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; From ac7c0df5208053e923f157c61530aac226228ad9 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 17:55:27 +0100 Subject: [PATCH 312/571] integration fix: let oaisim (S1) work again - some cleanup - thread names to include UE Mod_id - arg of UE_thread_rxn_txnp4 to be struct rx_tx_thread_data again - sync in UE_thread_rxn_txnp4 to use instance_cnt_rxtx again - UE_thread to call itti_send_msg_to_task with UE->Mod_id + NB_eNB_INST instead of INSTANCE_DEFAULT again This may break the softmodem UE, to be tested. The most problematic thing may be the synchronization. I don't think it will impact the processing at all, but I won't bet my shirt on it. --- targets/RT/USER/lte-softmodem.h | 6 +- targets/RT/USER/lte-ue.c | 115 +++++++++++++++++++++----------- targets/SIMU/USER/oaisim.c | 4 +- 3 files changed, 81 insertions(+), 44 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index e499bd12be..b438d9eee2 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -67,11 +67,7 @@ extern volatile int start_eNB; extern volatile int start_UE; #endif -typedef struct threads_s { - int iq; - int odd; - int even; -} threads_t; +#include "threads_t.h" extern threads_t threads; extern void exit_fun(const char* s); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 06ddcba0a7..d1ed039beb 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -124,10 +124,6 @@ static const eutra_band_t eutra_bands[] = { {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, }; -pthread_t main_ue_thread; -pthread_attr_t attr_UE_thread; -struct sched_param sched_param_UE_thread; - void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { #ifdef DEADLINE_SCHEDULER @@ -177,24 +173,25 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_ printf("started %s as PID: %ld\n",name, gettid()); } -void init_UE(int nb_inst) { +void init_UE(int nb_inst) +{ + int inst; + for (inst=0; inst < nb_inst; inst++) { + // UE->rfdevice.type = NONE_DEV; + PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0]; + AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, + &UE->proc.attr_ue, + UE_thread, + (void*)UE), ""); + } - for (long long inst=0; instrfdevice.type = NONE_DEV; - PHY_VARS_UE *UE = PHY_vars_UE_g[inst][0]; - AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, - &UE->proc.attr_ue, - UE_thread, - (void*)UE), ""); - } - - printf("UE threads created by %ld\n", gettid()); + printf("UE threads created by %ld\n", gettid()); #if 0 #if defined(ENABLE_USE_MME) - extern volatile int start_UE; - while (start_UE == 0) { - sleep(1); - } + extern volatile int start_UE; + while (start_UE == 0) { + sleep(1); + } #endif #endif } @@ -214,14 +211,15 @@ static void *UE_thread_synch(void *arg) { sync_mode_t sync_mode = pbch; int CC_id = UE->CC_id; int freq_offset=0; + char threadname[128]; cpu_set_t cpuset; CPU_ZERO(&cpuset); if ( threads.iq != -1 ) CPU_SET(threads.iq, &cpuset); // this thread priority must be lower that the main acquisition thread - init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, - "sync UE"); + sprintf(threadname, "sync UE %d\n", UE->Mod_id); + init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname); UE->is_synchronized = 0; @@ -460,6 +458,13 @@ static void *UE_thread_synch(void *arg) { } +/* this structure is used to pass both UE phy vars and + * proc to the function UE_thread_rxn_txnp4 + */ +struct rx_tx_thread_data { + PHY_VARS_UE *UE; + UE_rxtx_proc_t *proc; +}; /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. @@ -471,15 +476,16 @@ static void *UE_thread_synch(void *arg) { static void *UE_thread_rxn_txnp4(void *arg) { static __thread int UE_thread_rxtx_retval; - UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + PHY_VARS_UE *UE = rtd->UE; int ret; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id]; - static long long __thread instance_cnt_rxtx=-1; + proc->instance_cnt_rxtx=-1; proc->subframe_rx=proc->sub_frame_start; - char threadname[256]= {0}; - sprintf(threadname,"UE_proc_%d",proc->sub_frame_start); + char threadname[256]; + sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); cpu_set_t cpuset; CPU_ZERO(&cpuset); if ( (proc->sub_frame_start+1)%2 == 0 && threads.even != -1 ) @@ -490,14 +496,18 @@ static void *UE_thread_rxn_txnp4(void *arg) { threadname); while (!oai_exit) { - // Wait Rx data to process are available - AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); - pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - if ( (instance_cnt_rxtx+proc->sub_frame_step)%10 != proc->subframe_rx && instance_cnt_rxtx!=-1 ) - LOG_W(PHY,"REAL TIME NOT MATCHED: missed a sub-frame: expecting %lld, got %d\n", - (instance_cnt_rxtx+proc->sub_frame_step)%10, proc->subframe_rx); - instance_cnt_rxtx=proc->subframe_rx; - AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); + } + while (proc->instance_cnt_rxtx < 0) { + // most of the time, the thread is waiting here + pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + } + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } initRefTimes(t2); initRefTimes(t3); @@ -571,9 +581,19 @@ static void *UE_thread_rxn_txnp4(void *arg) { phy_procedures_UE_S_TX(UE,0,0,no_relay); updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); + if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } + proc->instance_cnt_rxtx--; + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); + exit_fun("noting to add"); + } } // thread finished + free(arg); return &UE_thread_rxtx_retval; } @@ -596,6 +616,7 @@ void *UE_thread(void *arg) { void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; int start_rx_stream = 0; int i; + char threadname[128]; cpu_set_t cpuset; CPU_ZERO(&cpuset); @@ -606,13 +627,14 @@ void *UE_thread(void *arg) { if (oaisim_flag == 0) AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); UE->rfdevice.host_type = BBU_HOST; - pthread_setname_np( pthread_self(), "Main UE" ); + sprintf(threadname, "Main UE %d", UE->Mod_id); + pthread_setname_np(pthread_self(), threadname); init_UE_threads(UE); #ifdef NAS_UE MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, INSTANCE_DEFAULT, message_p); + itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif int sub_frame=-1; @@ -638,13 +660,13 @@ void *UE_thread(void *arg) { UE->frame_parms.nb_antennas_rx), ""); AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); instance_cnt_synch = ++UE->proc.instance_cnt_synch; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); if (instance_cnt_synch == 0) { AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); } else { LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); exit_fun("nothing to add"); } + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); } else { // grab 10 ms of signal into dummy buffer if (UE->mode != loop_through_memory) { @@ -770,6 +792,18 @@ void *UE_thread(void *arg) { (4*UE->frame_parms.samples_per_tti)- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; + proc->instance_cnt_rxtx++; + if (proc->instance_cnt_rxtx == 0) { + if (pthread_cond_signal(&proc->cond_rxtx) != 0) { + LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); + exit_fun("nothing to add"); + } + } else { + LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx); + if (proc->instance_cnt_rxtx > 2) + exit_fun("instance_cnt_rxtx > 2"); + } + AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); initRefTimes(t1); @@ -797,6 +831,7 @@ void *UE_thread(void *arg) { * and the locking between them. */ void init_UE_threads(PHY_VARS_UE *UE) { + struct rx_tx_thread_data *rtd; pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); @@ -807,11 +842,15 @@ void init_UE_threads(PHY_VARS_UE *UE) { // the threads are not yet active, therefore access is allowed without locking int nb_threads=2; for (int i=0; iUE = UE; + rtd->proc = &UE->proc.proc_rxtx[i]; pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; - pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[i]); + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); } pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 02ccefed26..7f4a992023 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -181,7 +181,9 @@ extern uint16_t Nid_cell; extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; - +double cpuf; +#include "threads_t.h" +threads_t threads= {-1,-1,-1}; //#ifdef XFORMS int otg_enabled; From 053704b5c214c73f970bd2978c254bd1d352556d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 18:01:02 +0100 Subject: [PATCH 313/571] remove wrong comment --- targets/SIMU/USER/oaisim.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 7f4a992023..7c1ea1a3c8 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1291,8 +1291,6 @@ main (int argc, char **argv) init_ocm (); #if defined(ENABLE_ITTI) - // Handle signals until all tasks are terminated - // Note: Cannot handle both RRU/RAU and eNB at the same time, if the first "eNB" is an RRU/RAU, no NAS if (oai_emulation.info.node_function[0] < NGFI_RAU_IF4p5) { if (create_tasks(oai_emulation.info.nb_enb_local, From baeb93039778615079e2f4f96996fe13e1ce032c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 18:01:17 +0100 Subject: [PATCH 314/571] use ln -sf instead of ln -s in cmake_targets/build_oai When rebuilding oaisim, I had a failure because the target link already exists. The -f flag forces the link to be done. --- cmake_targets/build_oai | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 6a61d36cfa..aab109dbf0 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -694,8 +694,8 @@ function main() { compilations \ $oaisim_build_dir oai_eth_transpro \ liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL - ln -s liboai_eth_transpro.so liboai_transpro.so - ln -s $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so + ln -sf liboai_eth_transpro.so liboai_transpro.so + ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so echo_info "liboai_transpro.so is linked with ETHERNET library" fi @@ -782,8 +782,8 @@ function main() { liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL fi - ln -s liboai_usrpdevif.so liboai_device.so - ln -s $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so + ln -sf liboai_usrpdevif.so liboai_device.so + ln -sf $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to USRP device library" elif [ "$HW" == "OAI_BLADERF" ] ; then if [ -f "/usr/include/libbladeRF.h" ] ; then @@ -792,8 +792,8 @@ function main() { liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL fi - ln -s liboai_bladerfdevif.so liboai_device.so - ln -s $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so + ln -sf liboai_bladerfdevif.so liboai_device.so + ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to BLADERF device library" elif [ "$HW" == "OAI_LMSSDR" ] ; then # if [ -f "/usr/include/libbladeRF.h" ] ; then @@ -802,8 +802,8 @@ function main() { liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL # fi - ln -s liboai_lmssdrdevif.so liboai_device.so - ln -s $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so + ln -sf liboai_lmssdrdevif.so liboai_device.so + ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to LMSSDR device library" else echo_info "liboai_device.so is not linked to any device library" @@ -819,8 +819,8 @@ function main() { compilations \ $build_dir oai_eth_transpro \ liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL - ln -s liboai_eth_transpro.so liboai_transpro.so - ln -s $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so + ln -sf liboai_eth_transpro.so liboai_transpro.so + ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so echo_info "liboai_transpro.so is linked with ETHERNET library" fi fi From 74afbf84f4b3f6ee7dab6d5ad3fb036b8161972e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 11:49:35 +0100 Subject: [PATCH 315/571] warning fix: remove pragma in LFDS Not sure that it's correct, but those #pragma seem to be of no use for gcc. Let's remove them completely. --- .../src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c | 2 -- .../lfds700_list_addonly_singlylinked_unordered_insert.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c index af88b19179..e57fab74c4 100644 --- a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c +++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c @@ -36,7 +36,6 @@ void lfds700_hash_a_cleanup( struct lfds700_hash_a_state *has, /****************************************************************************/ -#pragma warning( disable : 4100 ) static void btree_au_element_cleanup_function( struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element *baue ) { @@ -57,5 +56,4 @@ static void btree_au_element_cleanup_function( struct lfds700_btree_au_state *ba return; } -#pragma warning( default : 4100 ) diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.c index ce2ee825aa..86472b004e 100644 --- a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.c +++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.c @@ -154,7 +154,6 @@ void lfds700_list_asu_insert_at_end( struct lfds700_list_asu_state *lasus, /****************************************************************************/ -#pragma warning( disable : 4100 ) void lfds700_list_asu_insert_after_element( struct lfds700_list_asu_state *lasus, struct lfds700_list_asu_element *lasue, @@ -189,5 +188,4 @@ void lfds700_list_asu_insert_after_element( struct lfds700_list_asu_state *lasus return; } -#pragma warning( default : 4100 ) From 37bc075cb20084a598d09431c3877ce2eee37b4b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 12:13:11 +0100 Subject: [PATCH 316/571] fix: exit if memory_read fails in the function nas_user_initialize --- openair3/NAS/UE/nas_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 3108858d06..0ff9a8741b 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -165,6 +165,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, int rc = memory_read(user->user_nvdata_store, user->nas_user_nvdata, sizeof(user_nvdata_t)); if (rc != RETURNok) { LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", user->nas_user_nvdata); + abort(); } user->nas_user_context = calloc_or_fail(sizeof(nas_user_context_t)); From 96dc12ccce6d3cd2c40c6cb8df3883e3e46896a4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 12:14:15 +0100 Subject: [PATCH 317/571] fix warning: add missing */ --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 07827524af..a15e6bbdae 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1588,6 +1588,7 @@ schedule_ue_spec( } break; + */ /* // disabled for now as this needs to be done properly case 5: From 603c84c700d6eaa5fe0af8b0ac41d2906f7c85e0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 12:14:47 +0100 Subject: [PATCH 318/571] fix warnings: fix LOG_X problems when compiling lte-softmodem The compilation line was: ./build_oai --eNB -w USRP The file openairinterface5g/cmake_targets/log/lte-softmodem.Rel10.txt has been checked and all LOG_X (and 'msg') warnings have been fixed. --- openair1/PHY/INIT/lte_init.c | 2 +- openair1/PHY/LTE_ESTIMATION/lte_sync_time.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/if4_tools.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/phich.c | 2 +- openair1/SCHED/phy_procedures_lte_ue.c | 3 ++- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 2 +- openair2/RRC/LITE/rrc_UE.c | 4 ++-- openair3/NAS/UE/nas_ue_task.c | 4 ++-- openair3/NAS/UE/nas_user.c | 2 +- targets/RT/USER/lte-enb.c | 16 ++++++++-------- targets/SIMU/USER/init_lte.c | 2 +- 11 files changed, 23 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index dd939a9869..d0556a0235 100755 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -1411,7 +1411,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff/fp->nb_antennas_tx; } #ifdef DEBUG_PHY - msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%d bytes)\n", + msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%zu bytes)\n", eNB_id,i,j,common_vars->beam_weights[eNB_id][i][j], fp->ofdm_symbol_size*sizeof(int32_t)); #endif diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index e6551033f3..6ce10723c6 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -581,10 +581,10 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain *peak_val_out = peak_val; if (peak_val <= (40*(uint32_t)mean_val)) { - LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%u,%u)\n",peak_pos,peak_val,mean_val,40*mean_val); + LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%"PRIu64",%"PRIu64")\n",peak_pos,peak_val,mean_val,40*mean_val); return(-1); } else { - LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %u\n",peak_pos,peak_val,mean_val); + LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %"PRIu64"\n",peak_pos,peak_val,mean_val); return(peak_pos); } diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index be1bc6b08e..4f821bc54d 100755 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -292,8 +292,8 @@ void recv_IF4p5(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_t } } else if (*packet_type == IF4p5_PRACH) { - LOG_D(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe); - if (eNB->CC_id==1) LOG_I(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d, symbol %d\n",eNB->CC_id,*frame,*subframe); + LOG_D(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d\n",eNB->CC_id,*frame,*subframe); + if (eNB->CC_id==1) LOG_I(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d\n",eNB->CC_id,*frame,*subframe); // FIX: hard coded prach samples length db_fulllength = PRACH_HARD_CODED_NUM_SAMPLES; diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index aa99f5cca1..ed3ef923e3 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1389,7 +1389,7 @@ void rx_phich(PHY_VARS_UE *ue, } } else { //#ifdef DEBUG_PHICH - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d (Mlimit %d)\n", + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n", ue->Mod_id,harq_pid, proc->frame_rx%1024, subframe, diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index b9662fd5d5..9bf0779fe2 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1910,7 +1910,8 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // if nothing to report ==> exit function if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0)) { - LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d Return \n", frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); + LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n", + frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); return; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index da9e8572ba..9a6fc29a58 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -769,7 +769,7 @@ int get_bw_index(module_id_t module_id, uint8_t CC_id) default: bw_index=1; - LOG_W(MAC,"[eNB %d] N_DL_RB %d unknown for CC_id %d, setting bw_index to 1\n", module_id, CC_id); + LOG_W(MAC,"[eNB %d] N_DL_RB %d unknown for CC_id %d, setting bw_index to 1\n", module_id, frame_parms->N_RB_DL, CC_id); break; } diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 4c877ebe23..d89c4501cf 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -1103,8 +1103,8 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection = radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection; - LOG_I(PHY,"New Transmission Mode %d \n",radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); - LOG_I(PHY,"Configured Transmission Mode %d \n",UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode); + LOG_I(PHY,"New Transmission Mode %ld \n",radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); + LOG_I(PHY,"Configured Transmission Mode %ld \n",UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode); } else diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index 2a42b38a72..da9ae8879d 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -72,7 +72,7 @@ void nas_user_api_id_initialize(nas_user_t *user) { user->user_api_id = user_api_id; char *port = make_port_str_from_ueid(NAS_PARSER_DEFAULT_USER_PORT_NUMBER, user->ueid); if ( port == NULL ) { - LOG_E(NAS, "[UE %d] can't get port from ueid %d !", user->ueid); + LOG_E(NAS, "[UE %d] can't get port from ueid!", user->ueid); exit (EXIT_FAILURE); } if (user_api_initialize (user_api_id, NAS_PARSER_DEFAULT_USER_HOSTNAME, port, NULL, @@ -106,7 +106,7 @@ void *nas_ue_task(void *args_p) /* Get USIM data application filename */ user->usim_data_store = memory_get_path_from_ueid(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME, user->ueid); if ( user->usim_data_store == NULL ) { - LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid, user->ueid); + LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); exit(EXIT_FAILURE); } diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index 0ff9a8741b..b698e4d682 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -164,7 +164,7 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, /* Get UE data stored in the non-volatile memory device */ int rc = memory_read(user->user_nvdata_store, user->nas_user_nvdata, sizeof(user_nvdata_t)); if (rc != RETURNok) { - LOG_TRACE(ERROR, "USR-MAIN - Failed to read %s", user->nas_user_nvdata); + LOG_TRACE(ERROR, "USR-MAIN - Failed to read non volatile memory"); abort(); } diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 3c971314c6..6e3fb92144 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -675,17 +675,17 @@ void fh_if5_asynch_UL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { proc->first_rx =2; *subframe = proc->subframe_rx; *frame = proc->frame_rx; - LOG_E(PHY,"[Mobipass]timestamp_rx:%llu, frame_rx %d, subframe: %d\n",proc->timestamp_rx,proc->frame_rx,proc->subframe_rx); + LOG_E(PHY,"[Mobipass]timestamp_rx:%"PRId64", frame_rx %d, subframe: %d\n",proc->timestamp_rx,proc->frame_rx,proc->subframe_rx); } else { if (proc->subframe_rx != *subframe) { proc->first_rx++; - LOG_E(PHY,"[Mobipass]timestamp:%llu, subframe_rx %d is not what we expect %d, first_rx:%d\n",proc->timestamp_rx, proc->subframe_rx,*subframe, proc->first_rx); + LOG_E(PHY,"[Mobipass]timestamp:%"PRId64", subframe_rx %d is not what we expect %d, first_rx:%d\n",proc->timestamp_rx, proc->subframe_rx,*subframe, proc->first_rx); //exit_fun("Exiting"); } if (proc->frame_rx != *frame) { proc->first_rx++; - LOG_E(PHY,"[Mobipass]timestamp:%llu, frame_rx %d is not what we expect %d, first_rx:%d\n",proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx); + LOG_E(PHY,"[Mobipass]timestamp:%"PRId64", frame_rx %d is not what we expect %d, first_rx:%d\n",proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx); // exit_fun("Exiting"); } // temporary solution @@ -990,7 +990,7 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { else { if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { - LOG_I(PHY,"rx_rf: rfdevice timing drift of %d samples\n",proc->timestamp_rx - old_ts - fp->samples_per_tti); + LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples\n",proc->timestamp_rx - old_ts - fp->samples_per_tti); eNB->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); proc->timestamp_rx = ts-eNB->ts_offset; } @@ -1007,12 +1007,12 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { if (proc->first_rx == 0) { if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"rx_rf: Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe); + LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe); exit_fun("Exiting"); } int f2 = (*frame+proc->frame_offset)&1023; if (proc->frame_rx != f2) { - LOG_E(PHY,"rx_rf: Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame,proc->frame_offset,f2); + LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame,proc->frame_offset,f2); exit_fun("Exiting"); } } else { @@ -1631,8 +1631,8 @@ static void* eNB_thread_single( void* param ) { } if (eNB->CC_id==1) - LOG_D(PHY,"eNB thread single %p (proc %p, CC_id %d), frame %d (%p), subframe %d (%p)\n", - pthread_self(), proc, eNB->CC_id, frame,&frame,subframe,&subframe); + LOG_D(PHY,"eNB thread single (proc %p, CC_id %d), frame %d (%p), subframe %d (%p)\n", + proc, eNB->CC_id, frame,&frame,subframe,&subframe); // synchronization on FH interface, acquire signals/data and block if (eNB->rx_fh) eNB->rx_fh(eNB,&frame,&subframe); diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c index 62273185b2..8ff274be14 100644 --- a/targets/SIMU/USER/init_lte.c +++ b/targets/SIMU/USER/init_lte.c @@ -81,7 +81,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms, } } - LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n"); + LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n", i); PHY_vars_eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,frame_parms->N_RB_UL, abstraction_flag); if (!PHY_vars_eNB->ulsch[1+i]) { From f9b5dafe2997082e2d65d87dc6506e789742859f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 18:16:22 +0100 Subject: [PATCH 319/571] T: let it compile with C++ We now have 4 versions of T_HEADER: - bad quality C++ version with time - good quality C version with time - bad quality C++ version without time - good quality C version without time --- common/utils/T/T.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/common/utils/T/T.h b/common/utils/T/T.h index 819615131e..37668a8309 100644 --- a/common/utils/T/T.h +++ b/common/utils/T/T.h @@ -184,8 +184,30 @@ extern T_cache_t *T_cache; } while (0) #endif +/* we have 4 versions of T_HEADER: + * - bad quality C++ version with time + * - good quality C version with time + * - bad quality C++ version without time + * - good quality C version without time + */ + #ifdef T_SEND_TIME +#ifdef __cplusplus + +/* C++ version of T_HEADER with time */ +#define T_HEADER(x) \ + do { \ + struct timespec T_HEADER_time; \ + if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \ + memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \ + T_LOCAL_size += sizeof(struct timespec); \ + T_PUT_int(1, (int)(uintptr_t)(x)); \ + } while (0) + +#else /* #ifdef __cplusplus */ + +/* C version of T_HEADER with time */ #define T_HEADER(x) \ do { \ if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ @@ -201,8 +223,21 @@ extern T_cache_t *T_cache; T_PUT_int(1, (int)(uintptr_t)(x)); \ } while (0) +#endif /* #ifdef __cplusplus */ + #else /* #ifdef T_SEND_TIME */ +#ifdef __cplusplus + +/* C++ version of T_HEADER without time */ +#define T_HEADER(x) \ + do { \ + T_PUT_int(1, (int)(uintptr_t)(x)); \ + } while (0) + +#else /* #ifdef __cplusplus */ + +/* C version of T_HEADER without time */ #define T_HEADER(x) \ do { \ if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \ @@ -214,6 +249,8 @@ extern T_cache_t *T_cache; T_PUT_int(1, (int)(uintptr_t)(x)); \ } while (0) +#endif /* #ifdef __cplusplus */ + #endif /* #ifdef T_SEND_TIME */ #define T1(t) \ From b82e7c1a88a0de520764814e39f34d8bd11de381 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Feb 2017 20:19:24 +0100 Subject: [PATCH 320/571] hotfix: forgot targets/COMMON/threads_t.h in a previous commit --- targets/COMMON/threads_t.h | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 targets/COMMON/threads_t.h diff --git a/targets/COMMON/threads_t.h b/targets/COMMON/threads_t.h new file mode 100644 index 0000000000..c9ba9fea1a --- /dev/null +++ b/targets/COMMON/threads_t.h @@ -0,0 +1,10 @@ +#ifndef _THREADS_T_H_ +#define _THREADS_T_H_ + +typedef struct threads_s { + int iq; + int odd; + int even; +} threads_t; + +#endif /* _THREADS_T_H_ */ From ea858d54fa024b78a4fab83656020b600c0f86cc Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Feb 2017 10:09:05 +0100 Subject: [PATCH 321/571] integration fix: strerror has to be used, not perror The command line to get the error was: ./build_oai --eNB -w EXMIMO -c --- targets/RT/USER/lte-ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index d1ed039beb..64f8f42d0f 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -135,7 +135,7 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_ attr.sched_deadline = sched_deadline; attr.sched_period = 0; AssertFatal(sched_setattr(0, &attr, 0) == 0, - "[SCHED] %s thread: sched_setattr failed %s \n", name, perror(errno)); + "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", name, (unsigned long)gettid(), sched_getcpu()); } From c8e642494bc70701fe46bea90fe6f82be82c38c1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Feb 2017 10:10:00 +0100 Subject: [PATCH 322/571] integration fix: protect include file The command line to get the error was: ./build_oai --eNB -w EXMIMO -c --- targets/RT/USER/rt_wrapper.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/rt_wrapper.h b/targets/RT/USER/rt_wrapper.h index ca0507e003..28466524ac 100644 --- a/targets/RT/USER/rt_wrapper.h +++ b/targets/RT/USER/rt_wrapper.h @@ -30,7 +30,8 @@ * \warning This code will be removed when a legacy libc API becomes available. */ - +#ifndef _RT_WRAPPER_H_ +#define _RT_WRAPPER_H_ #define _GNU_SOURCE #include @@ -121,3 +122,4 @@ int sched_getattr(pid_t pid,struct sched_attr *attr,unsigned int size, unsigned #define gettid() syscall(__NR_gettid) // for gettid +#endif /* _RT_WRAPPER_H_ */ From 339353a96c2057ff6b0a09e0e29c70b45686b6b2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Feb 2017 10:53:35 +0100 Subject: [PATCH 323/571] integration fix: have a central place of definition for clock_difftime_ns Prior to this commit, the following command failed to build dlsim: ./build_oai --phy_simulators -c Choice has been made to define it in a .h file as a static inline function. --- common/utils/time_utils.h | 23 +++++++++++++++++++++++ openair1/PHY/LTE_TRANSPORT/if5_tools.c | 26 ++++++++++++++------------ targets/RT/USER/lte-enb.c | 23 +++++------------------ 3 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 common/utils/time_utils.h diff --git a/common/utils/time_utils.h b/common/utils/time_utils.h new file mode 100644 index 0000000000..ee82c8cf95 --- /dev/null +++ b/common/utils/time_utils.h @@ -0,0 +1,23 @@ +#ifndef _TIME_UTILS_H_ +#define _TIME_UTILS_H_ + +#include +#include + +static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end) +{ + struct timespec temp; + int64_t temp_ns; + + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + temp_ns = (int64_t)(temp.tv_sec) * (int64_t)1000000000 + (temp.tv_nsec); + return temp_ns; +} + +#endif /* _TIME_UTILS_H_ */ diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index 85e6b7429c..399ebc4da2 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -33,6 +33,8 @@ #include "PHY/defs.h" #include "PHY/TOOLS/alaw_lut.h" +#include "time_utils.h" + //#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" #include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -83,7 +85,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe } } clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] Compress_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); clock_gettime( CLOCK_MONOTONIC, &start_comp); @@ -94,7 +96,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe fp->nb_antennas_tx, 0); clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); } } else if (eth->compression == NO_COMPRESS) { @@ -112,7 +114,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe fp->nb_antennas_tx, 0); clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); for (i=0; i < fp->nb_antennas_tx; i++) txp[i] += spp_eth; @@ -140,7 +142,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe } } clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] Compress_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 ); clock_gettime( CLOCK_MONOTONIC, &start_comp); @@ -151,7 +153,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe fp->nb_antennas_rx, 0); clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); } } else if (eth->compression == NO_COMPRESS) { @@ -169,7 +171,7 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe fp->nb_antennas_rx, 0); clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %d\n",subframe,clock_difftime_ns(start_comp, end_comp)); + LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 ); for (i=0; i < fp->nb_antennas_rx; i++) rxp[i] += spp_eth; @@ -291,7 +293,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram fp->nb_antennas_tx); clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); clock_gettime( CLOCK_MONOTONIC, &start_decomp); @@ -303,7 +305,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram } } clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] Decomperss_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); } } else if (eth->compression == NO_COMPRESS) { @@ -320,7 +322,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram spp_eth, fp->nb_antennas_tx); clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); for (i=0; i < fp->nb_antennas_tx; i++) txp[i] += spp_eth; @@ -346,7 +348,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram spp_eth, fp->nb_antennas_rx); clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 1 ); clock_gettime( CLOCK_MONOTONIC, &start_decomp); @@ -358,7 +360,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram } } clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] Decomperss_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); } } else if (eth->compression == NO_COMPRESS) { @@ -375,7 +377,7 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram spp_eth, fp->nb_antennas_rx); clock_gettime( CLOCK_MONOTONIC, &end_decomp); - LOG_D(HW,"[SF %d] IF_Read_Time: %d\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); + LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF, 0 ); for (i=0; i < fp->nb_antennas_rx; i++) rxp[i] += spp_eth; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 2cf3ec6794..189bb87d49 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -45,6 +45,8 @@ #include #include "rt_wrapper.h" +#include "time_utils.h" + #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all #include "assertions.h" @@ -170,21 +172,6 @@ extern struct timespec start_fh, start_fh_prev; extern int start_fh_sf, start_fh_prev_sf; struct timespec end_fh; int end_fh_sf; -int clock_difftime_ns(struct timespec start, struct timespec end) -{ - struct timespec temp; - int temp_ns; - - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - temp_ns = (temp.tv_sec) * 1000000000 + (temp.tv_nsec); - return temp_ns; -} static inline void thread_top_init(char *thread_name, int affinity, @@ -776,7 +763,7 @@ void fh_if5_asynch_DL(PHY_VARS_eNB *eNB,int *frame,int *subframe) { clock_gettime( CLOCK_MONOTONIC, &end_fh); end_fh_sf = *subframe; recv_if_count = recv_if_count + 1; - LOG_D(HW,"[From SF %d to SF %d] RTT_FH: %d\n", start_fh_prev_sf, end_fh_sf, clock_difftime_ns(start_fh_prev, end_fh)); + LOG_D(HW,"[From SF %d to SF %d] RTT_FH: %"PRId64"\n", start_fh_prev_sf, end_fh_sf, clock_difftime_ns(start_fh_prev, end_fh)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 0 ); @@ -985,8 +972,8 @@ void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { end_rf_ts = proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance; if (recv_if_count != 0 ) { recv_if_count = recv_if_count-1; - LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %d; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); - LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %d; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); + LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); + LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); From e98c3e8143b818518120802346d5a6eb98ce0673 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Feb 2017 12:54:46 +0100 Subject: [PATCH 324/571] report warnings to user after compilation Let the user see how many warnings a compilation generates. The goal is to have 0 warning, for any compiled component of openair. --- cmake_targets/tools/build_helper | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 30cfa0c9fb..ede8ef4196 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -136,6 +136,20 @@ clean_all_files() { # Compilers ################################### +#check_warnings: +# print error message if the compilation had warnings +#argument: +# $1: log file +check_warnings() { + #we look for 'warning:' in the compilation log file + #this is how gcc starts a warning + #this is not perfect, we may get false positive + warning_count=`grep "warning:" "$1"|wc -l` + if [ $warning_count -gt 0 ]; then + echo_error "WARNING: $warning_count warnings. See $1" + fi +} + compilations() { cd $OPENAIR_DIR/cmake_targets/$1/build set +e @@ -153,6 +167,7 @@ compilations() { if [ -s $3 ] ; then cp $3 $4 echo_success "$2 compiled" + check_warnings "$dlog/$2.$REL.txt" else echo_error "$2 compilation failed" exit 1 From 46b37aaa31e74b5bb737ca719a2b2168a434864d Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 21 Feb 2017 14:35:00 +0100 Subject: [PATCH 325/571] UE 20 MHz fix + remove too restrictive assert --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 64 +++++++++++++------------- openair1/SCHED/phy_procedures_lte_ue.c | 27 ++++++----- targets/RT/USER/lte-ue.c | 5 +- 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index c4dfecf848..71930b51c4 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4225,37 +4225,39 @@ int generate_ue_dlsch_params_from_dci(int frame, } if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; - } else { - if ((rballoc&(1<<10)) == 0) { //Gap 1 - rballoc = rballoc&(~(1<<12)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; - } - else { //Gap 2 - rballoc = rballoc&(~(1<<12)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; - } + + dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; + } + else { + if ((rballoc&(1<<10)) == 0) { //Gap 1 + rballoc = rballoc&(~(1<<12)); + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + } + else { //Gap 2 + rballoc = rballoc&(~(1<<12)); + dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; + dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; + dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + } } dlsch0_harq->vrb_type = vrb_type; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 9bf0779fe2..cd8fbdbc8e 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -364,7 +364,7 @@ void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance) PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!! - LOG_I(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); + LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); } @@ -1043,7 +1043,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt int overflow=0; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int k,l; - int dummy_tx_buffer[3840*4] __attribute__((aligned(16))); + int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16))); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN); @@ -1076,11 +1076,15 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt overflow = ulsch_start - 9*frame_parms->samples_per_tti; for (aa=0; aanb_antennas_tx; aa++) { - memset(&ue->common_vars.txdata[aa][ulsch_start],0, - 4*cmin(frame_parms->samples_per_tti-overflow,frame_parms->samples_per_tti)); - - if (overflow> 0) - memset(&ue->common_vars.txdata[aa][0],0,4*overflow); + if (overflow > 0) + { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow)); + memset(&ue->common_vars.txdata[aa][0],0,4*overflow); + } + else + { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti); + } } /*#else overflow = ulsch_start - 9*frame_parms->samples_per_tti; @@ -1469,7 +1473,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", Mod_id, ue->ulsch[eNB_id]->rnti, - frame_tx,subframe_tx, + frame_tx%1024,subframe_tx, ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } @@ -1632,8 +1636,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", - Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); + LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); start_meas(&ue->ulsch_modulation_stats); ulsch_modulation(ue->common_vars.txdataF, tx_amp, @@ -1935,7 +1939,8 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin &pucch_payload, &len); - LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); + LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", + frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); // Part - IV diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 64f8f42d0f..a102705c34 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -674,12 +674,11 @@ void *UE_thread(void *arg) { rxp[i] = (void*)&dummy_rx[i][0]; for (int sf=0; sf<10; sf++) // printf("Reading dummy sf %d\n",sf); - AssertFatal ( UE->frame_parms.samples_per_tti == - UE->rfdevice.trx_read_func(&UE->rfdevice, + UE->rfdevice.trx_read_func(&UE->rfdevice, ×tamp, rxp, UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx), ""); + UE->frame_parms.nb_antennas_rx); } } From 068ce4ca5588a00b261c267e1f5d1e690c31adc6 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 22 Feb 2017 09:29:33 +0100 Subject: [PATCH 326/571] adding a client-side pre-commit script. This script needs to be installed by every developer manually. see comments in script. --- pre-commit | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 pre-commit diff --git a/pre-commit b/pre-commit new file mode 100644 index 0000000000..82587fce34 --- /dev/null +++ b/pre-commit @@ -0,0 +1,31 @@ + +#!/bin/bash +# Installation: +# cp pre-commit .git/hooks +# chmod +x .git/hooks/pre-commit + +OPTIONS="--convert-tabs --indent=spaces=2 --indent-switches --indent-col1-comments --break-blocks --delete-empty-lines --align-pointer=name --keep-one-line-blocks --keep-one-line-statements --lineend=linux" + +RETURN=0 +ASTYLE=$(which astyle) +if [ $? -ne 0 ]; then + echo "[!] astyle not installed. Unable to check source file format policy." >&2 + exit 1 +fi + +FILES=`git diff --cached --name-only --diff-filter=ACMR | grep -E "\.(c|cpp|h)$"` +for FILE in $FILES; do + $ASTYLE $OPTIONS < $FILE | cmp -s $FILE - + if [ $? -ne 0 ]; then + echo "[!] $FILE does not respect the agreed coding style." >&2 + RETURN=1 + fi +done + +if [ $RETURN -eq 1 ]; then + echo "" >&2 + echo "Make sure you have run astyle with the following options:" >&2 + echo $OPTIONS >&2 +fi + +exit $RETURN \ No newline at end of file From b0d468c0f7518774a5ed3b5078342a95289d8883 Mon Sep 17 00:00:00 2001 From: fnabet Date: Wed, 22 Feb 2017 11:40:55 +0100 Subject: [PATCH 327/571] RLC AM: add retransmission and Rx status pdu --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 141 +--- .../LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h | 26 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h | 1 - openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c | 38 + openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.h | 8 + openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c | 2 - .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 718 ++++++++++++++---- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h | 24 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c | 9 +- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 109 ++- .../LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h | 3 +- .../AM_v9.3.0/rlc_am_timer_poll_retransmit.c | 4 + 12 files changed, 759 insertions(+), 324 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index ad9810cfff..df8682f726 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -389,7 +389,7 @@ rlc_am_get_pdus ( rlc_am_entity_t * const rlc_pP ) { - int display_flag = 0; + //int display_flag = 0; // 5.1.3.1 Transmit operations // 5.1.3.1.1 // General @@ -436,123 +436,21 @@ rlc_am_get_pdus ( rlc_pP->nb_bytes_requested_by_mac,rlc_pP->t_status_prohibit.ms_time_out,(rlc_pP->status_requested & RLC_AM_STATUS_TRIGGERED_DELAYED)); } - /*while ((rlc_pP->nb_bytes_requested_by_mac > 0) && (stay_on_this_list)) { - mem_block_t* pdu = list_get_head(&rlc_pP->control_pdu_list); - if (pdu != NULL { - if ( ((rlc_am_tx_control_pdu_management_t*)(pdu->data))->size <= rlc_pP->nb_bytes_requested_by_mac) { - pdu = list_remove_head(&rlc_pP->control_pdu_list); - #if TRACE_RLC_AM_TX - msg ("[FRAME %5u][%s][RLC_AM][MOD %u/%u][RB %u] SEND CONTROL PDU\n", ((rlc_am_entity_t *) rlc_pP)->module_id,((rlc_am_entity_t *) rlc_pP)->rb_id, ctxt_pP->frame); - #endif - list_add_tail_eurecom (pdu, &rlc_pP->pdus_to_mac_layer); - rlc_pP->nb_bytes_requested_by_mac = rlc_pP->nb_bytes_requested_by_mac - ((rlc_am_tx_control_pdu_management_t*)(pdu->data))->size; - } else { - stay_on_this_list = 0; - } - } else { - stay_on_this_list = 0; - } - }*/ // THEN TRY TO SEND RETRANS PDU - // BUG FIX : they can be PDU to ReTx due to received NACK or 1 PDU (SN = vtS - 1) to ReTx due TPoll Expiry if Buffer Occupancy is null - if (rlc_pP->first_retrans_pdu_sn >= 0) { - rlc_am_tx_data_pdu_management_t* tx_data_pdu_management; + if ((rlc_pP->retrans_num_bytes_to_retransmit) && (rlc_pP->nb_bytes_requested_by_mac > 2)) { - // tx min 3 bytes because of the size of the RLC header - while ((rlc_pP->nb_bytes_requested_by_mac > 2) && - (rlc_pP->first_retrans_pdu_sn >= 0) && - (rlc_pP->first_retrans_pdu_sn != rlc_pP->vt_s)) { + /* Get 1 AM data PDU or PDU segment to retransmit */ + mem_block_t* pdu_retx = rlc_am_get_pdu_to_retransmit(ctxt_pP, rlc_pP); - tx_data_pdu_management = &rlc_pP->tx_data_pdu_buffer[rlc_pP->first_retrans_pdu_sn]; + if (pdu_retx != NULL) { + list_add_tail_eurecom (pdu_retx, &rlc_pP->pdus_to_mac_layer); - if ((tx_data_pdu_management->header_and_payload_size <= rlc_pP->nb_bytes_requested_by_mac) && (tx_data_pdu_management->retx_count >= 0) - && (tx_data_pdu_management->nack_so_start == 0) && (tx_data_pdu_management->nack_so_stop == 0x7FFF)) { - mem_block_t* copy = rlc_am_retransmit_get_copy(ctxt_pP, rlc_pP, rlc_pP->first_retrans_pdu_sn); - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RE-SEND DATA PDU SN %04d %d BYTES\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->first_retrans_pdu_sn, - tx_data_pdu_management->header_and_payload_size); - rlc_pP->stat_tx_data_pdu += 1; - rlc_pP->stat_tx_retransmit_pdu += 1; - rlc_pP->stat_tx_retransmit_pdu_by_status += 1; - rlc_pP->stat_tx_data_bytes += tx_data_pdu_management->header_and_payload_size; - rlc_pP->stat_tx_retransmit_bytes += tx_data_pdu_management->header_and_payload_size; - rlc_pP->stat_tx_retransmit_bytes_by_status += tx_data_pdu_management->header_and_payload_size; - - list_add_tail_eurecom (copy, &rlc_pP->pdus_to_mac_layer); - rlc_pP->nb_bytes_requested_by_mac = rlc_pP->nb_bytes_requested_by_mac - tx_data_pdu_management->header_and_payload_size; - - tx_data_pdu_management->retx_count = tx_data_pdu_management->retx_count_next; return; - } else if ((tx_data_pdu_management->retx_count >= 0) && (rlc_pP->nb_bytes_requested_by_mac >= RLC_AM_MIN_SEGMENT_SIZE_REQUEST)) { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" SEND SEGMENT OF DATA PDU SN %04d MAC BYTES %d SIZE %d RTX COUNT %d nack_so_start %d nack_so_stop %04X(hex)\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->first_retrans_pdu_sn, - rlc_pP->nb_bytes_requested_by_mac, - tx_data_pdu_management->header_and_payload_size, - tx_data_pdu_management->retx_count, - tx_data_pdu_management->nack_so_start, - tx_data_pdu_management->nack_so_stop); - - mem_block_t* copy = rlc_am_retransmit_get_subsegment( - ctxt_pP, - rlc_pP, - rlc_pP->first_retrans_pdu_sn, - &rlc_pP->nb_bytes_requested_by_mac); - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" SEND SEGMENT OF DATA PDU SN %04d (NEW SO %05d)\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->first_retrans_pdu_sn, - tx_data_pdu_management->nack_so_start); - - rlc_pP->stat_tx_data_pdu += 1; - rlc_pP->stat_tx_retransmit_pdu += 1; - rlc_pP->stat_tx_retransmit_pdu_by_status += 1; - rlc_pP->stat_tx_data_bytes += (((struct mac_tb_req*)(copy->data))->tb_size); - rlc_pP->stat_tx_retransmit_bytes += (((struct mac_tb_req*)(copy->data))->tb_size); - rlc_pP->stat_tx_retransmit_bytes_by_status += (((struct mac_tb_req*)(copy->data))->tb_size); - list_add_tail_eurecom (copy, &rlc_pP->pdus_to_mac_layer); - } else { - break; - } - - // update first_retrans_pdu_sn - while ((rlc_pP->first_retrans_pdu_sn != rlc_pP->vt_s) && - (!(rlc_pP->tx_data_pdu_buffer[rlc_pP->first_retrans_pdu_sn].flags.retransmit))) { - rlc_pP->first_retrans_pdu_sn = (rlc_pP->first_retrans_pdu_sn+1) & RLC_AM_SN_MASK; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" UPDATED first_retrans_pdu_sn SN %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->first_retrans_pdu_sn); - }; - - display_flag = 1; - - if (rlc_pP->first_retrans_pdu_sn == rlc_pP->vt_s) { - // no more pdu to be retransmited - rlc_pP->first_retrans_pdu_sn = -1; - display_flag = 0; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" CLEAR first_retrans_pdu_sn\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); - } - - if (display_flag > 0) { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" UPDATED first_retrans_pdu_sn %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->first_retrans_pdu_sn); - } - - return; - - /* ONLY ONE TB PER TTI - if ((tx_data_pdu_management->retx_count >= 0) && (rlc_pP->nb_bytes_requested_by_mac < RLC_AM_MIN_SEGMENT_SIZE_REQUEST)) { - #if TRACE_RLC_AM_TX - msg ("[FRAME %5u][%s][RLC_AM][MOD %u/%u][RB %u] BREAK LOOP ON RETRANSMISSION BECAUSE ONLY %d BYTES ALLOWED TO TRANSMIT BY MAC\n",ctxt_pP->frame, ((rlc_am_entity_t *) rlc_pP)->module_id,((rlc_am_entity_t *) rlc_pP)->rb_id, rlc_pP->nb_bytes_requested_by_mac); - #endif - break; - }*/ } } - if ((rlc_pP->nb_bytes_requested_by_mac > 2) && (rlc_pP->vt_s != rlc_pP->vt_ms)) { + // THEN TRY TO SEND NEW DATA PDU + if ((rlc_pP->nb_bytes_requested_by_mac > 2) && (rlc_pP->sdu_buffer_occupancy) && (rlc_pP->vt_s != rlc_pP->vt_ms)) { rlc_am_segment_10(ctxt_pP, rlc_pP); list_add_list (&rlc_pP->segmentation_pdu_list, &rlc_pP->pdus_to_mac_layer); @@ -563,29 +461,6 @@ rlc_am_get_pdus ( } } - if ((rlc_pP->pdus_to_mac_layer.head == NULL) && - (rlc_am_is_timer_poll_retransmit_timed_out(ctxt_pP, rlc_pP)) && - (rlc_pP->nb_bytes_requested_by_mac > 2)) { - rlc_am_retransmit_any_pdu(ctxt_pP, rlc_pP); - return; - } else { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" COULD NOT RETRANSMIT ANY PDU BECAUSE ", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); - - if (rlc_pP->pdus_to_mac_layer.head != NULL) { - LOG_D(RLC, "THERE ARE SOME PDUS READY TO TRANSMIT "); - } - - if (!(rlc_am_is_timer_poll_retransmit_timed_out(ctxt_pP, rlc_pP))) { - LOG_D(RLC, "TIMER POLL DID NOT TIMED OUT (RUNNING = %d NUM PDUS TO RETRANS = %d NUM BYTES TO RETRANS = %d) ", rlc_pP->t_poll_retransmit.running, - rlc_pP->retrans_num_pdus, rlc_pP->retrans_num_bytes_to_retransmit); - } - - if (rlc_pP->nb_bytes_requested_by_mac <= 2) { - LOG_D(RLC, "NUM BYTES REQUESTED BY MAC = %d", rlc_pP->nb_bytes_requested_by_mac); - } - LOG_D(RLC, "\n"); - } break; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h index a2fc95aba5..10f310d5de 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h @@ -56,6 +56,9 @@ /** PDU minimal header size in bytes. */ # define RLC_AM_HEADER_MIN_SIZE 2 +/** PDU Segment minimal header size in bytes = PDU header + SOStart + SOEnd. */ +# define RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE 4 + /** If we want to send a segment of a PDU, then the min transport block size requested by MAC should be this amount. */ # define RLC_AM_MIN_SEGMENT_SIZE_REQUEST 8 @@ -77,8 +80,8 @@ /* MACRO DEFINITIONS */ -#define RLC_AM_NEXT_SN(sn) (((sn)+1) & ((RLC_AM_SN_MODULO)-1)) -#define RLC_AM_PREV_SN(sn) (((sn)+(RLC_AM_SN_MODULO)-1) & ((RLC_AM_SN_MODULO)-1)) +#define RLC_AM_NEXT_SN(sn) (((sn)+1) & (RLC_AM_SN_MASK)) +#define RLC_AM_PREV_SN(sn) (((sn)+(RLC_AM_SN_MODULO)-1) & (RLC_AM_SN_MASK)) #define RLC_DIFF_SN(sn,snref,modulus) ((sn+(modulus)-snref) & ((modulus)-1)) #define RLC_SN_IN_WINDOW(sn,snref,modulus) ((RLC_DIFF_SN(sn,snref,modulus)) < ((modulus) >> 1)) @@ -103,7 +106,8 @@ #define RLC_AM_PDU_RF_BITS 1 -#define EURL_AM_PDU_LSF_BITS 1 +#define RLC_AM_LI_BITS 11 +#define RLC_AM_LI_MASK 0x7FF /* AM Data PDU */ @@ -113,12 +117,28 @@ #define RLC_AM_PDU_RF_OFFSET (RLC_AM_PDU_POLL_OFFSET + RLC_AM_PDU_POLL_BITS) #define RLC_AM_PDU_D_C_OFFSET (RLC_AM_PDU_RF_OFFSET + RLC_AM_PDU_RF_BITS) +#define RLC_AM_PDU_GET_FI_START(px) (RLC_GET_BIT((px),RLC_AM_PDU_FI_OFFSET + 1)) +#define RLC_AM_PDU_GET_FI_END(px) (RLC_GET_BIT((px),RLC_AM_PDU_FI_OFFSET)) + +#define RLC_AM_PDU_GET_LI(x,offset) (((x) >> (offset)) & RLC_AM_LI_MASK) +#define RLC_AM_PDU_SET_LI(x,li,offset) ((x) |= (((li) & RLC_AM_LI_MASK) << (offset))) + #define RLC_AM_PDU_SET_E(px) (RLC_SET_BIT((px),RLC_AM_PDU_E_OFFSET)) #define RLC_AM_PDU_SET_D_C(px) (RLC_SET_BIT((px),RLC_AM_PDU_D_C_OFFSET)) #define RLC_AM_PDU_SET_RF(px) (RLC_SET_BIT((px),RLC_AM_PDU_RF_OFFSET)) #define RLC_AM_PDU_SET_POLL(px) (RLC_SET_BIT((px),RLC_AM_PDU_POLL_OFFSET)) #define RLC_AM_PDU_CLEAR_POLL(px) (RLC_CLEAR_BIT((px),RLC_AM_PDU_POLL_OFFSET)) +#define RLC_AM_PDU_SEGMENT_SO_LENGTH 15 +#define RLC_AM_PDU_SEGMENT_SO_BYTES 2 +#define RLC_AM_PDU_SEGMENT_SO_OFFSET 0 +#define RLC_AM_PDU_LSF_OFFSET (RLC_AM_PDU_SEGMENT_SO_OFFSET + RLC_AM_PDU_SEGMENT_SO_LENGTH) + +#define RLC_AM_PDU_SET_LSF(px) (RLC_SET_BIT((px),RLC_AM_PDU_LSF_OFFSET)) + +#define RLC_AM_HEADER_LI_LENGTH(li) ((li) + ((li)>>1) + ((li)&1)) +#define RLC_AM_PDU_SEGMENT_HEADER_SIZE(numLis) (RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + RLC_AM_HEADER_LI_LENGTH(numLis)) + /* STATUS PDU */ #define RLC_AM_STATUS_PDU_CPT_STATUS 0 diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h index 682a781818..602e8e98c2 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h @@ -175,7 +175,6 @@ typedef struct rlc_am_entity_s { sdu_size_t nb_bytes_requested_by_mac; /*!< \brief Number of remaining bytes available for transmission of any RLC PDU indicated by lower layer */ list_t pdus_to_mac_layer; /*!< \brief PDUs buffered for transmission to MAC layer. */ list_t control_pdu_list; /*!< \brief Control PDUs buffered for transmission to MAC layer. */ - rlc_sn_t first_retrans_pdu_sn; /*!< \brief Lowest sequence number of PDU to be retransmitted. */ list_t segmentation_pdu_list; /*!< \brief List of "freshly" segmented PDUs. */ uint8_t status_requested; /*!< \brief Status bitmap requested by peer. */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c index 820b06c233..f7ef37597a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c @@ -108,3 +108,41 @@ rlc_am_in_sdu_is_empty( return 0; } + +// called when PDU is ACKED +//----------------------------------------------------------------------------- +void +rlc_am_pdu_sdu_data_cnf( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t* const rlc_pP, + const rlc_sn_t snP) +{ + int pdu_sdu_index; + int sdu_index; + + for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP].nb_sdus; pdu_sdu_index++) { + sdu_index = rlc_pP->tx_data_pdu_buffer[snP].sdus_index[pdu_sdu_index]; + assert(sdu_index >= 0); + assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE); + rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1; + + if ((rlc_pP->input_sdus[sdu_index].nb_pdus_ack == rlc_pP->input_sdus[sdu_index].nb_pdus) && + (rlc_pP->input_sdus[sdu_index].sdu_remaining_size == 0)) { + #if TEST_RLC_AM + rlc_am_v9_3_0_test_data_conf ( + rlc_pP->module_id, + rlc_pP->rb_id, + rlc_pP->input_sdus[sdu_index].mui, + RLC_SDU_CONFIRM_YES); + #else + rlc_data_conf( + ctxt_pP, + rlc_pP->rb_id, + rlc_pP->input_sdus[sdu_index].mui, + RLC_SDU_CONFIRM_YES, + rlc_pP->is_data_plane); + #endif + rlc_am_free_in_sdu(ctxt_pP, rlc_pP, sdu_index); + } + } +} diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.h index 3201dfc941..c596bc671a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.h @@ -77,5 +77,13 @@ protected_rlc_am_in_sdu(void rlc_am_free_in_sdu_data (const protocol_ctxt_t* con * \return 1 if the buffer is empty, else 0. */ protected_rlc_am_in_sdu(signed int rlc_am_in_sdu_is_empty(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP);) + +/*! \fn void rlc_am_pdu_sdu_data_cnf(const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* const rlc_pP,const rlc_sn_t snP) +* \brief Process SDU cnf of a ACKED PDU for all SDUs concatenated in this PDU. +* \param[in] ctxtP Running context. +* \param[in] rlcP RLC AM protocol instance pointer. +* \param[in] snP Sequence number of the PDU. +*/ +protected_rlc_am_in_sdu(void rlc_am_pdu_sdu_data_cnf(const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* const rlc_pP,const rlc_sn_t snP);) /** @} */ # endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index ce5afe7c59..6a36d9b7de 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -80,7 +80,6 @@ rlc_am_init( rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED; rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 - rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->initialized = TRUE; } @@ -136,7 +135,6 @@ rlc_am_reestablish( rlc_pP->status_requested = RLC_AM_STATUS_NOT_TRIGGERED; rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 - rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->initialized = TRUE; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index d2941b061d..c636fc7082 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -30,12 +30,13 @@ #include "UTIL/LOG/log.h" #include "msc.h" //----------------------------------------------------------------------------- -void rlc_am_nack_pdu ( +boolean_t rlc_am_nack_pdu ( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlc_pP, const rlc_sn_t snP, - const sdu_size_t so_startP, - const sdu_size_t so_endP) + const rlc_sn_t prev_nack_snP, + sdu_size_t so_startP, + sdu_size_t so_endP) { // 5.2.1 Retransmission // ... @@ -51,43 +52,116 @@ void rlc_am_nack_pdu ( mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[snP]; //int pdu_sdu_index; //int sdu_index; + boolean_t status = TRUE; + boolean_t retx_count_increment = FALSE; + sdu_size_t pdu_data_to_retx = 0; if (mb_p != NULL) { assert(so_startP <= so_endP); - //----------------------------------------- - // allow holes in reports - // it is assumed that hole reports are done in byte offset - // increasing order among calls refering to only one status PDU - // and among time - //----------------------------------------- - if (rlc_pP->tx_data_pdu_buffer[snP].last_nack_time != ctxt_pP->frame) { - rlc_pP->tx_data_pdu_buffer[snP].last_nack_time = ctxt_pP->frame; - rlc_am_clear_holes(ctxt_pP, rlc_pP, snP); + // Handle full PDU NACK first + if ((so_startP == 0) && (so_endP == 0x7FFF)) { + if ((prev_nack_snP != snP) && (tx_data_pdu_buffer_p->flags.ack == 0) && (tx_data_pdu_buffer_p->flags.max_retransmit == 0)) { + pdu_data_to_retx = tx_data_pdu_buffer_p->payload_size; + /* Increment VtReTxNext if this is the first NACK or if some segments have already been transmitted */ + if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (tx_data_pdu_buffer_p->nack_so_start)) + { + retx_count_increment = TRUE; + } + + tx_data_pdu_buffer_p->nack_so_start = 0; + tx_data_pdu_buffer_p->num_holes = 0; + tx_data_pdu_buffer_p->retx_hole_index = 0; + tx_data_pdu_buffer_p->nack_so_stop = tx_data_pdu_buffer_p->payload_size - 1; + #if TRACE_RLC_AM_HOLE + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[HOLE] SN %04d GLOBAL NACK 0->%05d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + snP, + so_stopP); + #endif + assert(tx_data_pdu_buffer_p->nack_so_start < tx_data_pdu_buffer_p->payload_size); + } + else { + status = FALSE; + } + } + else if (tx_data_pdu_buffer_p->flags.max_retransmit == 0) { + // Handle Segment offset + if (so_endP == 0x7FFF) { + so_endP = tx_data_pdu_buffer_p->payload_size - 1; + } + + // Check consistency + if ((so_startP < so_endP) && (so_endP < tx_data_pdu_buffer_p->payload_size)) { + if (prev_nack_snP != snP) { + /* New NACK_SN with SO */ + /* check whether a new segment is to be placed in Retransmission Buffer, then increment vrReTx */ + if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (so_startP < tx_data_pdu_buffer_p->nack_so_start)) { + retx_count_increment = TRUE; + } + + tx_data_pdu_buffer_p->num_holes = 1; + tx_data_pdu_buffer_p->retx_hole_index = 0; + tx_data_pdu_buffer_p->hole_so_start[0] = so_startP; + tx_data_pdu_buffer_p->hole_so_stop[0] = so_endP; + tx_data_pdu_buffer_p->nack_so_start = so_startP; + tx_data_pdu_buffer_p->nack_so_stop = so_endP; + pdu_data_to_retx = so_endP - so_startP + 1; + + } + else if ((tx_data_pdu_buffer_p->num_holes) && (tx_data_pdu_buffer_p->num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU)) { + /* New SOStart/SOEnd for the same NACK_SN than before */ + /* check discontinuity */ + if (so_startP > tx_data_pdu_buffer_p->hole_so_stop[tx_data_pdu_buffer_p->num_holes - 1]) { + tx_data_pdu_buffer_p->hole_so_start[tx_data_pdu_buffer_p->num_holes] = so_startP; + tx_data_pdu_buffer_p->hole_so_stop[tx_data_pdu_buffer_p->num_holes] = so_endP; + tx_data_pdu_buffer_p->nack_so_stop = so_endP; + tx_data_pdu_buffer_p->num_holes ++; + pdu_data_to_retx = so_endP - so_startP + 1; + } + else { + status = FALSE; + } + } + else { + status = FALSE; + } + } + else { + status = FALSE; + } + } + else { + status = FALSE; } - rlc_am_add_hole(ctxt_pP, rlc_pP, snP, so_startP, so_endP); - - if (rlc_pP->first_retrans_pdu_sn < 0) { - rlc_pP->first_retrans_pdu_sn = snP; - } else if (rlc_am_tx_sn1_gt_sn2(ctxt_pP, rlc_pP, rlc_pP->first_retrans_pdu_sn, snP)) { - rlc_pP->first_retrans_pdu_sn = snP; - } - - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] NACK PDU SN %04d previous retx_count %d 1ST_RETRANS_PDU %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - snP, - rlc_pP->tx_data_pdu_buffer[snP].retx_count, - rlc_pP->first_retrans_pdu_sn); - - rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 1; - - /* TODO : before incrementing retx_count_next, one have to check this must be a new occurrence of retransmission */ - if (rlc_pP->tx_data_pdu_buffer[snP].retx_count == rlc_pP->tx_data_pdu_buffer[snP].retx_count_next){ - rlc_pP->tx_data_pdu_buffer[snP].retx_count_next ++; - rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->tx_data_pdu_buffer[snP].payload_size; + if (status) { + tx_data_pdu_buffer_p->flags.nack = 1; + if ((retx_count_increment) && (tx_data_pdu_buffer_p->retx_count == tx_data_pdu_buffer_p->retx_count_next)) { + tx_data_pdu_buffer_p->retx_count_next ++; + } + if (tx_data_pdu_buffer_p->flags.retransmit == 1) { + if (prev_nack_snP != snP) { + /* if first process of this NACK_SN and data already pending for retx */ + rlc_pP->retrans_num_bytes_to_retransmit += (pdu_data_to_retx - tx_data_pdu_buffer_p->retx_payload_size); + tx_data_pdu_buffer_p->retx_payload_size = pdu_data_to_retx; + } + else if (tx_data_pdu_buffer_p->num_holes > 1) { + /* Segment case : SOStart and SOEnd already received for same NACK_SN */ + /* filter case where a NACK_SN is received twice with SO first time and no SO second time */ + rlc_pP->retrans_num_bytes_to_retransmit += pdu_data_to_retx; + tx_data_pdu_buffer_p->retx_payload_size += pdu_data_to_retx; + } + } + else { + tx_data_pdu_buffer_p->flags.retransmit = 1; + rlc_pP->retrans_num_bytes_to_retransmit += pdu_data_to_retx; + tx_data_pdu_buffer_p->retx_payload_size = pdu_data_to_retx; + rlc_pP->retrans_num_pdus ++; + } } /* TODO: Move this part in UL SCH processing */ @@ -123,8 +197,10 @@ void rlc_am_nack_pdu ( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU SN %05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP); - //assert(2==3); + status = FALSE; } + + return status; } //----------------------------------------------------------------------------- void rlc_am_ack_pdu ( @@ -133,8 +209,6 @@ void rlc_am_ack_pdu ( const rlc_sn_t snP) { mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; - int pdu_sdu_index; - int sdu_index; rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 0; @@ -147,83 +221,13 @@ void rlc_am_ack_pdu ( snP, rlc_pP->tx_data_pdu_buffer[snP].retx_count); - if (rlc_pP->tx_data_pdu_buffer[snP].retx_count >= 0) { - rlc_pP->retrans_num_bytes_to_retransmit -= rlc_pP->tx_data_pdu_buffer[snP].payload_size; + if (rlc_pP->tx_data_pdu_buffer[snP].retx_payload_size) { + rlc_pP->retrans_num_bytes_to_retransmit -= rlc_pP->tx_data_pdu_buffer[snP].retx_payload_size; + rlc_pP->tx_data_pdu_buffer[snP].retx_payload_size = 0; + rlc_pP->tx_data_pdu_buffer[snP].num_holes = 0; + rlc_pP->retrans_num_pdus --; } - for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP].nb_sdus; pdu_sdu_index++) { - sdu_index = rlc_pP->tx_data_pdu_buffer[snP].sdus_index[pdu_sdu_index]; - assert(sdu_index >= 0); - assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE); - rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1; - - if ((rlc_pP->input_sdus[sdu_index].nb_pdus_ack == rlc_pP->input_sdus[sdu_index].nb_pdus) && - (rlc_pP->input_sdus[sdu_index].sdu_remaining_size == 0)) { -#if TEST_RLC_AM - rlc_am_v9_3_0_test_data_conf ( - rlc_pP->module_id, - rlc_pP->rb_id, - rlc_pP->input_sdus[sdu_index].mui, - RLC_SDU_CONFIRM_YES); -#else - rlc_data_conf( - ctxt_pP, - rlc_pP->rb_id, - rlc_pP->input_sdus[sdu_index].mui, - RLC_SDU_CONFIRM_YES, - rlc_pP->is_data_plane); -#endif - rlc_am_free_in_sdu(ctxt_pP, rlc_pP, sdu_index); - } - } - - // 7.1... - // VT(A) – Acknowledgement state variable - // This state variable holds the value of the SN of the next AMD PDU for which a positive acknowledgment is to be - // received in-sequence, and it serves as the lower edge of the transmitting window. It is initially set to 0, and is updated - // whenever the AM RLC entity receives a positive acknowledgment for an AMD PDU with SN = VT(A). - rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; - - if (snP == rlc_pP->vt_a) { - //rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; - do { - memset(&rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a], 0, sizeof(rlc_am_tx_data_pdu_management_t)); - - if (rlc_pP->vt_a == rlc_pP->first_retrans_pdu_sn) { - rlc_pP->first_retrans_pdu_sn = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; - } - - rlc_pP->vt_a = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; - } while ((rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a].flags.ack == 1) && (rlc_pP->vt_a != rlc_pP->vt_s)); - - - rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] UPDATED VT(A) %04d VT(MS) %04d VT(S) %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->vt_a, - rlc_pP->vt_ms, - rlc_pP->vt_s); - } - - if (snP == rlc_pP->first_retrans_pdu_sn) { - do { - rlc_pP->first_retrans_pdu_sn = (rlc_pP->first_retrans_pdu_sn + 1) & RLC_AM_SN_MASK; - - if (rlc_pP->tx_data_pdu_buffer[rlc_pP->first_retrans_pdu_sn].retx_count >= 0) { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] UPDATED first_retrans_pdu_sn -> %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->first_retrans_pdu_sn); - break; - } - } while (rlc_pP->first_retrans_pdu_sn != rlc_pP->vt_s); - - if (rlc_pP->vt_s == rlc_pP->first_retrans_pdu_sn) { - rlc_pP->first_retrans_pdu_sn = -1; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] UPDATED first_retrans_pdu_sn -> %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->first_retrans_pdu_sn); - } - } } else { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] WARNING ACK PDU SN %05d -> NO PDU TO ACK\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -233,29 +237,11 @@ void rlc_am_ack_pdu ( free_mem_block(mb_p, __func__); rlc_pP->tx_data_pdu_buffer[snP].mem_block = NULL; } - - if (rlc_pP->tx_data_pdu_buffer[snP].flags.ack > 0) { - if (snP == rlc_pP->vt_a) { - //rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; - do { - memset(&rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a], 0, sizeof(rlc_am_tx_data_pdu_management_t)); - - if (rlc_pP->vt_a == rlc_pP->first_retrans_pdu_sn) { - rlc_pP->first_retrans_pdu_sn = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; - } - - rlc_pP->vt_a = (rlc_pP->vt_a + 1) & RLC_AM_SN_MASK; - } while ((rlc_pP->tx_data_pdu_buffer[rlc_pP->vt_a].flags.ack == 1) && (rlc_pP->vt_a != rlc_pP->vt_s)); - - rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] UPDATED VT(A) %04d VT(MS) %04d VT(S) %04d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), - rlc_pP->vt_a, - rlc_pP->vt_ms, - rlc_pP->vt_s); - } - } } + rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; + rlc_pP->tx_data_pdu_buffer[snP].flags.transmitted = 0; + rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 0; + } //----------------------------------------------------------------------------- mem_block_t* rlc_am_retransmit_get_copy ( @@ -265,25 +251,343 @@ mem_block_t* rlc_am_retransmit_get_copy ( { mem_block_t* mb_original_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; - if (mb_original_p != NULL) { + AssertFatal (mb_original_p != NULL, "RLC AM PDU Copy Error: Empty block sn=%d vtA=%d vtS=%d LcId=%d !\n", + snP,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); - rlc_am_tx_data_pdu_management_t *pdu_mngt = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE]; + rlc_am_tx_data_pdu_management_t *pdu_mngt = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE]; - int size = pdu_mngt->header_and_payload_size + sizeof(struct mac_tb_req); - mem_block_t* mb_copy = get_free_mem_block(size, __func__); - memcpy(mb_copy->data, mb_original_p->data, size); + /* We need to allocate a new buffer and copy to it because header content may change for Polling bit */ + int size = pdu_mngt->header_and_payload_size + sizeof(struct mac_tb_req); + mem_block_t* mb_copy = get_free_mem_block(size, __func__); + memcpy(mb_copy->data, mb_original_p->data, size); - rlc_am_pdu_sn_10_t *pdu_p = (rlc_am_pdu_sn_10_t*) (&mb_copy->data[sizeof(struct mac_tb_req)]); - ((struct mac_tb_req*)(mb_copy->data))->data_ptr = (uint8_t*)pdu_p; + rlc_am_pdu_sn_10_t *pdu_p = (rlc_am_pdu_sn_10_t*) (&mb_copy->data[sizeof(struct mac_tb_req)]); + ((struct mac_tb_req*)(mb_copy->data))->data_ptr = (uint8_t*)pdu_p; - pdu_mngt->flags.retransmit = 0; - - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_p, pdu_mngt->payload_size,false); - return mb_copy; - } else { - return NULL; - } + return mb_copy; } + +//----------------------------------------------------------------------------- +mem_block_t* rlc_am_retransmit_get_am_segment( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + rlc_am_tx_data_pdu_management_t *const pdu_mngt, + sdu_size_t * const payload_sizeP /* in-out*/) +{ + int16_t sdus_segment_size[RLC_AM_MAX_SDU_IN_PDU]; + mem_block_t* mb_original_p = pdu_mngt->mem_block; + mem_block_t* mem_pdu_segment_p = NULL; + uint8_t *pdu_original_header_p = NULL; + uint8_t *pdu_segment_header_p = NULL; + sdu_size_t retx_so_start,retx_so_stop; //starting and ending SO for retransmission in this PDU + rlc_sn_t sn = pdu_mngt->sn; + uint16_t header_so_part; + boolean_t fi_start, fi_end; + uint8_t sdu_index = 0; + uint8_t sdu_segment_index = 0; + uint8_t num_LIs_pdu_segment = pdu_mngt->nb_sdus - 1; + uint8_t li_bit_offset = 4; /* toggle between 0 and 4 */ + uint8_t li_jump_offset = 1; /* toggle between 1 and 2 */ + + + AssertFatal (mb_original_p != NULL, "RLC AM PDU Segment Error: Empty block sn=%d vtA=%d vtS=%d LcId=%d !\n", + sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); + + + AssertFatal (pdu_mngt->payload == mb_original_p->data + sizeof(struct mac_tb_req) + pdu_mngt->header_and_payload_size - pdu_mngt->payload_size, + "RLC AM PDU Segment Error: Inconsistent data pointers p1=%p p2=%p sn = %d total size = %d data size = %d LcId=%d !\n", + pdu_mngt->payload,mb_original_p->data + sizeof(struct mac_tb_req),pdu_mngt->header_and_payload_size,pdu_mngt->payload_size,sn,rlc_pP->channel_id); + + /* Init ReTx Hole list if not configured, ie the whole PDU has to be retransmitted */ + if (pdu_mngt->num_holes == 0) + { + AssertFatal (pdu_mngt->retx_payload_size == pdu_mngt->payload_size,"RLC AM PDU ReTx Segment: Expecting full PDU size ReTxSize=%d DataSize=%d sn=%d vtA=%d vtS=%d LcId=%d !\n", + pdu_mngt->retx_payload_size,pdu_mngt->payload_size,sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); + pdu_mngt->retx_hole_index = 0; + pdu_mngt->hole_so_start[0] = 0; + pdu_mngt->hole_so_stop[0] = pdu_mngt->payload_size - 1; + pdu_mngt->num_holes = 1; + } + + /* Init SO Start and SO Stop */ + retx_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; + retx_so_stop = pdu_mngt->hole_so_stop[pdu_mngt->retx_hole_index]; + + /* Init FI to the same value as original PDU */ + fi_start = (!(RLC_AM_PDU_GET_FI_START(*(pdu_mngt->first_byte)))); + fi_end = (!(RLC_AM_PDU_GET_FI_END(*(pdu_mngt->first_byte)))); + + /* Handle no LI case first */ + if (num_LIs_pdu_segment == 0) + { + /* Bound retx_so_stop to available TBS */ + if (retx_so_stop - retx_so_start + 1 + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE > rlc_pP->nb_bytes_requested_by_mac) + { + retx_so_stop = retx_so_start + rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE - 1; + } + + *payload_sizeP = retx_so_stop - retx_so_start + 1; + mem_pdu_segment_p = get_free_mem_block((*payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + sizeof(struct mac_tb_req)), __func__); + pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; + + /* clear all PDU segment */ + memset(pdu_segment_header_p, 0, *payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE); + /* copy data part */ + memcpy(pdu_segment_header_p + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE, pdu_mngt->payload + retx_so_start, *payload_sizeP); + + /* Set FI part to false if SO Start and SO End are different from PDU boundaries */ + if (retx_so_start) + { + fi_start = FALSE; + } + if (retx_so_stop < pdu_mngt->payload_size - 1) + { + fi_end = FALSE; + } + + /* Header content is filled at the end */ + } + else + { + /* Step 1 */ + /* Find the SDU index in the original PDU containing retx_so_start */ + sdu_size_t sdu_size = 0; + sdu_size_t data_size = 0; + sdu_size_t header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; + pdu_original_header_p = pdu_mngt->first_byte + 2; + li_bit_offset = 4; /* toggle between 0 and 4 */ + li_jump_offset = 1; /* toggle between 1 and 2 */ + + + /* Read first LI */ + sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + pdu_original_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + data_size += sdu_size; + + while ((data_size - 1 < retx_so_start) && (sdu_index < pdu_mngt->nb_sdus)) + { + sdu_index ++; + if (sdu_index < pdu_mngt->nb_sdus) + { + sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + pdu_original_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + data_size += sdu_size; + } + } + + /* Set FI Start if retx_so_start = cumulated data size */ + if (retx_so_start == data_size) + { + fi_start = TRUE; + /* jump to next SDU */ + sdu_index ++; + /* there must be at least one SDU more */ + AssertFatal (sdu_index < pdu_mngt->nb_sdus, "RLC AM PDU Segment Error: sdu_index=%d nb_sdus=%d sn=%d LcId=%d !\n", + sdu_index,pdu_mngt->nb_sdus,sn,rlc_pP->channel_id); + sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + pdu_original_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + data_size += sdu_size; + } + /* Set first SDU portion of the segment */ + sdus_segment_size[0] = data_size - retx_so_start; + + /* Now look for the end */ + while ((data_size - 1 < retx_so_stop) && (sdu_index < pdu_mngt->nb_sdus)) + { + sdu_index ++; + sdu_segment_index ++; + if (sdu_index < pdu_mngt->nb_sdus) + { + sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + pdu_original_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + data_size += sdu_size; + sdus_segment_size[sdu_segment_index] = sdu_size; + } + } + + /* Set FI End if retx_so_stop = cumulated data size */ + if (retx_so_stop == data_size - 1) + { + fi_end = TRUE; + } + /* Set last SDU portion of the segment even if it will be out of LI */ + if (sdu_segment_index) + { + sdus_segment_size[sdu_segment_index] = retx_so_stop - (data_size - sdu_size) + 1; + } + else + { + sdus_segment_size[0] = retx_so_stop - retx_so_start + 1; + } + + /* Set number of LIs in the segment */ + num_LIs_pdu_segment = sdu_segment_index; + + /* Memory allocation taking into account available TBS */ + /* Compute Header Length and Data Length */ + /* Init Segment Payload data size */ + *payload_sizeP = sdus_segment_size[0]; + + /* Bound to available TBS taking into account min PDU segment header*/ + if (*payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE > rlc_pP->nb_bytes_requested_by_mac) + { + *payload_sizeP = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; + } + + sdu_segment_index = 1; + while ((sdu_segment_index < num_LIs_pdu_segment + 1) && (rlc_pP->nb_bytes_requested_by_mac > *payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index))) + { + /* Add next sdu_segment_index to data part */ + if (RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index) + sdus_segment_size[sdu_segment_index] < rlc_pP->nb_bytes_requested_by_mac) + { + (*payload_sizeP) += sdus_segment_size[sdu_segment_index]; + } + else + { + /* bound to available TBS size */ + (*payload_sizeP) += (rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index)); + sdus_segment_size[sdu_segment_index] = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); + } + header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); + sdu_segment_index ++; + } + + num_LIs_pdu_segment = sdu_segment_index - 1; + + /* Check consistency between sdus_segment_size and payload_sizeP */ + data_size = 0; + for (int i = 0; i < num_LIs_pdu_segment + 1; i++) + { + data_size += sdus_segment_size[i]; + } + + AssertFatal (data_size == *payload_sizeP, "RLC AM PDU Segment Data Error: SduSum=%d Data=%d sn=%d LcId=%d !\n", + data_size,*payload_sizeP,sn,rlc_pP->channel_id); + + /* Allocation */ + AssertFatal (header_segment_length + *payload_sizeP <= pdu_mngt->header_and_payload_size + 2, "RLC AM PDU Segment Error: Hdr=%d Data=%d Original Hdr+Data =%d sn=%d LcId=%d !\n", + header_segment_length,*payload_sizeP,pdu_mngt->header_and_payload_size,sn,rlc_pP->channel_id); + mem_pdu_segment_p = get_free_mem_block((*payload_sizeP + header_segment_length + sizeof(struct mac_tb_req)), __func__); + pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; + + /* clear all PDU segment */ + memset(pdu_segment_header_p, 0, *payload_sizeP + header_segment_length); + /* copy data part */ + memcpy(pdu_segment_header_p + header_segment_length, pdu_mngt->payload + retx_so_start, *payload_sizeP); + } + + /* Last step : update contexts and fill PDU Segment Header */ + if (mem_pdu_segment_p != NULL) + { + /* Update PDU Segment contexts */ + if (*payload_sizeP == pdu_mngt->hole_so_stop[pdu_mngt->retx_hole_index] - pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index] + 1) + { + /* All data in the segment are transmitted : switch to next one */ + pdu_mngt->retx_hole_index ++; + if (pdu_mngt->retx_hole_index < pdu_mngt->num_holes) + { + /* Set min SOStart to the value of next hole : assumption is holes are ordered by increasing SOStart */ + pdu_mngt->nack_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; + } + else + { + /* no more scheduled Retx: reset values */ + /* Retx size is reset in the calling function */ + pdu_mngt->num_holes = 0; + pdu_mngt->retx_hole_index = 0; + } + } + else + { + /* not all segment data could be transmitted, just update SoStart */ + pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index] += (*payload_sizeP); + pdu_mngt->nack_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; + } + + /* Set Fixed part of AM PDU Segment Header */ + pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; + + /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ + /* copy first two bytes from original: D/C + RF + FI + E+ SN*/ + *pdu_segment_header_p = *(pdu_mngt->first_byte); + *(pdu_segment_header_p + 1) = *(pdu_mngt->first_byte + 1); + + /* Set Segmentation Flag */ + RLC_AM_PDU_SET_RF(*pdu_segment_header_p); + /* clear polling */ + RLC_AM_PDU_CLEAR_POLL(*pdu_segment_header_p); + /* Change FI */ + if (!fi_start) + { + // Set to not starting + (*pdu_segment_header_p) |= (1 << (RLC_AM_PDU_FI_OFFSET + 1)); + + } + if (!fi_end) + { + // Set to not starting + (*pdu_segment_header_p) |= (1 << (RLC_AM_PDU_FI_OFFSET)); + + } + + /* Segment Offset */ + header_so_part = retx_so_start; + + /* Last Segment Flag (LSF) */ + if (retx_so_stop == pdu_mngt->payload_size - 1) + { + RLC_AM_PDU_SET_LSF(header_so_part); + } + + /* Store SO bytes */ + * (pdu_segment_header_p + 2) = (header_so_part >> 8) & 0xFF; + * (pdu_segment_header_p + 3) = header_so_part & 0xFF; + + /* Fill LI part */ + if (num_LIs_pdu_segment) + { + uint16_t index = 0; + uint16_t temp = 0; + /* Set Extension bit in first byte */ + RLC_AM_PDU_SET_E(*pdu_segment_header_p); + + /* loop on nb of LIs */ + pdu_segment_header_p += RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; + li_bit_offset = 4; /* toggle between 0 and 4 */ + li_jump_offset = 1; /* toggle between 1 and 2 */ + + while (index < num_LIs_pdu_segment) + { + /* Set E bit for next LI if present */ + if (index < num_LIs_pdu_segment - 1) + RLC_SET_BIT(temp,li_bit_offset + RLC_AM_LI_BITS); + /* Set LI */ + RLC_AM_PDU_SET_LI(temp,sdus_segment_size[index],li_bit_offset); + *pdu_segment_header_p = temp >> 8; + *(pdu_segment_header_p + 1) = temp & 0xFF; + pdu_segment_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + + temp = ((*pdu_segment_header_p) << 8) + *(pdu_segment_header_p + 1); + index ++; + } + } + + } + + return mem_pdu_segment_p; +} + +#if 0 //----------------------------------------------------------------------------- mem_block_t* rlc_am_retransmit_get_subsegment( const protocol_ctxt_t* const ctxt_pP, @@ -739,8 +1043,6 @@ mem_block_t* rlc_am_retransmit_get_subsegment( snP); return NULL; } - - rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_sub_segment_p, test_pdu_copy_size,false); return mb_sub_segment_p; } else { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] RE-SEND DATA PDU SN %04d BUT NO PDU AVAILABLE -> RETURN NULL\n", @@ -750,6 +1052,7 @@ mem_block_t* rlc_am_retransmit_get_subsegment( return NULL; } } +#endif //----------------------------------------------------------------------------- void rlc_am_tx_buffer_display ( const protocol_ctxt_t* const ctxt_pP, @@ -803,6 +1106,124 @@ void rlc_am_tx_buffer_display ( LOG_D(RLC, "\n"); } + +//----------------------------------------------------------------------------- +mem_block_t * rlc_am_get_pdu_to_retransmit( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t* const rlc_pP) +{ + rlc_sn_t sn = rlc_pP->vt_a; + rlc_sn_t sn_end = rlc_pP->vt_s; + mem_block_t* pdu_p = NULL; + rlc_am_tx_data_pdu_management_t* tx_data_pdu_management; + + AssertFatal ((rlc_pP->retrans_num_pdus > 0) && (rlc_pP->vt_a != rlc_pP->vt_s), "RLC AM ReTx start process Error: NbPDUtoRetx=%d vtA=%d vtS=%d LcId=%d !\n", + rlc_pP->retrans_num_pdus,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); + + do + { + tx_data_pdu_management = &rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE]; + if ((tx_data_pdu_management->flags.retransmit) && (tx_data_pdu_management->flags.max_retransmit == 0)) + { + AssertFatal (tx_data_pdu_management->sn == sn, "RLC AM ReTx PDU Error: SN Error pdu_sn=%d sn=%d vtA=%d vtS=%d LcId=%d !\n", + tx_data_pdu_management->sn,sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); + AssertFatal (tx_data_pdu_management->flags.transmitted == 1, "RLC AM ReTx PDU Error: State Error sn=%d vtA=%d vtS=%d LcId=%d !\n", + sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); + AssertFatal (tx_data_pdu_management->retx_payload_size > 0, "RLC AM ReTx PDU Error: No Data to Retx sn=%d vtA=%d vtS=%d LcId=%d !\n", + sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); + + /* Either the whole RLC PDU is to be transmitted and there is enough MAC TBS or there is minimum TBS size for transmitting 1 AM PDU segment */ + if ((tx_data_pdu_management->retx_payload_size == tx_data_pdu_management->payload_size) && (rlc_pP->nb_bytes_requested_by_mac >= tx_data_pdu_management->header_and_payload_size)) + { + /* check maxretx is not hit */ + if (tx_data_pdu_management->retx_count_next <= rlc_pP->max_retx_threshold) + { + pdu_p = rlc_am_retransmit_get_copy(ctxt_pP, rlc_pP, sn); + + if (pdu_p != NULL) + { + rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_management->retx_payload_size; + rlc_pP->retrans_num_pdus --; + tx_data_pdu_management->retx_payload_size = 0; + tx_data_pdu_management->flags.retransmit = 0; + + // update stats + rlc_pP->stat_tx_data_pdu += 1; + rlc_pP->stat_tx_retransmit_pdu += 1; + rlc_pP->stat_tx_retransmit_pdu_by_status += 1; + rlc_pP->stat_tx_data_bytes += tx_data_pdu_management->payload_size; + rlc_pP->stat_tx_retransmit_bytes += tx_data_pdu_management->payload_size; + rlc_pP->stat_tx_retransmit_bytes_by_status += tx_data_pdu_management->payload_size; + + } + } + else + { + // TO DO : RLC Notification to RRC + ReEstablishment procedure + tx_data_pdu_management->flags.max_retransmit = 1; + } + } + else if (rlc_pP->nb_bytes_requested_by_mac >= 5) + { + /* Resegmentation case */ + /* check maxretx is not hit */ + if (tx_data_pdu_management->retx_count_next <= rlc_pP->max_retx_threshold) + { + sdu_size_t pdu_data_size = 0; + + pdu_p = rlc_am_retransmit_get_am_segment(ctxt_pP, rlc_pP, tx_data_pdu_management,&pdu_data_size); + + if (pdu_p != NULL) + { + AssertFatal ((tx_data_pdu_management->retx_payload_size >= pdu_data_size) && (rlc_pP->retrans_num_bytes_to_retransmit >= pdu_data_size), "RLC AM ReTx PDU Segment Error: DataSize=%d PDUReTxsize=%d TotalReTxsize=%d sn=%d LcId=%d !\n", + pdu_data_size,tx_data_pdu_management->retx_payload_size,rlc_pP->retrans_num_bytes_to_retransmit,sn,rlc_pP->channel_id); + + tx_data_pdu_management->retx_payload_size -= pdu_data_size; + rlc_pP->retrans_num_bytes_to_retransmit -= pdu_data_size; + if (tx_data_pdu_management->retx_payload_size == 0) + { + rlc_pP->retrans_num_pdus --; + tx_data_pdu_management->retx_payload_size = 0; + tx_data_pdu_management->flags.retransmit = 0; + } + + // update stats + rlc_pP->stat_tx_data_pdu += 1; + rlc_pP->stat_tx_retransmit_pdu += 1; + rlc_pP->stat_tx_retransmit_pdu_by_status += 1; + rlc_pP->stat_tx_data_bytes += pdu_data_size; + rlc_pP->stat_tx_retransmit_bytes += pdu_data_size; + rlc_pP->stat_tx_retransmit_bytes_by_status += pdu_data_size; + + } + } + else + { + // TO DO : RLC Notification to RRC + ReEstablishment procedure + tx_data_pdu_management->flags.max_retransmit = 1; + } + } + + if (pdu_p != NULL) + { + /* check polling */ + rlc_am_pdu_sn_10_t* pdu_header_p = (rlc_am_pdu_sn_10_t*) (&pdu_p->data[sizeof(struct mac_tb_req)]); + rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_header_p, tx_data_pdu_management->payload_size,false); + + tx_data_pdu_management->retx_count = tx_data_pdu_management->retx_count_next; + + break; + } + + } + + sn = RLC_AM_NEXT_SN(sn); + } while((sn != sn_end) && (rlc_pP->retrans_num_pdus > 0)); + + return pdu_p; +} + +#if 0 //----------------------------------------------------------------------------- void rlc_am_retransmit_any_pdu( const protocol_ctxt_t* const ctxt_pP, @@ -891,3 +1312,4 @@ void rlc_am_retransmit_any_pdu( } } } +#endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h index 99570e5d7f..338bc79196 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h @@ -50,21 +50,24 @@ # define public_rlc_am_retransmit(x) extern x # endif # endif -/*! \fn void rlc_am_nack_pdu (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, uint16_t snP, sdu_size_t so_startP, sdu_size_t so_endP) +/*! \fn boolean_t rlc_am_nack_pdu (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, int16_t snP, int16_t prev_nack_snP,sdu_size_t so_startP, sdu_size_t so_endP) * \brief The RLC AM PDU which have the sequence number snP is marked NACKed with segment offset fields. * \param[in] ctxtP Running context. * \param[in] rlcP RLC AM protocol instance pointer. * \param[in] snP Sequence number of the PDU that is negative acknowledged. +* \param[in] prev_nack_snP Sequence number of previous PDU that is negative acknowledged. * \param[in] so_startP Start of the segment offset of the PDU that . * \param[in] so_endP Transport blocks received from MAC layer. +* \return OK/KO * \note It may appear a new hole in the retransmission buffer depending on the segment offset informations. Depending on the state of the retransmission buffer, negative confirmation can be sent to higher layers about the drop by the RLC AM instance of a particular SDU. */ -protected_rlc_am_retransmit(void rlc_am_nack_pdu ( +protected_rlc_am_retransmit(boolean_t rlc_am_nack_pdu ( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, const rlc_sn_t snP, - const sdu_size_t so_startP, - const sdu_size_t so_endP);) + const rlc_sn_t prev_nack_snP, + sdu_size_t so_startP, + sdu_size_t so_endP);) /*! \fn void rlc_am_ack_pdu (const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t *rlcP, rlc_sn_t snP) * \brief The RLC AM PDU which have the sequence number snP is marked ACKed. @@ -90,6 +93,7 @@ protected_rlc_am_retransmit(mem_block_t* rlc_am_retransmit_get_copy ( rlc_am_entity_t *const rlcP, const rlc_sn_t snP)); +#if 0 /*! \fn mem_block_t* rlc_am_retransmit_get_subsegment (const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t *rlcP,rlc_sn_t snP, sdu_size_t *sizeP) * \brief The RLC AM PDU which have the sequence number snP is marked ACKed. * \param[in] ctxtP Running context. @@ -103,7 +107,18 @@ protected_rlc_am_retransmit(mem_block_t* rlc_am_retransmit_get_subsegment ( rlc_am_entity_t *const rlcP, const rlc_sn_t snP, sdu_size_t *const sizeP)); +#endif +/*! \fn mem_block_t* rlc_am_get_pdu_to_retransmit(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* rlcP) +* \brief Find a PDU or PDU segment to retransmit. +* \param[in] ctxtP Running context. +* \param[in] rlcP RLC AM protocol instance pointer. +* \return A copy of the retransmitted PDU or PDU segment or NULL if TBS was not big enough +*/ +protected_rlc_am_retransmit(mem_block_t* rlc_am_get_pdu_to_retransmit( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t* const rlcP);) +#if 0 /*! \fn void rlc_am_retransmit_any_pdu(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* rlcP) * \brief Retransmit any PDU in order to unblock peer entity, if no suitable PDU is found (depending on requested MAC size) to be retransmitted, then try to retransmit a subsegment of any PDU. * \param[in] ctxtP Running context. @@ -112,6 +127,7 @@ protected_rlc_am_retransmit(mem_block_t* rlc_am_retransmit_get_subsegment ( protected_rlc_am_retransmit(void rlc_am_retransmit_any_pdu( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP);) +#endif /*! \fn void rlc_am_tx_buffer_display (const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* rlcP, char* message_pP) * \brief Display the dump of the retransmission buffer. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index 824154b311..27816ccb2c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -113,14 +113,14 @@ void rlc_am_pdu_polling ( rlc_pP->c_byte_without_poll = 0; // vt_s shall have been updated before in case of new transmission - rlc_pP->poll_sn = (rlc_pP->vt_s -1) & RLC_AM_SN_MASK; + rlc_pP->poll_sn = RLC_AM_PREV_SN(rlc_pP->vt_s); //optimisation if (!rlc_pP->t_poll_retransmit.running) { rlc_am_start_timer_poll_retransmit(ctxt_pP, rlc_pP); //optimisation } else { //optimisation rlc_pP->t_poll_retransmit.frame_time_out = ctxt_pP->frame + rlc_pP->t_poll_retransmit.time_out; //optimisation } } else { - // Not sure this is necessary + // Need to clear poll bit as it may be a copy(retransmission case) of the original RLC PDU which was containing a poll RLC_AM_PDU_CLEAR_POLL(pdu_pP->b1); } } @@ -533,16 +533,19 @@ void rlc_am_segment_10 ( pdu_mngt_p->header_and_payload_size = data_pdu_size - pdu_remaining_size; pdu_mngt_p->retx_count = 0; pdu_mngt_p->retx_count_next = 0; + pdu_mngt_p->flags.retransmit = 0; pdu_mngt_p->flags.transmitted = 1; + //TBC: What for resetting local pointers at the end ?? pdu_p = NULL; pdu_mem_p = NULL; //nb_bytes_to_transmit = nb_bytes_to_transmit - data_pdu_size; nb_bytes_to_transmit = 0; // 1 PDU only - mem_block_t* copy = rlc_am_retransmit_get_copy (ctxt_pP, rlc_pP, (rlc_pP->vt_s-1) & RLC_AM_SN_MASK); + /* We need to copy the PDU to pass to MAC in order to keep it in the buffer for potential retransmissions */ + mem_block_t* copy = rlc_am_retransmit_get_copy (ctxt_pP, rlc_pP, RLC_AM_PREV_SN(rlc_pP->vt_s)); list_add_tail_eurecom (copy, &rlc_pP->segmentation_pdu_list); } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 84d587d53b..de23cac006 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -268,6 +268,14 @@ rlc_am_receive_process_control_pdu( { rlc_am_pdu_sn_10_t *rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)*first_byte_ppP; sdu_size_t initial_pdu_size = *tb_size_in_bytes_pP; + rlc_sn_t ack_sn = rlc_pP->control_pdu_info.ack_sn; + rlc_sn_t sn_cursor = rlc_pP->vt_a; + rlc_sn_t vt_a_new = rlc_pP->vt_a; + rlc_sn_t sn_data_cnf; + rlc_sn_t nack_sn,prev_nack_sn; + sdu_size_t data_cnf_so_stop = 0x7FFF; + unsigned int nack_index; + boolean_t status = TRUE; if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_p, tb_size_in_bytes_pP, &rlc_pP->control_pdu_info) >= 0) { @@ -280,10 +288,6 @@ rlc_am_receive_process_control_pdu( rlc_pP->control_pdu_info.ack_sn); rlc_am_display_control_pdu_infos(&rlc_pP->control_pdu_info); - rlc_sn_t ack_sn = rlc_pP->control_pdu_info.ack_sn; - rlc_sn_t sn_cursor = rlc_pP->vt_a; - rlc_sn_t nack_sn; - unsigned int nack_index; // 5.2.1 Retransmission // @@ -308,50 +312,89 @@ rlc_am_receive_process_control_pdu( assert(ack_sn < RLC_AM_SN_MODULO); assert(rlc_pP->control_pdu_info.num_nack < RLC_AM_MAX_NACK_IN_STATUS_PDU); - /* Nv1495998 : ackSn can be equal to current vtA only in case the status pdu contains a list of nack_sn with same value = vtA with SOStart/SOEnd */ + /* Note : ackSn can be equal to current vtA only in case the status pdu contains a list of nack_sn with same value = vtA with SOStart/SOEnd */ /* and meaning the report is not complete due to not enough ressources to fill all SOStart/SOEnd of this NACK_SN */ if (RLC_AM_DIFF_SN(rlc_pP->vt_s,rlc_pP->vt_a) >= RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a)) { if (rlc_pP->control_pdu_info.num_nack == 0) { while (sn_cursor != ack_sn) { rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor); - sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK; + sn_cursor = RLC_AM_NEXT_SN(sn_cursor); } + + vt_a_new = ack_sn; + sn_data_cnf = RLC_AM_PREV_SN(vt_a_new); } else { nack_index = 0; nack_sn = rlc_pP->control_pdu_info.nack_list[nack_index].nack_sn; + prev_nack_sn = 0x3FFF; - while (sn_cursor != ack_sn) { + while (sn_cursor != nack_sn) { + rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor); + sn_cursor = RLC_AM_NEXT_SN(sn_cursor); + } + + vt_a_new = nack_sn; + + // catch DataCfn + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[nack_sn]; + if (tx_data_pdu_buffer_p->retx_payload_size == tx_data_pdu_buffer_p->payload_size) { + sn_data_cnf = RLC_AM_PREV_SN(nack_sn); + } + else if (tx_data_pdu_buffer_p->nack_so_start != 0) { + sn_data_cnf = nack_sn; + data_cnf_so_stop = tx_data_pdu_buffer_p->nack_so_start - 1; + } + else { + sn_data_cnf = RLC_AM_PREV_SN(nack_sn); + } + + + while ((sn_cursor != ack_sn) && (status)) { if (sn_cursor != nack_sn) { rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor); } else { - rlc_am_nack_pdu (ctxt_pP, + status = rlc_am_nack_pdu (ctxt_pP, rlc_pP, - sn_cursor, + nack_sn, + prev_nack_sn, rlc_pP->control_pdu_info.nack_list[nack_index].so_start, rlc_pP->control_pdu_info.nack_list[nack_index].so_end); nack_index = nack_index + 1; + prev_nack_sn = nack_sn; - if (nack_index == rlc_pP->control_pdu_info.num_nack) { - nack_sn = 0xFFFF; // value never reached by sn - } else { - nack_sn = rlc_pP->control_pdu_info.nack_list[nack_index].nack_sn; + if (nack_index < rlc_pP->control_pdu_info.num_nack) { + nack_sn = rlc_pP->control_pdu_info.nack_list[nack_index].nack_sn; + } + else if (nack_sn != ack_sn) { + /* general case*/ + nack_sn = ack_sn; + } + else { + /*specific case when the sender did not have enough TBS to fill all SOStart SOEnd for this NACK_SN */ + break; } } - - if ((nack_index < rlc_pP->control_pdu_info.num_nack) && (nack_index > 0)) { - if (rlc_pP->control_pdu_info.nack_list[nack_index].nack_sn != rlc_pP->control_pdu_info.nack_list[nack_index-1].nack_sn) { - sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK; - } - } else { - sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK; - } + sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK; } } + + } else { + LOG_N(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN OUT OF WINDOW\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + status = FALSE; + } + } else { + LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT" ERROR IN DECODING CONTROL PDU\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + status = FALSE; + } + + if (status) { /* Check for Stopping TpollReTx */ if ((rlc_pP->poll_sn != RLC_SN_UNDEFINED) && (RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a) > RLC_AM_DIFF_SN(rlc_pP->poll_sn,rlc_pP->vt_a))) { @@ -359,15 +402,23 @@ rlc_am_receive_process_control_pdu( rlc_pP->poll_sn = RLC_SN_UNDEFINED; } - /* Update vtA */ + //TODO : this part does not cover all cases of Data Cnf and move it at the end of Status PDU processing + sn_cursor = rlc_pP->vt_a; - } else { - LOG_N(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN OUT OF WINDOW\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); - } - } else { - LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT" ERROR IN DECODING CONTROL PDU\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + /* Handle all acked PDU up to and excluding sn_data_cnf */ + while (sn_cursor != sn_data_cnf) { + rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_cursor); + sn_cursor = RLC_AM_NEXT_SN(sn_cursor); + } + + // Handle last SN. TO DO : case of PDU partially ACKED with SDU to be data conf + if (data_cnf_so_stop == 0x7FFF) { + rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_data_cnf); + } + + /* Update vtA and vtMS */ + rlc_pP->vt_a = vt_a_new; + rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; } *first_byte_ppP = (uint8_t*)((uint64_t)*first_byte_ppP + initial_pdu_size - *tb_size_in_bytes_pP); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h index e2658f2c14..e79dac57c0 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h @@ -113,9 +113,10 @@ typedef struct rlc_am_tx_data_pdu_management { uint8_t retx_hole_index; /*!< \brief Next index of registered holes to retransmit. */ sdu_size_t header_and_payload_size; /*!< \brief Size of the PDU in bytes, including header and payload. */ sdu_size_t payload_size; /*!< \brief Size of the PDU payload in bytes. */ + sdu_size_t retx_payload_size; /*!< \brief Size of the PDU payload to be retransmitted in bytes including all Segment portions. */ rlc_sn_t sn; /*!< \brief Sequence number of the PDU. */ sdu_size_t nack_so_start; /*!< \brief Lowest NACK start segment offset, must be set to 0 if global NACK. */ - sdu_size_t nack_so_stop; /*!< \brief Highest NACK stop segment offset, must be set to data_size if global NACK */ + sdu_size_t nack_so_stop; /*!< \brief Highest NACK stop segment offset, must be set to data_size - 1 if global NACK */ int8_t nb_sdus; /*!< \brief Number of sdu having segments in this pdu. */ int8_t retx_count; /*!< \brief Counts the number of already occurred retransmissions of an AMD PDU (see subclause 5.2.1). */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c index d7079bba9b..29b8fc0971 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c @@ -90,8 +90,12 @@ rlc_am_check_timer_poll_retransmit( sn, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); if ((rlc_pP->tx_data_pdu_buffer[sn].flags.ack == 0) && (rlc_pP->tx_data_pdu_buffer[sn].flags.max_retransmit == 0)) { rlc_pP->tx_data_pdu_buffer[sn].flags.retransmit = 1; + if (rlc_pP->tx_data_pdu_buffer[sn].retx_count == rlc_pP->tx_data_pdu_buffer[sn].retx_count_next) { + rlc_pP->tx_data_pdu_buffer[sn].retx_count_next ++; + } rlc_pP->retrans_num_pdus += 1; rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->tx_data_pdu_buffer[sn].payload_size; + break; } else { From 34ca9a7f93939f974a16065c94ed582429986e75 Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 22 Feb 2017 11:52:01 +0100 Subject: [PATCH 328/571] [OAI-UE] issue#214 fix timing offset compensation --- targets/RT/USER/lte-ue.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 64f8f42d0f..00825c7419 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -731,6 +731,9 @@ void *UE_thread(void *arg) { readBlockSize=UE->frame_parms.samples_per_tti; writeBlockSize=UE->frame_parms.samples_per_tti; } else { + // set TO compensation to zero + UE->rx_offset_diff = 0; + // compute TO compensation that should be applied for this frame if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && UE->rx_offset > 0 ) UE->rx_offset_diff = -1 ; @@ -738,7 +741,7 @@ void *UE_thread(void *arg) { UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) UE->rx_offset_diff = 1; - LOG_D(PHY,"SET rx_off_diff to %d\n",UE->rx_offset_diff); + LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); readBlockSize=UE->frame_parms.samples_per_tti - UE->frame_parms.ofdm_symbol_size - UE->frame_parms.nb_prefix_samples0 - From 0030635237e8899486e708ccef0f3ae779e17486 Mon Sep 17 00:00:00 2001 From: fnabet Date: Wed, 22 Feb 2017 13:00:30 +0100 Subject: [PATCH 329/571] RLC AM Tx buffer: fix sn modulo window size access --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c | 4 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c | 6 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 57 ++++++++++--------- .../RLC/AM_v9.3.0/rlc_am_segments_holes.c | 2 + .../RLC/AM_v9.3.0/rlc_am_segments_holes.h | 3 +- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 6 +- .../AM_v9.3.0/rlc_am_timer_poll_retransmit.c | 14 +++-- 7 files changed, 50 insertions(+), 42 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c index f7ef37597a..b41dea42f2 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c @@ -120,8 +120,8 @@ rlc_am_pdu_sdu_data_cnf( int pdu_sdu_index; int sdu_index; - for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP].nb_sdus; pdu_sdu_index++) { - sdu_index = rlc_pP->tx_data_pdu_buffer[snP].sdus_index[pdu_sdu_index]; + for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].nb_sdus; pdu_sdu_index++) { + sdu_index = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].sdus_index[pdu_sdu_index]; assert(sdu_index >= 0); assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE); rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index 6a36d9b7de..129d4ffb0f 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -175,9 +175,9 @@ rlc_am_cleanup( if (rlc_pP->tx_data_pdu_buffer != NULL) { for (i=0; i < RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE; i++) { - if (rlc_pP->tx_data_pdu_buffer[i].mem_block != NULL) { - free_mem_block(rlc_pP->tx_data_pdu_buffer[i].mem_block, __func__); - rlc_pP->tx_data_pdu_buffer[i].mem_block = NULL; + if (rlc_pP->tx_data_pdu_buffer[i % RLC_AM_WINDOW_SIZE].mem_block != NULL) { + free_mem_block(rlc_pP->tx_data_pdu_buffer[i % RLC_AM_WINDOW_SIZE].mem_block, __func__); + rlc_pP->tx_data_pdu_buffer[i % RLC_AM_WINDOW_SIZE].mem_block = NULL; } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index c636fc7082..85138afed3 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -51,8 +51,8 @@ boolean_t rlc_am_nack_pdu ( // - indicate to upper layers that max retransmission has been reached. - mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; - rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[snP]; + mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block; + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE]; //int pdu_sdu_index; //int sdu_index; boolean_t status = TRUE; @@ -208,23 +208,24 @@ void rlc_am_ack_pdu ( rlc_am_entity_t *const rlc_pP, const rlc_sn_t snP) { - mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; + mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block; + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE]; - rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 0; + tx_data_pdu_buffer->flags.retransmit = 0; - if ((rlc_pP->tx_data_pdu_buffer[snP].flags.ack == 0) && (mb_p != NULL)) { + if ((tx_data_pdu_buffer->flags.ack == 0) && (mb_p != NULL)) { //if (mb_pP != NULL) { free_mem_block(mb_p, __func__); - rlc_pP->tx_data_pdu_buffer[snP].mem_block = NULL; + tx_data_pdu_buffer->mem_block = NULL; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] ACK PDU SN %05d previous retx_count %d \n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP, - rlc_pP->tx_data_pdu_buffer[snP].retx_count); + tx_data_pdu_buffer->retx_count); - if (rlc_pP->tx_data_pdu_buffer[snP].retx_payload_size) { - rlc_pP->retrans_num_bytes_to_retransmit -= rlc_pP->tx_data_pdu_buffer[snP].retx_payload_size; - rlc_pP->tx_data_pdu_buffer[snP].retx_payload_size = 0; - rlc_pP->tx_data_pdu_buffer[snP].num_holes = 0; + if (tx_data_pdu_buffer->retx_payload_size) { + rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_buffer->retx_payload_size; + tx_data_pdu_buffer->retx_payload_size = 0; + tx_data_pdu_buffer->num_holes = 0; rlc_pP->retrans_num_pdus --; } @@ -235,12 +236,12 @@ void rlc_am_ack_pdu ( if (mb_p != NULL) { free_mem_block(mb_p, __func__); - rlc_pP->tx_data_pdu_buffer[snP].mem_block = NULL; + tx_data_pdu_buffer->mem_block = NULL; } } - rlc_pP->tx_data_pdu_buffer[snP].flags.ack = 1; - rlc_pP->tx_data_pdu_buffer[snP].flags.transmitted = 0; - rlc_pP->tx_data_pdu_buffer[snP].flags.retransmit = 0; + tx_data_pdu_buffer->flags.ack = 1; + tx_data_pdu_buffer->flags.transmitted = 0; + tx_data_pdu_buffer->flags.retransmit = 0; } //----------------------------------------------------------------------------- @@ -249,12 +250,12 @@ mem_block_t* rlc_am_retransmit_get_copy ( rlc_am_entity_t *const rlc_pP, const rlc_sn_t snP) { - mem_block_t* mb_original_p = rlc_pP->tx_data_pdu_buffer[snP].mem_block; + mem_block_t* mb_original_p = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block; AssertFatal (mb_original_p != NULL, "RLC AM PDU Copy Error: Empty block sn=%d vtA=%d vtS=%d LcId=%d !\n", snP,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); - rlc_am_tx_data_pdu_management_t *pdu_mngt = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE]; + rlc_am_tx_data_pdu_management_t *pdu_mngt = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE]; /* We need to allocate a new buffer and copy to it because header content may change for Polling bit */ int size = pdu_mngt->header_and_payload_size + sizeof(struct mac_tb_req); @@ -1061,6 +1062,7 @@ void rlc_am_tx_buffer_display ( { rlc_sn_t sn = rlc_pP->vt_a; int i, loop = 0; + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p; if (message_pP) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" Retransmission buffer %s VT(A)=%04d VT(S)=%04d:", @@ -1076,25 +1078,26 @@ void rlc_am_tx_buffer_display ( } while (rlc_pP->vt_s != sn) { - if (rlc_pP->tx_data_pdu_buffer[sn].mem_block) { + tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE]; + if (tx_data_pdu_buffer_p->mem_block) { if ((loop % 1) == 0) { LOG_D(RLC, "\nTX SN:\t"); } - if (rlc_pP->tx_data_pdu_buffer[sn].flags.retransmit) { - LOG_D(RLC, "%04d %d/%d Bytes (NACK RTX:%02d ",sn, rlc_pP->tx_data_pdu_buffer[sn].header_and_payload_size, rlc_pP->tx_data_pdu_buffer[sn].payload_size, - rlc_pP->tx_data_pdu_buffer[sn].retx_count); + if (tx_data_pdu_buffer_p->flags.retransmit) { + LOG_D(RLC, "%04d %d/%d Bytes (NACK RTX:%02d ",sn, tx_data_pdu_buffer_p->header_and_payload_size, tx_data_pdu_buffer_p->payload_size, + tx_data_pdu_buffer_p->retx_count); } else { - LOG_D(RLC, "%04d %d/%d Bytes (RTX:%02d ",sn, rlc_pP->tx_data_pdu_buffer[sn].header_and_payload_size, rlc_pP->tx_data_pdu_buffer[sn].payload_size, - rlc_pP->tx_data_pdu_buffer[sn].retx_count); + LOG_D(RLC, "%04d %d/%d Bytes (RTX:%02d ",sn, tx_data_pdu_buffer_p->header_and_payload_size, tx_data_pdu_buffer_p->payload_size, + tx_data_pdu_buffer_p->retx_count); } - if (rlc_pP->tx_data_pdu_buffer[sn].num_holes == 0) { - LOG_D(RLC, "SO:%04d->%04d)\t", rlc_pP->tx_data_pdu_buffer[sn].nack_so_start, rlc_pP->tx_data_pdu_buffer[sn].nack_so_stop); + if (tx_data_pdu_buffer_p->num_holes == 0) { + LOG_D(RLC, "SO:%04d->%04d)\t", tx_data_pdu_buffer_p->nack_so_start, tx_data_pdu_buffer_p->nack_so_stop); } else { - for (i=0; itx_data_pdu_buffer[sn].num_holes; i++) { + for (i=0; inum_holes; i++) { assert(i < RLC_AM_MAX_HOLES_REPORT_PER_PDU); - LOG_D(RLC, "SO:%04d->%04d)\t", rlc_pP->tx_data_pdu_buffer[sn].hole_so_start[i], rlc_pP->tx_data_pdu_buffer[sn].hole_so_stop[i]); + LOG_D(RLC, "SO:%04d->%04d)\t", tx_data_pdu_buffer_p->hole_so_start[i], tx_data_pdu_buffer_p->hole_so_stop[i]); } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c index b1eabdd1ca..46a656e65a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#if 0 #define RLC_AM_MODULE 1 #define RLC_AM_SEGMENT_HOLES_C 1 //----------------------------------------------------------------------------- @@ -315,3 +316,4 @@ void rlc_am_add_hole ( assert(rlc_pP->tx_data_pdu_buffer[snP].num_holes < RLC_AM_MAX_HOLES_REPORT_PER_PDU); assert(rlc_pP->tx_data_pdu_buffer[snP].nack_so_start < rlc_pP->tx_data_pdu_buffer[snP].payload_size); } +#endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.h index 902bc59306..68200c0f99 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segments_holes.h @@ -32,7 +32,7 @@ * @ingroup _rlc_am_internal_segment_impl_ * @{ */ - +#if 0 #ifndef __RLC_AM_SEGMENT_HOLES_H__ # define __RLC_AM_SEGMENT_HOLES_H__ //----------------------------------------------------------------------------- @@ -108,3 +108,4 @@ protected_rlc_am_segments_holes(void rlc_am_add_hole ( sdu_size_t so_stopP);) /** @} */ #endif +#endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index de23cac006..6d4fd0a2b7 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -268,7 +268,7 @@ rlc_am_receive_process_control_pdu( { rlc_am_pdu_sn_10_t *rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)*first_byte_ppP; sdu_size_t initial_pdu_size = *tb_size_in_bytes_pP; - rlc_sn_t ack_sn = rlc_pP->control_pdu_info.ack_sn; + rlc_sn_t ack_sn = RLC_AM_NEXT_SN(rlc_pP->vt_a); rlc_sn_t sn_cursor = rlc_pP->vt_a; rlc_sn_t vt_a_new = rlc_pP->vt_a; rlc_sn_t sn_data_cnf; @@ -288,7 +288,7 @@ rlc_am_receive_process_control_pdu( rlc_pP->control_pdu_info.ack_sn); rlc_am_display_control_pdu_infos(&rlc_pP->control_pdu_info); - + ack_sn = rlc_pP->control_pdu_info.ack_sn; // 5.2.1 Retransmission // // The transmitting side of an AM RLC entity can receive a negative acknowledgement (notification of reception failure @@ -337,7 +337,7 @@ rlc_am_receive_process_control_pdu( vt_a_new = nack_sn; // catch DataCfn - rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[nack_sn]; + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[nack_sn % RLC_AM_WINDOW_SIZE]; if (tx_data_pdu_buffer_p->retx_payload_size == tx_data_pdu_buffer_p->payload_size) { sn_data_cnf = RLC_AM_PREV_SN(nack_sn); } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c index 29b8fc0971..7c5d55800f 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c @@ -83,18 +83,20 @@ rlc_am_check_timer_poll_retransmit( // force BO to be > 0 rlc_sn_t sn = RLC_AM_PREV_SN(rlc_pP->vt_s); rlc_sn_t sn_end = RLC_AM_PREV_SN(rlc_pP->vt_a); + rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p; /* Look for the first retransmittable PDU starting from vtS - 1 */ while (sn != sn_end) { - AssertFatal (rlc_pP->tx_data_pdu_buffer[sn].mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n", + tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE]; + AssertFatal (tx_data_pdu_buffer_p->mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n", sn, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); - if ((rlc_pP->tx_data_pdu_buffer[sn].flags.ack == 0) && (rlc_pP->tx_data_pdu_buffer[sn].flags.max_retransmit == 0)) { - rlc_pP->tx_data_pdu_buffer[sn].flags.retransmit = 1; - if (rlc_pP->tx_data_pdu_buffer[sn].retx_count == rlc_pP->tx_data_pdu_buffer[sn].retx_count_next) { - rlc_pP->tx_data_pdu_buffer[sn].retx_count_next ++; + if ((tx_data_pdu_buffer_p->flags.ack == 0) && (tx_data_pdu_buffer_p->flags.max_retransmit == 0)) { + tx_data_pdu_buffer_p->flags.retransmit = 1; + if (tx_data_pdu_buffer_p->retx_count == tx_data_pdu_buffer_p->retx_count_next) { + tx_data_pdu_buffer_p->retx_count_next ++; } rlc_pP->retrans_num_pdus += 1; - rlc_pP->retrans_num_bytes_to_retransmit += rlc_pP->tx_data_pdu_buffer[sn].payload_size; + rlc_pP->retrans_num_bytes_to_retransmit += tx_data_pdu_buffer_p->payload_size; break; } else From dcb48081a0b7334919ad89e09d5785697c3ab139 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 23 Feb 2017 08:54:04 +0100 Subject: [PATCH 330/571] Merge remote-tracking branch 'origin/dci_handling_br' into develop_integration_w08 --- openair1/PHY/LTE_TRANSPORT/dci.h | 50 + openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4333 +++++++++-------- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 - .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 3 - openair1/PHY/LTE_TRANSPORT/phich.c | 2 +- openair1/PHY/LTE_TRANSPORT/prach.c | 1 - 6 files changed, 2340 insertions(+), 2051 deletions(-) mode change 100755 => 100644 openair1/PHY/LTE_TRANSPORT/dci_tools.c diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h index 74c150ccab..c250e7c10a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.h +++ b/openair1/PHY/LTE_TRANSPORT/dci.h @@ -2969,3 +2969,53 @@ struct DCI0A_20_MHz { #define sizeof_DCI0A_20MHz 17 #define MAX_DCI_SIZE_BITS 45 + +struct DCI_INFO_EXTRACTED { + /// type = 0 => DCI Format 0, type = 1 => DCI Format 1A + uint8_t type; + /// Resource Allocation Header + uint8_t rah; + /// HARQ Process + uint8_t harq_pid; + /// CQI Request + uint8_t cqi_req; + /// SRS Request + uint8_t srs_req; + /// Power Control + uint8_t TPC; + /// Localized/Distributed VRB + uint8_t vrb_type; + /// RB Assignment (ceil(log2(N_RB_DL/P)) bits) + uint32_t rballoc; + // Applicable only when vrb_type = 1 + uint8_t Ngap; + /// Cyclic shift + uint8_t cshift; + /// Hopping flag + uint8_t hopping; + /// Downlink Assignment Index + uint8_t dai; + /// DAI (TDD) + uint8_t ulindex; + + /// TB swap + uint8_t tb_swap; + /// TPMI information for precoding + uint8_t tpmi; + /// Redundancy version 2 + uint8_t rv2; + /// New Data Indicator 2 + uint8_t ndi2; + /// Modulation and Coding Scheme and Redundancy Version 2 + uint8_t mcs2; + /// Redundancy version 1 + uint8_t rv1; + /// New Data Indicator 1 + uint8_t ndi1; + /// Modulation and Coding Scheme and Redundancy Version 1 + uint8_t mcs1; + + /// Scrambling ID + uint64_t ap_si_nl_id:3; +}; +typedef struct DCI_INFO_EXTRACTED DCI_INFO_EXTRACTED_t; diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c old mode 100755 new mode 100644 index c4dfecf848..7c1fab0350 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -3941,6 +3941,1878 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) } +void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + uint8_t harq_pid=0; + uint32_t rballoc=0; + uint8_t vrb_type=0; + uint8_t mcs=0; + uint8_t rv=0; + uint8_t ndi=0; + uint8_t TPC=0; + + uint8_t dai=0; + + switch (N_RB_DL) { + case 6: + if (frame_type == TDD) { + vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; + // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } + break; + + case 25: + + if (frame_type == TDD) { + vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai; + //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } + + break; + + case 50: + if (frame_type == TDD) { + vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai; + // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, vrb_type %d, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,vrb_type,rballoc,ndi,rv,TPC); + } + break; + + case 100: + if (frame_type == TDD) { + vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; + rv = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv; + ndi = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi; + TPC = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid; + dai = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai; + // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } else { + vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type; + mcs = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv; + ndi = ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi; + TPC = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC; + harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid; + //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); + } + break; + } + + pdci_info_extarcted->vrb_type = vrb_type; + pdci_info_extarcted->mcs1 = mcs; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->rv1 = rv; + pdci_info_extarcted->ndi1 = ndi; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->harq_pid = harq_pid; + pdci_info_extarcted->dai = dai; +} + +void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t mcs=0; + + switch (N_RB_DL) { + case 6: + mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); + + break; + + case 25: + mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); + + break; + + case 50: + mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6); + + break; + + case 100: + mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; + rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6); + break; + + default: + AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",N_RB_DL); + break; + } + + pdci_info_extarcted->mcs1 = mcs; + pdci_info_extarcted->rballoc = rballoc; +} + +void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t mcs=0; + uint8_t rah=0; + uint8_t rv=0; + uint8_t TPC=0; + uint8_t ndi=0; + uint8_t harq_pid=0; + + switch (N_RB_DL) { + case 6: + if (frame_type == TDD) { + mcs = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + + case 25: + if (frame_type == TDD) { + mcs = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + + case 50: + if (frame_type == TDD) { + mcs = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + + case 100: + if (frame_type == TDD) { + mcs = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs; + rballoc = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah; + rv = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv; + TPC = ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid; + } else { + mcs = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs; + rah = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah; + rballoc = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc; + rv = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv; + TPC = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC; + ndi = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi; + harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid; + } + + break; + } + + pdci_info_extarcted->mcs1 = mcs; + pdci_info_extarcted->rah = rah; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->rv1 = rv; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->ndi1 = ndi; + pdci_info_extarcted->harq_pid = harq_pid; + +} + +void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t rah=0; + uint8_t mcs1=0; + uint8_t mcs2=0; + uint8_t rv1=0; + uint8_t rv2=0; + uint8_t ndi1=0; + uint8_t ndi2=0; + uint8_t tbswap=0; + uint8_t tpmi=0; + uint8_t harq_pid=0; + uint8_t TPC=0; + + switch (N_RB_DL) { + + case 6: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + + case 25: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + + case 50: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + + case 100: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; + } else { + rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; + mcs1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; + harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->TPC; + ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; + } + } else { + LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); + } + + break; + } + + pdci_info_extarcted->rah = rah; + pdci_info_extarcted->mcs1 = mcs1; + pdci_info_extarcted->mcs1 = mcs2; + pdci_info_extarcted->rv1 = rv1; + pdci_info_extarcted->rv2 = rv2; + pdci_info_extarcted->harq_pid = harq_pid; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->tb_swap = tbswap; + pdci_info_extarcted->tpmi = tpmi; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->ndi1 = ndi1; + pdci_info_extarcted->ndi2 = ndi2; + +} + +void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) +{ + + uint32_t rballoc=0; + uint8_t rah=0; + uint8_t mcs1=0; + uint8_t mcs2=0; + uint8_t rv1=0; + uint8_t rv2=0; + uint8_t ndi1=0; + uint8_t ndi2=0; + uint8_t tbswap=0; + uint8_t tpmi=0; + uint8_t harq_pid=0; + uint8_t TPC=0; + + AssertFatal( (nb_antenna_ports_eNB == 2) || (nb_antenna_ports_eNB == 4), "unsupported nb_antenna_ports_eNB %d\n", nb_antenna_ports_eNB); + switch (N_RB_DL) { + + case 6: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rv1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + + break; + + case 25: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + break; + + case 50: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + + break; + + case 100: + if (nb_antenna_ports_eNB == 2) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; + TPC = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC; + } + } else if (nb_antenna_ports_eNB == 4) { + if (frame_type == TDD) { + mcs1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->TPC; + } else { + mcs1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1; + mcs2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2; + rballoc = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc; + rah = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah; + rv1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1; + rv2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2; + ndi1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi1; + ndi2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi2; + harq_pid = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; + tbswap = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; + tpmi = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi; + TPC = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->TPC; + } + } + + break; + } + + pdci_info_extarcted->mcs1 = mcs1; + pdci_info_extarcted->mcs2 = mcs2; + pdci_info_extarcted->rballoc = rballoc; + pdci_info_extarcted->rah = rah; + pdci_info_extarcted->rv1 = rv1; + pdci_info_extarcted->rv2 = rv2; + pdci_info_extarcted->ndi1 = ndi1; + pdci_info_extarcted->ndi2 = ndi2; + pdci_info_extarcted->harq_pid = harq_pid; + pdci_info_extarcted->tb_swap = tbswap; + pdci_info_extarcted->TPC = TPC; + pdci_info_extarcted->tpmi = tpmi; +} + +#define DEBUG_DL_DECODING +int check_dci_format1_1a_coherency(DCI_format_t dci_format, + uint8_t N_RB_DL, + uint16_t rnti, + uint16_t tc_rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_UE_HARQ_t *pdlsch0_harq) +{ + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t ndi1 = pdci_info_extarcted->ndi1; + uint8_t TPC = pdci_info_extarcted->TPC; + uint8_t rah = pdci_info_extarcted->rah; + + uint8_t NPRB = 0; + uint32_t RIV_max = 0; + + // I- check dci content minimum coherency + if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0) + { + return(0); + } + + if(harq_pid >8) + { + LOG_I(PHY,"bad harq id \n"); + return(0); + } + + if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) ) + { + LOG_I(PHY,"bad dci format \n"); + return(0); + } + + + if( mcs1 > 28) + { + if(pdlsch0_harq->round == 0) + { + LOG_I(PHY,"bad dci mcs + round \n"); + return(0); + } + + if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + LOG_I(PHY,"bad dci mcs + rnti \n"); + return(0); + } + } + + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + NPRB = (TPC&1) + 2; + switch (N_RB_DL) { + case 6: + RIV_max = RIV_max6; + break; + case 25: + RIV_max = RIV_max25; + break; + case 50: + RIV_max = RIV_max50; + break; + case 100: + RIV_max = RIV_max100; + break; + } + } + else + { + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + RIV_max = RIV_max6; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + RIV_max = RIV_max25; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + RIV_max = RIV_max50; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + RIV_max = RIV_max100; + break; + } + } + + + if(dci_format == format1) + { + NPRB = conv_nprb(rah, rballoc, N_RB_DL); + } + + + if(rballoc > RIV_max) + { + LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %d \n",rballoc, RIV_max); + // DCI false detection + return(0); + } + + if(NPRB == 0) + { + // DCI false detection + LOG_I(PHY,"bad NPRB = 0 \n"); + return(0); + } + + // this a retransmission + if(pdlsch0_harq->round>0) + { + // compare old TBS to new TBS + if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1])) + { + // this is an eNB issue + // retransmisison but old and new TBS are different !!! + // work around, consider it as a new transmission + LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n"); + pdlsch0_harq->round = 0; + //return(0); // ?? to cross check + } + } + + return(1); +} + +int check_dci_format1c_coherency(uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + uint16_t rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + LTE_DL_UE_HARQ_t *pdlsch0_harq) +{ + uint32_t rballoc = pdci_info_extarcted->rballoc; + + uint8_t NPRB = 0; + uint32_t RIV_max = 0; + + // I- check dci content minimum coherency + + if((rnti!=si_rnti) || (rnti!=p_rnti) || (rnti!=ra_rnti)) + return(0); + + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + RIV_max = RIV_max6; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + RIV_max = RIV_max25; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + RIV_max = RIV_max50; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + RIV_max = RIV_max100; + break; + } + + if(rballoc > RIV_max) + { + // DCI false detection + return(0); + } + + if(NPRB == 0) + { + // DCI false detection + return(0); + } + + return(1); +} + +int check_dci_format2_2a_coherency(DCI_format_t dci_format, + uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + uint16_t rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + LTE_DL_UE_HARQ_t *pdlsch0_harq, + LTE_DL_UE_HARQ_t *pdlsch1_harq) +{ + uint8_t rah = pdci_info_extarcted->rah; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t mcs2 = pdci_info_extarcted->mcs1; + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t rv2 = pdci_info_extarcted->rv2; + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t ndi1 = pdci_info_extarcted->ndi1; + uint8_t ndi2 = pdci_info_extarcted->ndi2; + + uint8_t NPRB = 0; + long long RIV_max = 0; + + LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format); + LOG_I(PHY, "extarcted dci - rah %d \n", rah); + LOG_I(PHY, "extarcted dci - mcs1 %d \n", mcs1); + LOG_I(PHY, "extarcted dci - mcs2 %d \n", mcs2); + LOG_I(PHY, "extarcted dci - rv1 %d \n", rv1); + LOG_I(PHY, "extarcted dci - rv2 %d \n", rv2); + LOG_I(PHY, "extarcted dci - ndi1 %d \n", ndi1); + LOG_I(PHY, "extarcted dci - ndi2 %d \n", ndi2); + LOG_I(PHY, "extarcted dci - rballoc %x \n", rballoc); + LOG_I(PHY, "extarcted dci - harq pif %d \n", harq_pid); + LOG_I(PHY, "extarcted dci - round0 %d \n", pdlsch0_harq->round); + LOG_I(PHY, "extarcted dci - round1 %d \n", pdlsch1_harq->round); + + // I- check dci content minimum coherency + if(harq_pid >8) + { + LOG_I(PHY,"bad harq pid\n"); + return(0); + } + + if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) ) + { + LOG_I(PHY,"bad rnti\n"); + return(0); + } + + + if( mcs1 > 28) + { + if(pdlsch0_harq->round == 0) + { + LOG_I(PHY,"bad mcs1\n"); + return(0); + } + } + + if( mcs2 > 28) + { + if(pdlsch1_harq->round == 0) + { + LOG_I(PHY,"bad mcs2\n"); + return(0); + } + + } + + /* + if((pdlsch0_harq->round > 0) && (mcs1 != pdlsch0_harq->mcs)) + { + // DCI false detection + return(0); + }*/ + + + switch (N_RB_DL) { + case 6: + if (rah == 0) + { + //RBG = 1; + RIV_max = 0x3F; + } + else + { + RIV_max = RIV_max6; + } + break; + case 25: + if (rah == 0) + { + //RBG = 2; + RIV_max = 0x1FFF; + } + else + { + RIV_max = RIV_max25; + } + break; + case 50: + if (rah == 0) + { + //RBG = 3; + RIV_max = 0x1FFFF; + } + else + { + RIV_max = RIV_max50; + } + break; + case 100: + if (rah == 0) + { + //RBG = 4; + RIV_max = 0x1FFFFFF; + } + else + { + RIV_max = RIV_max100; + } + break; + } + + NPRB = conv_nprb(rah, + rballoc, + N_RB_DL); + + + + if( (rballoc > RIV_max) && (rah == 1) ) + { + // DCI false detection + LOG_I(PHY,"bad rballoc %d RIV_max %d\n", rballoc, RIV_max); + return(0); + } + + if(NPRB == 0) + { + // DCI false detection + LOG_I(PHY,"bad NPRB\n"); + return(0); + } + + return(1); +} + +void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, + uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + uint16_t rnti, + uint16_t si_rnti, + uint16_t ra_rnti, + uint16_t p_rnti, + LTE_DL_UE_HARQ_t *pdlsch0_harq, + LTE_UE_DLSCH_t *pdlsch0) +{ + + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint8_t vrb_type = pdci_info_extarcted->vrb_type; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t ndi1 = pdci_info_extarcted->ndi1; + uint8_t TPC = pdci_info_extarcted->TPC; + uint8_t rah = pdci_info_extarcted->rah; + uint8_t dai = pdci_info_extarcted->dai; + + uint8_t NPRB = 0; + + if(dci_format == format1A) + { + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + NPRB = (TPC&1) + 2; + } + else + { + switch (N_RB_DL) { + case 6: + NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + break; + case 25: + NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + break; + case 50: + NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + break; + case 100: + NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + break; + } + } + } + else // format1 + { + NPRB = conv_nprb(rah, rballoc, N_RB_DL); + } + + pdlsch0->current_harq_pid = harq_pid; + pdlsch0->active = 1; + pdlsch0->rnti = rnti; + if(dci_format == format1A) + pdlsch0->harq_ack[subframe].vDAI_DL = dai+1; + + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + pdlsch0_harq->round = 0; + pdlsch0_harq->first_tx = 1; + pdlsch0_harq->status = ACTIVE; + } + else //CRNTI + { + // DCI has been toggled or this is the first transmission + if (ndi1!=pdlsch0_harq->DCINdi) + { + pdlsch0_harq->round = 0; + pdlsch0_harq->first_tx = 1; + pdlsch0_harq->status = ACTIVE; + } + + if( ((ndi1 == pdlsch0_harq->DCINdi) && (pdlsch0_harq->round == 0)) || + ((rv1 != 0) && (pdlsch0_harq->round == 0)) + ) + { + LOG_D(PHY,"skip pdsch decoding and report ack\n"); + // skip pdsch decoding and report ack + pdlsch0_harq->status = SCH_IDLE; + pdlsch0->active = 0; + pdlsch0->harq_ack[subframe].ack = 1; + pdlsch0->harq_ack[subframe].harq_id = harq_pid; + pdlsch0->harq_ack[subframe].send_harq_status = 1; + + pdlsch0_harq->first_tx = 0; + } + } + + pdlsch0_harq->DCINdi = ndi1; + pdlsch0_harq->mcs = mcs1; + pdlsch0_harq->rvidx = rv1; + pdlsch0_harq->nb_rb = NPRB; + + pdlsch0_harq->codeword = 0; + pdlsch0_harq->Nl = 1; + pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; + pdlsch0_harq->dl_power_off = 1; //no power offset + pdlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC &3]; + + // compute resource allocation + if(dci_format == format1A) + { + switch (N_RB_DL) { + case 6: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; + } + break; + + case 25: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; + } + break; + + case 50: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; + // printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]); + } else { // DISTRIBUTED + if ((rballoc&(1<<10)) == 0) { + rballoc = rballoc&(~(1<<10)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } + else { + rballoc = rballoc&(~(1<<10)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } + } + break; + + case 100: + if (vrb_type == LOCALIZED) { + pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; + } else { + if ((rballoc&(1<<10)) == 0) { //Gap 1 + rballoc = rballoc&(~(1<<12)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + } + else { //Gap 2 + rballoc = rballoc&(~(1<<12)); + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + } + } + break; + } + } + else // format1 + { + conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,pdlsch0_harq->rb_alloc_even); + pdlsch0_harq->rb_alloc_odd[0]= pdlsch0_harq->rb_alloc_even[0]; + pdlsch0_harq->rb_alloc_odd[1]= pdlsch0_harq->rb_alloc_even[1]; + pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2]; + pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3]; + } + + if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) + { + pdlsch0_harq->TBS = TBStable[mcs1][NPRB-1]; + pdlsch0_harq->Qm = 2; + } + else + { + if(mcs1 < 29) + { + pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB-1]; + pdlsch0_harq->Qm = get_Qm(mcs1); + } + } +} + +void prepare_dl_decoding_format1C(uint8_t N_RB_DL, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_FRAME_PARMS *frame_parms, + uint32_t rnti, + uint32_t si_rnti, + uint32_t ra_rnti, + uint32_t p_rnti, + uint32_t frame, + uint8_t subframe, + LTE_DL_UE_HARQ_t *pdlsch0_harq, + LTE_UE_DLSCH_t *pdlsch0) +{ + + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t Ngap = pdci_info_extarcted->Ngap; + + pdlsch0_harq->round = 0; + pdlsch0_harq->first_tx = 1; + pdlsch0_harq->vrb_type = DISTRIBUTED; + + if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321 + if (((frame&1) == 0) && (subframe == 5)) + pdlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 + else + pdlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs + } + else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3 + pdlsch0_harq->rvidx = 0; + } + + + pdlsch0_harq->Nl = 1; + pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; + pdlsch0_harq->dl_power_off = 1; //no power offset + + pdlsch0_harq->codeword = 0; + pdlsch0_harq->mcs = mcs1; + pdlsch0_harq->TBS = TBStable1C[mcs1]; + pdlsch0_harq->Qm = 2; + + + pdlsch0->current_harq_pid = harq_pid; + pdlsch0->active = 1; + pdlsch0->rnti = rnti; + + switch (N_RB_DL) { + case 6: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; + + break; + + case 25: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; + break; + + case 50: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc]; + if (Ngap == 0) { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; + } + break; + + case 100: + pdlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc]; + if (Ngap==0) { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; + } + else { + pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; + pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; + pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; + pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; + pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; + } + break; + + default: + AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL); + break; + } +} + +void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq) +{ + +switch (tpmi) { + case 0: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); + break; + case 1: + dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); + break; + case 2: // PUSCH precoding + dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; + if (tbswap==0){ + dlsch0_harq->pmi_alloc = pmi_alloc; + dlsch1_harq->pmi_alloc = pmi_alloc^0x1555; + } else { + dlsch1_harq->pmi_alloc = pmi_alloc; + dlsch0_harq->pmi_alloc = pmi_alloc^0x1555; + } + break; + default: + break; + } +} + +void compute_precoding_info_1cw(uint8_t tpmi, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch_harq) +{ + +switch (tpmi) { + case 0 : + dlsch_harq->mimo_mode = ALAMOUTI; + break; + case 1: + dlsch_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); + break; + case 2: + dlsch_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; + case 3: + dlsch_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + break; + case 4: + dlsch_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; + case 5: + dlsch_harq->mimo_mode = PUSCH_PRECODING0; + dlsch_harq->pmi_alloc = pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); + #ifdef DEBUG_HARQ + printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc); + #endif + break; + case 6: + dlsch_harq->mimo_mode = PUSCH_PRECODING1; + dlsch_harq->pmi_alloc = pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); + #ifdef DEBUG_HARQ + printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc); + #endif + break; + } +} + +void compute_precoding_info_format2A(uint8_t tpmi, + uint8_t nb_antenna_ports_eNB, + uint8_t tb0_active, + uint8_t tb1_active, + LTE_DL_UE_HARQ_t *dlsch0_harq, + LTE_DL_UE_HARQ_t *dlsch1_harq) +{ + + dlsch0_harq->dl_power_off = 0; + dlsch1_harq->dl_power_off = 0; + + if (nb_antenna_ports_eNB == 2) { + if ((tb0_active==1) && (tb1_active==1)) { + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + } else { + dlsch0_harq->mimo_mode = ALAMOUTI; + dlsch1_harq->mimo_mode = ALAMOUTI; + } + } else if (nb_antenna_ports_eNB == 4) { // 4 antenna case + if ((tb0_active==1) && (tb1_active==1)) { + switch (tpmi) { + case 0: // one layer per transport block + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + break; + + case 1: // one-layers on TB 0, two on TB 1 + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + break; + + case 2: // two-layers on TB 0, two on TB 1 + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + break; + + case 3: // + LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n"); + break; + } + } else if (tb0_active == 1) { + switch (tpmi) { + case 0: // one layer per transport block + dlsch0_harq->mimo_mode = ALAMOUTI; + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + + case 1: // two-layers on TB 0 + dlsch0_harq->mimo_mode = LARGE_CDD; + dlsch0_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + break; + + case 2: // two-layers on TB 0, two on TB 1 + case 3: // + LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); + break; + } + } else if (tb1_active == 1) { + switch (tpmi) { + case 0: // one layer per transport block + dlsch0_harq->mimo_mode = ALAMOUTI; + dlsch1_harq->mimo_mode = ALAMOUTI; + break; + + case 1: // two-layers on TB 0 + dlsch1_harq->mimo_mode = LARGE_CDD; + dlsch1_harq->Nl = 2; + dlsch0_harq->dl_power_off = 1; + break; + + case 2: // two-layers on TB 0, two on TB 1 + case 3: // + LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); + break; + } + } + } + // printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active); + //printf("UE (%x/%d): Subframe %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, + // dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status); + //printf("TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS); + +} + +void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, + DCI_INFO_EXTRACTED_t *pdci_info_extarcted, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + LTE_DL_UE_HARQ_t *dlsch0_harq, + LTE_DL_UE_HARQ_t *dlsch1_harq, + LTE_UE_DLSCH_t *pdlsch0, + LTE_UE_DLSCH_t *pdlsch1) +{ + + uint8_t rah = pdci_info_extarcted->rah; + uint8_t mcs1 = pdci_info_extarcted->mcs1; + uint8_t mcs2 = pdci_info_extarcted->mcs1; + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t rv2 = pdci_info_extarcted->rv2; + uint8_t harq_pid = pdci_info_extarcted->harq_pid; + uint32_t rballoc = pdci_info_extarcted->rballoc; + uint8_t tbswap = pdci_info_extarcted->tb_swap; + uint8_t tpmi = pdci_info_extarcted->tpmi; + uint8_t TPC = pdci_info_extarcted->TPC; + uint8_t ndi1 = pdci_info_extarcted->ndi1; + uint8_t ndi2 = pdci_info_extarcted->ndi2; + + uint8_t TB0_active = 0; + uint8_t TB1_active = 0; + + + + // check if either TB is disabled (see 36-213 V8.6 p. 26) + TB0_active = 1; + TB1_active = 1; + + if ((rv1 == 1) && (mcs1 == 0)) { + TB0_active=0; + } + if ((rv2 == 1) && (mcs2 == 0)) { + TB1_active=0; + } + + //#ifdef DEBUG_HARQ + printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active); + //#endif + + dlsch0_harq->mcs = mcs1; + dlsch1_harq->mcs = mcs2; + dlsch0_harq->rvidx = rv1; + dlsch1_harq->rvidx = rv2; + dlsch0_harq->DCINdi = ndi1; + dlsch1_harq->DCINdi = ndi2; + + dlsch0_harq->codeword = 0; + dlsch1_harq->codeword = 1; + dlsch0_harq->Nl = 1; + dlsch1_harq->Nl = 1; + dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + dlsch0_harq->dl_power_off = 1; + dlsch1_harq->dl_power_off = 1; + + pdlsch0->current_harq_pid = harq_pid; + pdlsch0->harq_ack[subframe].harq_id = harq_pid; + pdlsch1->current_harq_pid = harq_pid; + pdlsch1->harq_ack[subframe].harq_id = harq_pid; + + // assume two CW are active + dlsch0_harq->status = ACTIVE; + dlsch1_harq->status = ACTIVE; + pdlsch0->active = 1; + pdlsch1->active = 1; + + + if (TB0_active && TB1_active && tbswap==1) { + dlsch0_harq->codeword = 1; + dlsch1_harq->codeword = 0; + } + + if (TB0_active==0) { + dlsch0_harq->status = SCH_IDLE; + pdlsch0->active = 0; + //#ifdef DEBUG_HARQ + printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); + //#endif + } + + if (TB1_active==0) { + dlsch1_harq->status = SCH_IDLE; + pdlsch1->active = 0; + //#ifdef DEBUG_HARQ + printf("[DCI UE]: TB1 is deactivated, retransmit TB0 transmit in TM6\n"); + //#endif + } + + + printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); + + // compute resource allocation + if (TB0_active == 1){ + + dlsch0_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch0_harq->rb_alloc_even); + + dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; + dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; + dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; + dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; + + if (TB1_active == 1){ + dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; + dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0]; + dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1]; + dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; + dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; + + dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + } + } else if ((TB0_active == 0) && (TB1_active == 1)){ + + conv_rballoc(rah, + rballoc, + frame_parms->N_RB_DL, + dlsch1_harq->rb_alloc_even); + + dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3]; + dlsch1_harq->nb_rb = conv_nprb(rah, + rballoc, + frame_parms->N_RB_DL); + } + + + // compute precoding matrix + mimo mode + if(dci_format == format2) + { + if ((TB0_active) && (TB1_active)){ //two CW active + compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq); + } else if ((TB0_active) && (!TB1_active)) { // only CW 0 active + compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq); + } else { + compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch1_harq); + } + //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); + if ((frame_parms->mode1_flag == 1) && (TB0_active)) + dlsch0_harq->mimo_mode = SISO; + } + else + { + compute_precoding_info_format2A( tpmi, + frame_parms->nb_antenna_ports_eNB, + TB0_active, + TB1_active, + dlsch0_harq, + dlsch1_harq); + } + + // reset round + compute Qm + if (TB0_active) { + if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { + dlsch0_harq->round = 0; + + if ( dlsch0_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); + dlsch0_harq->first_tx = 0; + } + }else{ + if(dlsch0_harq->round == 0) { + // skip pdsch decoding and report ack + dlsch0_harq->status = SCH_IDLE; + pdlsch0->active = 0; + pdlsch0->harq_ack[subframe].ack = 1; + pdlsch0->harq_ack[subframe].harq_id = harq_pid; + pdlsch0->harq_ack[subframe].send_harq_status = 1; + } + } + + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + if(dlsch0_harq->Nl == 2) + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; + if (mcs1 <= 28) + dlsch0_harq->Qm = get_Qm(mcs1); + else if (mcs1<=31) + dlsch0_harq->Qm = (mcs1-28)<<1; + } + + if (TB1_active) { + if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { + dlsch1_harq->round = 0; + if (dlsch1_harq->first_tx==1) { + LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); + dlsch1_harq->first_tx = 0; + } + }else{ + if(dlsch1_harq->round == 0) { + // skip pdsch decoding and report ack + dlsch1_harq->status = SCH_IDLE; + pdlsch1->active = 0; + pdlsch1->harq_ack[subframe].ack = 1; + pdlsch1->harq_ack[subframe].harq_id = harq_pid; + pdlsch1->harq_ack[subframe].send_harq_status = 1; + } + } + + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; + if(dlsch0_harq->Nl == 2) + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; + + if (mcs2 <= 28) + dlsch1_harq->Qm = get_Qm(mcs2); + else if (mcs1<=31) + dlsch1_harq->Qm = (mcs2-28)<<1; + } + + printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); + + #ifdef DEBUG_HARQ + if (dlsch0 != NULL && dlsch1 != NULL) + printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status); + else if (dlsch0 == NULL && dlsch1 != NULL) + printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status); + else if (dlsch0 != NULL && dlsch1 == NULL) + printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status); + #endif +} + int generate_ue_dlsch_params_from_dci(int frame, uint8_t subframe, void *dci_pdu, @@ -3956,1758 +5828,414 @@ int generate_ue_dlsch_params_from_dci(int frame, uint16_t tc_rnti) { - uint8_t harq_pid=0; - uint32_t rballoc=0,RIV_max=0; - uint8_t frame_type=frame_parms->frame_type; - uint8_t vrb_type=0; - uint8_t mcs=0,mcs1=0,mcs2=0; - uint8_t rv=0,rv1=0,rv2=0; - uint8_t TB0_active=0,TB1_active=0; - uint8_t ndi=0,ndi1=0,ndi2=0; - uint8_t rah=0; - uint8_t TPC=0; - uint8_t NPRB=0,tbswap=0,tpmi=0; - uint8_t Ngap; - uint8_t dai=0; - LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; - LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; - if (!dlsch[0]) return -1; + uint8_t harq_pid=0; + uint8_t frame_type=frame_parms->frame_type; + uint8_t tpmi=0; + LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; + LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; + DCI_INFO_EXTRACTED_t dci_info_extarcted; + uint8_t status=0; -#ifdef DEBUG_DCI - LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, SFN/SF %d/%d, dci_format %s\n", - rnti, - frame%1024, - subframe, - (dci_format==format0? "Format 0":( - dci_format==format1? "format 1":( - dci_format==format1A? "format 1A":( - dci_format==format1B? "format 1B":( - dci_format==format1C? "format 1C":( - dci_format==format1D? "format 1D":( - dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":( - dci_format==format2? "format 2":( - dci_format==format2A? "format 2A":( - dci_format==format2B? "format 2B":( - dci_format==format2C? "format 2C":( - dci_format==format2D? "format 2D":( - dci_format==format3? "format 3": "UNKNOWN" - )))))))))))))); -#endif - - switch (dci_format) { - - case format0: // This is an ULSCH allocation so nothing here, inform MAC - LOG_E(PHY,"format0 not possible\n"); - return(-1); - break; - - case format1A: if (!dlsch[0]) return -1; - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_type == TDD) { - vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; - // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } + #ifdef DEBUG_DCI + LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, SFN/SF %d/%d, dci_format %s\n", + rnti, + frame%1024, + subframe, + (dci_format==format0? "Format 0":( + dci_format==format1? "format 1":( + dci_format==format1A? "format 1A":( + dci_format==format1B? "format 1B":( + dci_format==format1C? "format 1C":( + dci_format==format1D? "format 1D":( + dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":( + dci_format==format2? "format 2":( + dci_format==format2A? "format 2A":( + dci_format==format2B? "format 2B":( + dci_format==format2C? "format 2C":( + dci_format==format2D? "format 2D":( + dci_format==format3? "format 3": "UNKNOWN" + )))))))))))))); + #endif - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { // - harq_pid = 0; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - // see 36-212 V8.6.0 p. 45 - NPRB = (TPC&1) + 2; - } else { + memset(&dci_info_extarcted,0,sizeof(dci_info_extarcted)); + switch (dci_format) { - if (harq_pid>=8) { - LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - - - NPRB = RIV2nb_rb_LUT6[rballoc]; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - - } - - if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc]; - } - else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; - } - dlsch0_harq->vrb_type = vrb_type; - - - dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc];//NPRB; - RIV_max = RIV_max6; - - break; - - case 25: - - if (frame_type == TDD) { - vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai; - //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } - - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { // - harq_pid = 0; - // see 36-212 V8.6.0 p. 45 - NPRB = (TPC&1) + 2; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - } else { - - if (harq_pid>=8) { - LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - NPRB = RIV2nb_rb_LUT25[rballoc]; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - } - - if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc]; - } - else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; - } - dlsch0_harq->vrb_type = vrb_type; - dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc]; - RIV_max = RIV_max25; - - break; - - case 50: - if (frame_type == TDD) { - vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai; - // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, vrb_type %d, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,vrb_type,rballoc,ndi,rv,TPC); - } - - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { // - harq_pid = 0; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - // see 36-212 V8.6.0 p. 45 - NPRB = (TPC&1) + 2; - } else { - - if (harq_pid>=8) { - LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - NPRB = RIV2nb_rb_LUT50[rballoc]; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - } - - if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; - // printf("rballoc: %08x.%08x\n",dlsch0_harq->rb_alloc_even[0],dlsch0_harq->rb_alloc_even[1]); - } else { // DISTRIBUTED - if ((rballoc&(1<<10)) == 0) { - rballoc = rballoc&(~(1<<10)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } - else { - rballoc = rballoc&(~(1<<10)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } - } - dlsch0_harq->vrb_type = vrb_type; - - dlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc];//NPRB; - RIV_max = RIV_max50; - break; - - case 100: - if (frame_type == TDD) { - vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; - rv = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv; - ndi = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi; - TPC = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid; - dai = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai; - // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } else { - vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type; - mcs = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv; - ndi = ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi; - TPC = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC; - harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid; - //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); - } - - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { // - harq_pid = 0; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - // see 36-212 V8.6.0 p. 45 - NPRB = (TPC&1) + 2; - } else { - - if (harq_pid>=8) { - LOG_E(PHY,"Format 1A: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - NPRB = RIV2nb_rb_LUT100[rballoc]; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - } - - if (vrb_type == LOCALIZED) { - dlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; - } else { - if ((rballoc&(1<<10)) == 0) { //Gap 1 - rballoc = rballoc&(~(1<<12)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; - } - else { //Gap 2 - rballoc = rballoc&(~(1<<12)); - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; - } - } - dlsch0_harq->vrb_type = vrb_type; - - dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc];//NPRB; - RIV_max = RIV_max100; - break; - } - - if (rballoc>RIV_max) { - LOG_E(PHY,"Format 1A: rb_alloc > RIV_max\n"); + case format0: // This is an ULSCH allocation so nothing here, inform MAC + LOG_E(PHY,"format0 not possible\n"); return(-1); - } + break; - if (NPRB==0) { - LOG_E(PHY,"Format 1A: NPRB=0\n"); - return(-1); - } - - if((mcs>28) && ( (dlsch0_harq->round == 0) || (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) )) + case format1A: { - // DCI false detection - return(-1); + // extract dci infomation + extract_dci1A_info(frame_parms->N_RB_DL, + frame_type, + dci_pdu, + &dci_info_extarcted); + + + // check dci content + dlsch0 = dlsch[0]; + dlsch0->active = 0; + dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; + + status = check_dci_format1_1a_coherency(format1A, + frame_parms->N_RB_DL, + rnti, + tc_rnti, + si_rnti, + ra_rnti, + p_rnti, + &dci_info_extarcted, + dlsch0_harq); + if(status == 0) + return(-1); + + // dci is correct ==> update internal structure and prepare dl decoding + prepare_dl_decoding_format1_1A(format1A, + frame_parms->N_RB_DL, + &dci_info_extarcted, + frame_parms, + subframe, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch0); + + + + break; } - if((rv!=0) && (dlsch0_harq->round == 0) && (rnti != si_rnti) && (rnti != p_rnti) && (rnti != ra_rnti)) + case format1C: { - // DCI false detection - return(-1); + // extract dci infomation +#ifdef DEBUG_DL_DECODING + LOG_I(PHY,"[DCI Format-1C] extact dci information \n"); +#endif + extract_dci1C_info(frame_parms->N_RB_DL, + frame_type, + dci_pdu, + &dci_info_extarcted); + + + // check dci content +#ifdef DEBUG_DL_DECODING + LOG_I(PHY,"[DCI Format-1C] check dci content \n"); +#endif + dlsch0 = dlsch[0]; + dlsch0->active = 0; + dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; + + status = check_dci_format1c_coherency(frame_parms->N_RB_DL, + &dci_info_extarcted, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq); + if(status == 0) + return(-1); + + // dci is correct ==> update internal structure and prepare dl decoding +#ifdef DEBUG_DL_DECODING + LOG_I(PHY,"[DCI Format-1C] prepare downlink decoding \n"); +#endif + prepare_dl_decoding_format1C(frame_parms->N_RB_DL, + &dci_info_extarcted, + frame_parms, + rnti, + si_rnti, + ra_rnti, + p_rnti, + frame, + subframe, + dlsch0_harq, + dlsch0); + + break; } - // change the mcs limit from 7 to 8, supported by MAC - /* if (mcs > 10) { - LOG_E(PHY,"Format 1A: subframe %d unlikely mcs for format 1A (%d), TPC %d rv %d\n",subframe,mcs,TPC,rv); - return(-1); - }*/ + case format1: + { + // extract dci infomation + extract_dci1_info(frame_parms->N_RB_DL, + frame_type, + dci_pdu, + &dci_info_extarcted); - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { // - // if ((dlsch0_harq->round == 4) || ( { - dlsch0_harq->round = 0; - dlsch0_harq->first_tx = 1; - // } + // check dci content + dlsch0 = dlsch[0]; + dlsch0->active = 0; + dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; - // if (dlsch0_harq->round == 0) - // ndi = 1-dlsch0_harq->DCINdi; + status = check_dci_format1_1a_coherency(format1, + frame_parms->N_RB_DL, + rnti, + tc_rnti, + si_rnti, + ra_rnti, + p_rnti, + &dci_info_extarcted, + dlsch0_harq); + if(status == 0) + return(-1); + + // dci is correct ==> update internal structure and prepare dl decoding + prepare_dl_decoding_format1_1A(format1, + frame_parms->N_RB_DL, + &dci_info_extarcted, + frame_parms, + subframe, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch0); + break; } - dlsch[0]->current_harq_pid = harq_pid; + case format2: + { + // extract dci infomation + LOG_I(PHY,"[DCI-format2] extract dci infomation \n"); + extract_dci2_info(frame_parms->N_RB_DL, + frame_type, + frame_parms->nb_antenna_ports_eNB, + dci_pdu, + &dci_info_extarcted); - dlsch0_harq->rvidx = rv; - dlsch0_harq->Nl = 1; - // dlsch[0]->layer_index = 0; + // check dci content + dlsch[0]->active = 0; + dlsch[1]->active = 0; - dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; - dlsch0_harq->dl_power_off = 1; //no power offset + if (dci_info_extarcted.tb_swap == 0) { + dlsch0 = dlsch[0]; + dlsch1 = dlsch[1]; + } else { + dlsch0 = dlsch[1]; + dlsch1 = dlsch[0]; + } + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; - dlsch0_harq->codeword=0; + LOG_I(PHY,"[DCI-format2] check dci content \n"); + status = check_dci_format2_2a_coherency(format2, + frame_parms->N_RB_DL, + &dci_info_extarcted, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch1_harq); + if(status == 0) + return(-1); - LOG_D(PHY,"UE (%x/%d): Subframe %d Format1A DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d, round %d\n", - dlsch[0]->rnti, - harq_pid, - subframe, - ndi, - dlsch0_harq->DCINdi, - dlsch0_harq->first_tx, - dlsch0_harq->status, - dlsch0_harq->round); + // dci is correct ==> update internal structure and prepare dl decoding + LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n"); + prepare_dl_decoding_format2_2A(format2, + &dci_info_extarcted, + frame_parms, + subframe, + dlsch0_harq, + dlsch1_harq, + dlsch0, + dlsch1); - dlsch[0]->active = 1; + } + break; - if ((ndi!=dlsch0_harq->DCINdi)|| // DCI has been toggled or this is the first transmission + case format2A: + { + // extract dci infomation + LOG_I(PHY,"[DCI-format2A] extract dci infomation \n"); + extract_dci2A_info(frame_parms->N_RB_DL, + frame_type, + frame_parms->nb_antenna_ports_eNB, + dci_pdu, + &dci_info_extarcted); - (dlsch0_harq->first_tx==1)) { - dlsch0_harq->round = 0; - - if (dlsch0_harq->first_tx==1) { - //LOG_I(PHY,"[PDSCH %x/%d] Format 1A DCI First TX: Clearing flag\n"); - dlsch0_harq->first_tx = 0; - } - } else if (dlsch0_harq->round == 0) { // duplicated PDSCH received. possibly eNB missed the previous DL ACK/NACK feedback - - // skip PDSCH decoding + // check dci content + LOG_I(PHY,"[DCI-format2A] check dci content \n"); + LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid); dlsch[0]->active = 0; - // report ACK back to eNB for this duplicated PDSCH - dlsch0_harq->status = SCH_IDLE; - dlsch0_harq->round = 0; - dlsch[0]->harq_ack[subframe].ack = 1; - dlsch[0]->harq_ack[subframe].harq_id = harq_pid; - dlsch[0]->harq_ack[subframe].send_harq_status = 1; - LOG_D(PHY,"UE (%x/%d): Format1A DCI: Duplicated PDSCH. Setting ACK for subframe %d (pid %d, round 0)\n", - dlsch[0]->rnti,harq_pid, subframe,harq_pid); - } + dlsch[1]->active = 0; - LOG_D(PHY,"UE (%x/%d): SFN/SF %4d/%1d Format1A DCI: dai %d, ndi %d, old_ndi %d (first tx %d), harq_status %d, round %d\n", - rnti, - harq_pid, - frame % 1024, - subframe, - dai, - ndi, - dlsch0_harq->DCINdi, - dlsch0_harq->first_tx, - dlsch0_harq->status, - dlsch0_harq->round); - - if (rnti == tc_rnti) { - dlsch0_harq->DCINdi = (uint8_t)-1; - LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n", - rnti,harq_pid,dlsch0_harq->DCINdi); - } else { - dlsch0_harq->DCINdi = ndi; - } - - dlsch[0]->harq_ack[subframe].vDAI_DL = dai+1; - // this a retransmission - if(dlsch0_harq->round) - { - // compare old TBS to new TBS - if((mcs<29) && (dlsch0_harq->TBS != TBStable[get_I_TBS(mcs)][NPRB-1])) - { - // this is an eNB issue - // retransmisison but old and new TBS are different !!! - // work around, consider it as a new transmission - LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n"); - dlsch0_harq->round = 0; - } - } - - if(mcs<29) - { - dlsch0_harq->mcs = mcs; - } - - if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { - dlsch0_harq->TBS = TBStable[mcs][NPRB-1]; - dlsch0_harq->Qm = 2; - } - else { - if(mcs < 29) - dlsch0_harq->TBS = TBStable[get_I_TBS(mcs)][NPRB-1]; - dlsch0_harq->Qm = get_Qm(mcs); - } - dlsch[0]->rnti = rnti; - dlsch0 = dlsch[0]; - - if (dlsch0_harq->round == 0) - dlsch0_harq->status = ACTIVE; - - //printf("Format 1A: harq_pid %d, nb_rb %d, round %d\n",harq_pid,dlsch0_harq->nb_rb,dlsch0_harq->round); - break; - - case format1C: - if (!dlsch[0]) return -1; - - harq_pid = 0; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - - switch (frame_parms->N_RB_DL) { - case 6: - mcs = ((DCI1C_1_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_1_5MHz_t *)dci_pdu)->rballoc,6); - dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc]; - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; - RIV_max = RIV_max6; - - break; - - case 25: - mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,25); - dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc]; - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; - RIV_max = RIV_max25; - - // printf("Format1C : %x : mcs %d, rballoc %d=>%d=>%x\n",((uint32_t*)dci_pdu)[0], - // mcs,((DCI1C_5MHz_t *)dci_pdu)->rballoc,rballoc,dlsch0_harq->rb_alloc_even[0]); - break; - - case 50: - mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,50); - Ngap = ((DCI1C_10MHz_t *)dci_pdu)->Ngap; - dlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc]; - if (Ngap == 0) { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; - } - else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; - } - RIV_max = RIV_max50; - - break; - - case 100: - mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; - rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,100); - Ngap = ((DCI1C_20MHz_t *)dci_pdu)->Ngap; - dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc]; - if (Ngap==0) { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; - } - else { - dlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; - dlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; - dlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; - dlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; - dlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; - } - RIV_max = RIV_max100; - /* - printf("Format1C : %x : mcs %d, rballoc %d=>%d=>(%08x.%08x.%08x.%08x), Ngap %d\n",((uint32_t*)dci_pdu)[0], - mcs,((DCI1C_20MHz_t *)dci_pdu)->rballoc,rballoc, - dlsch0_harq->rb_alloc_even[0], - dlsch0_harq->rb_alloc_even[1], - dlsch0_harq->rb_alloc_even[2], - dlsch0_harq->rb_alloc_even[3], - Ngap - ); - */ - break; - - default: - LOG_E(PHY,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL); - return(-1); - break; - } - if (rballoc>RIV_max) { - LOG_E(PHY,"Format 1C: rb_alloc > RIV_max\n"); - return(-1); - } - - dlsch0_harq->round = 0; - dlsch0_harq->first_tx = 1; - dlsch0_harq->vrb_type = DISTRIBUTED; - dlsch[0]->current_harq_pid = harq_pid; - - if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321 - if (((frame&1) == 0) && (subframe == 5)) - dlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 - else - dlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3; // other SIBs - } - else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3 - dlsch0_harq->rvidx = 0; - } - - - dlsch0_harq->Nl = 1; - dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; - dlsch0_harq->dl_power_off = 1; //no power offset - - dlsch0_harq->codeword=0; - - LOG_D(PHY,"UE (%x/%d): Subframe %d Format1C DCI: harq_status %d, round %d\n", - dlsch[0]->rnti, - harq_pid, - subframe, - dlsch0_harq->status, - dlsch0_harq->round); - - dlsch0_harq->mcs = mcs; - - dlsch0_harq->TBS = TBStable1C[mcs]; - dlsch0_harq->Qm = 2; - dlsch[0]->rnti = rnti; - dlsch[0]->active = 1; - dlsch0 = dlsch[0]; - break; - - case format1: - if (!dlsch[0]) return -1; - - switch (frame_parms->N_RB_DL) { - case 6: - if (frame_type == TDD) { - mcs = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - - case 25: - if (frame_type == TDD) { - mcs = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - - case 50: - if (frame_type == TDD) { - mcs = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - - case 100: - if (frame_type == TDD) { - mcs = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs; - rballoc = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah; - rv = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv; - TPC = ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid; - } else { - mcs = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs; - rah = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah; - rballoc = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc; - rv = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv; - TPC = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC; - ndi = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi; - harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid; - } - - break; - } - - if (harq_pid>=8) { - LOG_E(PHY,"Format 1: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - - if((mcs>28) && (dlsch0_harq->round == 0) ) - { - // DCI false detection - return(-1); - } - - if((rv!=0) && (dlsch0_harq->round == 0) ) - { - // DCI false detection - return(-1); - } - - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - - dlsch[0]->current_harq_pid = harq_pid; - dlsch[0]->harq_ack[subframe].harq_id = harq_pid; - - conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even); - dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; - - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - - NPRB = dlsch0_harq->nb_rb; - - // printf("test PDSCH NPRB %d, rah %d, rballoc %x, rballoc2 %x\n",NPRB,rah,rballoc,dlsch0_harq->rb_alloc[0]); - - if (NPRB==0) { - LOG_E(PHY,"Format 1: NPRB=0 (rballoc %x,mcs %d, frame_type %d N_RB_DL %d)\n",rballoc,mcs,frame_parms->frame_type,frame_parms->N_RB_DL); - return(-1); - } - - - if (TPC!=1) - LOG_D(PHY,"format1 TPC %d, dlsch0_harq->delta_PUCCH %d\n",TPC,dlsch0_harq->delta_PUCCH); - - dlsch0_harq->rvidx = rv; - - dlsch0_harq->Nl = 1; - // dlsch[0]->layer_index = 0; - - dlsch0_harq->dl_power_off = 1; //no power offset - - dlsch0_harq->codeword=0; - - LOG_D(PHY,"UE (%x/%d): Subframe %d Format1 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, - - dlsch0_harq->first_tx,dlsch0_harq->status); - - if ((ndi!=dlsch0_harq->DCINdi)|| - (dlsch0_harq->first_tx==1)) { - // printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx); - dlsch0_harq->round=0; - dlsch0_harq->DCINdi = ndi; - - dlsch[0]->harq_ack[subframe].send_harq_status = 1; - if (dlsch0_harq->first_tx==1) { - LOG_D(PHY,"[PDSCH %x/%d] Format 1 DCI First TX: Clearing flag\n",rnti,harq_pid); - dlsch0_harq->first_tx = 0; - } - } - - // this a retransmission - if(dlsch0_harq->round) - { - // compare old TBS to new TBS - if(dlsch0_harq->TBS != TBStable[get_I_TBS(mcs)][NPRB-1]) - { - // this is an eNB issue - // retransmisison but old and new TBS are different !!! - // work around, consider it as a new transmission - LOG_E(PHY,"Format1 Retransmission but TBS are different: consider it as new transmission !!! \n"); - dlsch0_harq->round = 0; - } - } - - // printf("test: MCS %d, NPRB %d, TBS %d\n",mcs,NPRB,dlsch0_harq->TBS); - - dlsch[0]->active = 1; - - if (dlsch0_harq->round == 0) { - dlsch0_harq->status = ACTIVE; - // printf("Setting DLSCH process %d to ACTIVE\n",harq_pid); - // MCS and TBS don't change across HARQ rounds - dlsch0_harq->mcs = mcs; - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1]; - - if (mcs <= 28) - dlsch0_harq->Qm = get_Qm(mcs); - else if (mcs<=31) - dlsch0_harq->Qm = (mcs-28)<<1; - else - LOG_E(PHY,"invalid mcs %d\n",mcs); - } - - dlsch[0]->rnti = rnti; - - if (beamforming_mode == 0) - dlsch0_harq->mimo_mode = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI; - else if (beamforming_mode == 7) - dlsch0_harq->mimo_mode = TM7; - else - LOG_E(PHY,"Not supported beamforming mode %d\n",beamforming_mode); - - - dlsch0 = dlsch[0]; - - break; - - case format2: - switch (frame_parms->N_RB_DL) { - - case 6: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi; - } - } - else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } - else { - LOG_E(PHY,"UE: subframe %d Format2 DCI: unsupported number of TX antennas %d\n",subframe,frame_parms->nb_antenna_ports_eNB); - - } - - break; - - case 25: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; - } - } - else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } - - break; - - case 50: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; - } - } - else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } - else { - LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB); - } - - break; - - case 100: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; - } - } - else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; - } - else { - mcs1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } - else { - LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antenna_ports_eNB); - } - - break; - } - - if (harq_pid>=8) { - LOG_E(PHY,"Format 2_2A: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - // check if either TB is disabled (see 36-213 V8.6 p. 26) - TB0_active = 1; - TB1_active = 1; - - if ((rv1 == 1) && (mcs1 == 0)) { - TB0_active=0; - } - if ((rv2 == 1) && (mcs2 == 0)) { - TB1_active=0; - } -#ifdef DEBUG_HARQ - printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active); -#endif - - //printf("RV TB0 = %d\n", rv1); - - - if (TB0_active && TB1_active && tbswap==0) { //dlsch0, dlsch0_harq are at the TB level - dlsch0=dlsch[0]; - dlsch1=dlsch[1]; - dlsch0->active = 1; - dlsch1->active = 1; - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - dlsch0_harq->mcs = mcs1; - dlsch1_harq->mcs = mcs2; - dlsch0_harq->rvidx = rv1; - dlsch1_harq->rvidx = rv2; - dlsch0_harq->status = ACTIVE; - dlsch1_harq->status = ACTIVE; - dlsch0_harq->codeword=0; - dlsch1_harq->codeword=1; -#ifdef DEBUG_HARQ - printf("[DCI UE]: BOTH ACTIVE\n"); -#endif - } - else if (TB0_active && TB1_active && tbswap==1) { - dlsch0=dlsch[0]; - dlsch1=dlsch[1]; - dlsch0->active = 1; - dlsch1->active = 1; - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - dlsch0_harq->mcs = mcs1; - dlsch1_harq->mcs = mcs2; - dlsch0_harq->rvidx = rv1; - dlsch1_harq->rvidx = rv2; - dlsch0_harq->status = ACTIVE; - dlsch1_harq->status = ACTIVE; - dlsch0_harq->codeword=1; - dlsch1_harq->codeword=0; - } - else if (TB0_active && (TB1_active==0)) { - dlsch0=dlsch[0]; - dlsch0->active = 1; - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch0_harq->mcs = mcs1; - dlsch0_harq->rvidx = rv1; - dlsch0_harq->status = ACTIVE; - dlsch0_harq->codeword = 0; - dlsch1=NULL; - dlsch1_harq = NULL; -#ifdef DEBUG_HARQ - printf("[DCI UE]: TB1 is deactivated, retransmit TB0 transmit in TM6\n"); -#endif - } - else if ((TB0_active==0) && TB1_active) { - dlsch1=dlsch[1]; - dlsch1->active = 1; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - dlsch1_harq->mcs = mcs2; - dlsch1_harq->rvidx = rv2; - dlsch1_harq->status = ACTIVE; - dlsch1_harq->codeword = 0; - dlsch0=NULL; - dlsch0_harq = NULL; -#ifdef DEBUG_HARQ - printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); -#endif - } - - - if (dlsch0 != NULL){ - dlsch0->current_harq_pid = harq_pid; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - } - - if (dlsch1 != NULL){ - dlsch1->current_harq_pid = harq_pid; - dlsch1->harq_ack[subframe].harq_id = harq_pid; - } - - if (dlsch0_harq != NULL){ - conv_rballoc(rah, - rballoc, - frame_parms->N_RB_DL, - dlsch0_harq->rb_alloc_even); - - dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; - - if (dlsch1_harq != NULL){ - dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; - dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0]; - dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1]; - dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; - dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; - - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; - } - - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - - } else if ((dlsch0_harq == NULL) && (dlsch1_harq != NULL)){ - - conv_rballoc(rah, - rballoc, - frame_parms->N_RB_DL, - dlsch1_harq->rb_alloc_even); - - dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3]; - dlsch1_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - } - - - if (dlsch0_harq != NULL) { - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - } - - if (dlsch1_harq != NULL) { - dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - } - - // assume one layer per codeword (2 antenna port case) - if (dlsch0_harq != NULL) - dlsch0_harq->Nl = 1; - - if (dlsch1_harq != NULL) - dlsch1_harq->Nl = 1; -#ifdef DEBUG_HARQ - printf ("[DCI UE] tpmi = %d\n", tpmi); -#endif - - - if ((dlsch0 != NULL) && (dlsch1 != NULL)){ //two CW active - dlsch0_harq->dl_power_off = 1; - dlsch1_harq->dl_power_off = 1; - switch (tpmi) { - case 0: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); - break; - case 1: - dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); - break; - case 2: // PUSCH precoding - dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; - if (tbswap==0){ - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; - } else { - dlsch1_harq->pmi_alloc = dlsch0->pmi_alloc; - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc^0x1555; - } - break; - default: - break; - } - } else if ((dlsch0 != NULL) && (dlsch1 == NULL)) { // only CW 0 active - dlsch0_harq->dl_power_off = 1; - switch (tpmi) { - case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); - break; - case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; - case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; - case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; - case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - // we need to extract the first column of precoding matrix (which was computed assuming rank==2) - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); -#ifdef DEBUG_HARQ - printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc); -#endif - break; - case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - // we need to extract the second column of precoding matrix (which was computed assuming rank==2) - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); -#ifdef DEBUG_HARQ - printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc); -#endif - break; -#ifdef DEBUG_HARQ - printf("[DCI UE] harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); -#endif - } - } else { - dlsch1_harq->dl_power_off = 1; - switch (tpmi) { - case 0 : - dlsch1_harq->mimo_mode = ALAMOUTI; - break; - case 1: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); - break; - case 2: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; - case 3: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; - case 4: - dlsch1_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; - case 5: - dlsch1_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch1_harq->pmi_alloc = dlsch1->pmi_alloc; -#ifdef DEBUG_HARQ - printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch1->pmi_alloc); -#endif - - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; - case 6: - dlsch1_harq->mimo_mode = PUSCH_PRECODING1; - dlsch1_harq->pmi_alloc = dlsch1->pmi_alloc; -#ifdef DEBUG_HARQ - printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch1->pmi_alloc); -#endif - return(-1); - break; - } -#ifdef DEBUG_HARQ - printf("[DCI UE] harq1 MIMO mode = %d\n", dlsch1_harq->mimo_mode); -#endif - } - //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); - if ((frame_parms->mode1_flag == 1) && (dlsch0_harq != NULL)) - dlsch0_harq->mimo_mode = SISO; - - - if (dlsch0 != NULL) { - if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { - dlsch0_harq->round = 0; - dlsch0_harq->status = ACTIVE; - dlsch0_harq->DCINdi = ndi1; - - if ( dlsch0_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); - dlsch0_harq->first_tx = 0; - } - } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, - - // this happens if either another harq process in the same - // is NAK or an ACK was not received - - dlsch0->harq_ack[subframe].ack = 1; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch0->harq_ack[subframe].send_harq_status = 1; - dlsch0->active = 0; - } - } - - if ((dlsch1 != NULL) && (dlsch1->active == 1 )) { - if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { - dlsch1_harq->round = 0; - dlsch1_harq->status = ACTIVE; - dlsch1_harq->DCINdi = ndi2; - if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); - dlsch1_harq->first_tx = 0; - } - } - else if ((dlsch1 != NULL) && (dlsch1_harq->status == SCH_IDLE)) { // we got an Ndi = 0 for a previously decoded process, - // this happens if either another harq process in the same - // is NAK or an ACK was not received - - dlsch1->harq_ack[subframe].ack = 1; - dlsch1->harq_ack[subframe].harq_id = harq_pid; - dlsch1->harq_ack[subframe].send_harq_status = 1; - dlsch1->active = 0; - } - } - - if (dlsch0 != NULL){ - if (dlsch0_harq->nb_rb>1) { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - if (mcs1 <= 28) - dlsch0_harq->Qm = get_Qm(mcs1); - else if (mcs1<=31) - dlsch0_harq->Qm = (mcs1-28)<<1; - else - LOG_E(PHY,"invalid mcs1 %d\n",mcs1); - } else - dlsch0_harq->TBS =0; - - dlsch0->rnti = rnti; - } - - if (dlsch1 != NULL) { - if (dlsch1_harq->DCINdi != ndi2) { - dlsch1_harq->round=0; - dlsch1_harq->status = ACTIVE; - } - - dlsch1_harq->DCINdi = ndi2; - - if (dlsch1_harq->nb_rb>1) { - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - if (mcs2 <= 28) - dlsch1_harq->Qm = get_Qm(mcs2); - else if (mcs1<=31) - dlsch1_harq->Qm = (mcs2-28)<<1; - else - LOG_E(PHY,"invalid mcs2 %d\n",mcs2); - } else - dlsch1_harq->TBS = 0; - - dlsch1->rnti = rnti; - } -#ifdef DEBUG_HARQ - if (dlsch0 != NULL && dlsch1 != NULL) - printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status); - else if (dlsch0 == NULL && dlsch1 != NULL) - printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status); - else if (dlsch0 != NULL && dlsch1 == NULL) - printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status); -#endif - - break; - - case format2A: - - switch (frame_parms->N_RB_DL) { - - case 6: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - } else { - mcs1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - } else { - mcs1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rv1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } else { - LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB); - } - - break; - - case 25: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; - } else { - mcs1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi; - } else { - mcs1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } else { - LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB); - } - - break; - - case 50: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; - } else { - mcs1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi; - } else { - mcs1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } else { - LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB); - } - - break; - - case 100: - if (frame_parms->nb_antenna_ports_eNB == 2) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; - } else { - mcs1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { - if (frame_type == TDD) { - mcs1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi; - } else { - mcs1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1; - mcs2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2; - rballoc = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc; - rah = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah; - rv1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1; - rv2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2; - ndi1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi1; - ndi2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi2; - harq_pid = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; - tbswap = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; - tpmi = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi; - } - } else { - LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB); - } - - break; - } - - - if (harq_pid>=8) { - LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - // printf("UE: format 2A, rballoc=%x, harq_pid= %d, mcs1=%d,mcs2=%d, rv1=%d, rv2=%d, ndi1=%d, ndi2=%d\n",rballoc, harq_pid, mcs1,mcs2,rv1,rv2,ndi1,ndi2); - - // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0 - // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated - //Needs to be done in the same manner as TM$. - if (tbswap == 0) { + if (dci_info_extarcted.tb_swap == 0) { dlsch0 = dlsch[0]; dlsch1 = dlsch[1]; } else { dlsch0 = dlsch[1]; dlsch1 = dlsch[0]; } + dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; + dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - dlsch1_harq = dlsch[1]->harq_processes[harq_pid]; - // Needs to be checked - dlsch0_harq->codeword=0; - dlsch1_harq->codeword=1; - dlsch0->current_harq_pid = harq_pid; - dlsch1->current_harq_pid = harq_pid; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch1->harq_ack[subframe].harq_id = harq_pid; - - conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,dlsch0_harq->rb_alloc_even); - dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; - dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; - dlsch1_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_odd[0]; - dlsch1_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_odd[1]; - dlsch1_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_odd[2]; - dlsch1_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_odd[3]; - - dlsch0_harq->nb_rb = conv_nprb(rah, - rballoc, - frame_parms->N_RB_DL); - - dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; - - NPRB = dlsch0_harq->nb_rb; - - - if (NPRB==0) { - LOG_E(PHY,"Format 2A: NPRB=0 (rballoc %x,mcs %d, frame_type %d N_RB_DL %d)\n",rballoc,mcs,frame_parms->frame_type,frame_parms->N_RB_DL); + LOG_I(PHY,"[DCI-format2A] check dci content \n"); + status = check_dci_format2_2a_coherency(format2A, + frame_parms->N_RB_DL, + &dci_info_extarcted, + rnti, + si_rnti, + ra_rnti, + p_rnti, + dlsch0_harq, + dlsch1_harq); + if(status == 0) return(-1); + + // dci is correct ==> update internal structure and prepare dl decoding + LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n"); + prepare_dl_decoding_format2_2A(format2A, + &dci_info_extarcted, + frame_parms, + subframe, + dlsch0_harq, + dlsch1_harq, + dlsch0, + dlsch1); } + break; - // printf("NPRB %d\n",NPRB); - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; - dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3]; + case format1E_2A_M10PRB: + if (!dlsch[0]) return -1; - dlsch0_harq->mcs = mcs1; - dlsch1_harq->mcs = mcs2; + harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; - dlsch0_harq->rvidx = rv1; - dlsch1_harq->rvidx = rv2; + if (harq_pid>=8) { + LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); + return(-1); + } + dlsch[0]->current_harq_pid = harq_pid; + dlsch[0]->harq_ack[subframe].harq_id = harq_pid; - - dlsch0_harq->Nl = 1; - dlsch1_harq->Nl = 1; - // dlsch[0]->layer_index = 0; - - dlsch0_harq->dl_power_off = 1; //no power offset - dlsch1_harq->dl_power_off = 1; //no power offset - - dlsch0->active = dlsch1->active = 1; - - // check if either TB is disabled (see 36-213 V11.3 Section ) - if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { - dlsch0->active = 0; - } - - if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { - dlsch1->active = 0; - } - - - // printf("Format2A DCI (UE, hard pid %d): ndi %d, old_ndi %d (first tx %d)\n",harq_pid,ndi,dlsch0_harq->DCINdi, - // dlsch0_harq->first_tx); - - if (dlsch0->active == 1) { - if ((ndi1!=dlsch0_harq->DCINdi)|| - (dlsch0_harq->first_tx==1)) { - // printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx); - dlsch0_harq->round=0; - dlsch0_harq->status = ACTIVE; - dlsch0_harq->DCINdi = ndi1; - - if (dlsch0_harq->first_tx==1) { - LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX0: Clearing flag\n",rnti,harq_pid); - dlsch0_harq->first_tx = 0; + /* + tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap; + if (tbswap == 0) { + dlsch0 = dlsch[0]; + dlsch1 = dlsch[1]; } + else{ + dlsch0 = dlsch[1]; + dlsch1 = dlsch[0]; + } + */ + dlsch0 = dlsch[0]; + + dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + // Needs to be checked + dlsch0_harq->codeword=0; + conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL, + dlsch0_harq->rb_alloc_even); + + dlsch0_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_even[0]; + dlsch0_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_even[1]; + dlsch0_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_even[2]; + dlsch0_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_even[3]; + /* + dlsch1_harq->rb_alloc_even[0] = dlsch0_harq->rb_alloc_even[0]; + dlsch1_harq->rb_alloc_even[1] = dlsch0_harq->rb_alloc_even[1]; + dlsch1_harq->rb_alloc_even[2] = dlsch0_harq->rb_alloc_even[2]; + dlsch1_harq->rb_alloc_even[3] = dlsch0_harq->rb_alloc_even[3]; + */ + dlsch0_harq->nb_rb = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc, + frame_parms->N_RB_DL); + //dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + + dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; + dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->TPC&3]; + + + + /* + if (dlsch0_harq->mcs>20) { + printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs); + return(-1); + } + */ + + //dlsch1_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2; + dlsch0_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv; + //dlsch1_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2; + + // check if either TB is disabled (see 36-213 V8.6 p. 26) + + if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { + dlsch0_harq->status = DISABLED; + } + + //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { + //dlsch1_harq->status = DISABLED; + //} + dlsch0_harq->Nl = 1; + + //dlsch0->layer_index = tbswap; + //dlsch1->layer_index = 1-tbswap; + + + // Fix this + tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi; + // printf("ue: tpmi %d\n",tpmi); + + switch (tpmi) { + case 0 : + dlsch0_harq->mimo_mode = ALAMOUTI; + break; + + case 1: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); + break; + + case 2: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); + break; + + case 3: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); + + break; + + case 4: + dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; + dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); + break; + + case 5: + dlsch0_harq->mimo_mode = PUSCH_PRECODING0; + // pmi stored from ulsch allocation routine + dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; + //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); + break; + + case 6: + dlsch0_harq->mimo_mode = PUSCH_PRECODING1; + LOG_E(PHY,"Unsupported TPMI\n"); + return(-1); + break; + } + + + if (frame_parms->mode1_flag == 1) + dlsch0_harq->mimo_mode = SISO; + + + if (dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) { + + dlsch0_harq->round = 0; + dlsch0_harq->status = ACTIVE; } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received @@ -5716,364 +6244,81 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0->harq_ack[subframe].harq_id = harq_pid; dlsch0->harq_ack[subframe].send_harq_status = 1; dlsch0->active = 0; - // printf("Got NDI=0 for correctly decoded SDU (harq_pid %d) subframe %d\n",harq_pid,subframe); - + return(0); } - } - if (dlsch1->active == 1) { - if ((ndi2!=dlsch1_harq->DCINdi)|| - (dlsch1_harq->first_tx==1)) { - dlsch1_harq->round=0; - dlsch1_harq->status = ACTIVE; - dlsch1_harq->DCINdi = ndi2; + dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi; + dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; - if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX1: Clearing flag\n",rnti,harq_pid); - dlsch1_harq->first_tx = 0; - } + if (dlsch0_harq->nb_rb>1) { + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + } else + dlsch0_harq->TBS =0; - } else if (dlsch1_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, - // this happens if either another harq process in the same - // is NAK or an ACK was not received + dlsch0->rnti = rnti; + //dlsch1->rnti = rnti; - dlsch1->harq_ack[subframe].ack = 1; - dlsch1->harq_ack[subframe].harq_id = harq_pid; - dlsch1->harq_ack[subframe].send_harq_status = 1; - dlsch1->active = 0; - // printf("Got NDI=0 for correctly decoded SDU (harq_pid %d) subframe %d\n",harq_pid,subframe); - } - } + dlsch0->active = 1; + //dlsch1->active = 1; - if (frame_parms->nb_antenna_ports_eNB == 2) { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1]; + dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; + //dlsch1_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; - - if ((dlsch0->active==1) && (dlsch1->active==1)) { - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - } else { - dlsch0_harq->mimo_mode = ALAMOUTI; - dlsch1_harq->mimo_mode = ALAMOUTI; - } - } else if (frame_parms->nb_antenna_ports_eNB == 4) { // 4 antenna case - if ((dlsch0->active==1) && (dlsch1->active==1)) { - switch (tpmi) { - case 0: // one layer per transport block - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - - break; - - case 1: // one-layers on TB 0, two on TB 1 - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->Nl = 2; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; - break; - - case 2: // two-layers on TB 0, two on TB 1 - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->Nl = 2; - - if (frame_parms->N_RB_DL <= 56) { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; - } else { - LOG_E(PHY,"Add implementation of Table 7.1.7.2.2-1 for two-layer TBS conversion with N_RB_DL > 56\n"); - } - - break; - - case 3: // - LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n"); - break; - } - } else if (dlsch0->active == 1) { - switch (tpmi) { - case 0: // one layer per transport block - dlsch0_harq->mimo_mode = ALAMOUTI; - dlsch1_harq->mimo_mode = ALAMOUTI; - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - break; - - case 1: // two-layers on TB 0 - dlsch0_harq->mimo_mode = LARGE_CDD; - dlsch0_harq->Nl = 2; - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; - break; - - case 2: // two-layers on TB 0, two on TB 1 - case 3: // - LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); - break; - } - } else if (dlsch1->active == 1) { - switch (tpmi) { - case 0: // one layer per transport block - dlsch0_harq->mimo_mode = ALAMOUTI; - dlsch1_harq->mimo_mode = ALAMOUTI; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - break; - - case 1: // two-layers on TB 0 - dlsch1_harq->mimo_mode = LARGE_CDD; - dlsch1_harq->Nl = 2; - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1]; - break; - - case 2: // two-layers on TB 0, two on TB 1 - case 3: // - LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); - break; - } - } - } else { - LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antenna_ports_eNB); - } - - if (mcs1 <= 28) - dlsch0_harq->Qm = get_Qm(mcs1); - else if (mcs1<=31) - dlsch0_harq->Qm = (mcs1-28)<<1; - else - LOG_E(PHY,"invalid mcs1 %d\n",mcs1); - - if (mcs2 <= 28) - dlsch1_harq->Qm = get_Qm(mcs2); - else if (mcs2<=31) - dlsch1_harq->Qm = (mcs2-28)<<1; - else - LOG_E(PHY,"invalid mcs2 %d\n",mcs2); - - // printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active); - //printf("UE (%x/%d): Subframe %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi, - // dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status); - //printf("TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS); - - - break; - - case format1E_2A_M10PRB: - if (!dlsch[0]) return -1; - - harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; - - if (harq_pid>=8) { - LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); - return(-1); - } - - dlsch[0]->current_harq_pid = harq_pid; - dlsch[0]->harq_ack[subframe].harq_id = harq_pid; - - /* - tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap; - if (tbswap == 0) { - dlsch0 = dlsch[0]; - dlsch1 = dlsch[1]; - } - else{ - dlsch0 = dlsch[1]; - dlsch1 = dlsch[0]; - } - */ - dlsch0 = dlsch[0]; - - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - // Needs to be checked - dlsch0_harq->codeword=0; - conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL, - dlsch0_harq->rb_alloc_even); - - dlsch0_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_even[0]; - dlsch0_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_even[1]; - dlsch0_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_even[2]; - dlsch0_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_even[3]; - /* - dlsch1_harq->rb_alloc_even[0] = dlsch0_harq->rb_alloc_even[0]; - dlsch1_harq->rb_alloc_even[1] = dlsch0_harq->rb_alloc_even[1]; - dlsch1_harq->rb_alloc_even[2] = dlsch0_harq->rb_alloc_even[2]; - dlsch1_harq->rb_alloc_even[3] = dlsch0_harq->rb_alloc_even[3]; - */ - dlsch0_harq->nb_rb = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, - ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc, - frame_parms->N_RB_DL); - //dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; - - dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; - dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->TPC&3]; - - - - /* - if (dlsch0_harq->mcs>20) { - printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs); - return(-1); - } - */ - - //dlsch1_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2; - dlsch0_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv; - //dlsch1_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2; - - // check if either TB is disabled (see 36-213 V8.6 p. 26) - - if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { - dlsch0_harq->status = DISABLED; - } - - //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { - //dlsch1_harq->status = DISABLED; - //} - dlsch0_harq->Nl = 1; - - //dlsch0->layer_index = tbswap; - //dlsch1->layer_index = 1-tbswap; - - - // Fix this - tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi; - // printf("ue: tpmi %d\n",tpmi); - - switch (tpmi) { - case 0 : - dlsch0_harq->mimo_mode = ALAMOUTI; - break; - - case 1: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); - break; - - case 2: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); - break; - - case 3: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); - break; - case 4: - dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; - dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); - break; - - case 5: - dlsch0_harq->mimo_mode = PUSCH_PRECODING0; - // pmi stored from ulsch allocation routine - dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; - //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); - break; - - case 6: - dlsch0_harq->mimo_mode = PUSCH_PRECODING1; - LOG_E(PHY,"Unsupported TPMI\n"); + default: + LOG_E(PHY,"format %d not yet implemented\n",dci_format); return(-1); break; } - if (frame_parms->mode1_flag == 1) - dlsch0_harq->mimo_mode = SISO; + #ifdef DEBUG_DCI - - if (dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) { - - dlsch0_harq->round = 0; - dlsch0_harq->status = ACTIVE; - } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process, - // this happens if either another harq process in the same - // is NAK or an ACK was not received - - dlsch0->harq_ack[subframe].ack = 1; - dlsch0->harq_ack[subframe].harq_id = harq_pid; - dlsch0->harq_ack[subframe].send_harq_status = 1; - dlsch0->active = 0; - return(0); + if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { + printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe); + printf("PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti); + printf("PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb); + printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); + printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid); + printf("PDSCH dlsch0 UE: tpc %d\n",TPC); + printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); + printf("PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); + printf("PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); + printf("PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx); + printf("PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS); + printf("PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); + printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); } - dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi; - dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; + #endif - if (dlsch0_harq->nb_rb>1) { - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - } else - dlsch0_harq->TBS =0; - - dlsch0->rnti = rnti; - //dlsch1->rnti = rnti; - - dlsch0->active = 1; - //dlsch1->active = 1; - - dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; - //dlsch1_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; + #if T_TRACER + if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) + { + T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe), T_INT(0), + T_INT(dlsch[0]->rnti), T_INT(dci_format), + T_INT(harq_pid), + T_INT(dlsch0_harq->mcs), + T_INT(dlsch0_harq->TBS)); + } + #endif - break; + // compute DL power control parameters + if (dlsch0_harq != NULL){ + computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); + computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off); + } - default: - LOG_E(PHY,"format %d not yet implemented\n",dci_format); - return(-1); - break; - } + if (dlsch1_harq != NULL) { + computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); + computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off); + } -#ifdef DEBUG_DCI - - if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { - printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe); - printf("PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti); - printf("PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb); - printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); - printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid); - printf("PDSCH dlsch0 UE: tpc %d\n",TPC); - printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); - printf("PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); - printf("PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); - printf("PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx); - printf("PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS); - printf("PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); - printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); - } - -#endif - -#if T_TRACER - if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) - { - T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe), T_INT(0), - T_INT(dlsch[0]->rnti), T_INT(dci_format), - T_INT(harq_pid), - T_INT(dlsch0_harq->mcs), - T_INT(dlsch0_harq->TBS)); - } -#endif - - - // compute DL power control parameters - if (dlsch0_harq != NULL){ - computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); - computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off); - } - - if (dlsch1_harq != NULL) { - computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); - computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off); - } - - - return(0); + return(0); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 3026054994..9112725172 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -2090,7 +2090,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned char aarx=0,symbol_mod,pilots=0; int precoded_signal_strength0=0,precoded_signal_strength1=0; int rx_power_correction; - int output_shift; int **rxdataF_ext = pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext; @@ -3153,7 +3152,6 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned short nb_rb, unsigned char dual_stream_UE) { - unsigned char aatx; int i; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 2906c47e45..91ac860ba7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -697,7 +697,6 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; - int16_t clean_x1[2*frame_parms->N_RB_DL*12]; uint16_t amp_tmp; uint16_t *llr16=(uint16_t*)dlsch_llr; int i, len, nsymb; @@ -953,7 +952,6 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms, { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; - int16_t clean_x1[2*frame_parms->N_RB_DL*12]; uint16_t amp_tmp; uint32_t *llr32=(uint32_t*)dlsch_llr; int i, len, nsymb; @@ -1222,7 +1220,6 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, { int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12]; int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12]; - int16_t clean_x1[2*frame_parms->N_RB_DL*12]; uint16_t amp_tmp; uint16_t *llr32=(uint16_t*)dlsch_llr; int i, len, nsymb, len2; diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index ed3ef923e3..df789cd174 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1395,7 +1395,7 @@ void rx_phich(PHY_VARS_UE *ue, subframe, HI16, nseq_PHICH, - ngroup_PHICH,ulsch->harq_processes[harq_pid]->round+1, + ngroup_PHICH, ulsch->Mlimit); //#endif diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 1555162cb4..bffcd4b23a 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -1133,7 +1133,6 @@ void rx_prach(PHY_VARS_eNB *eNB, int fft_size,log2_ifft_size; uint8_t nb_ant_rx = 1; //eNB->frame_parms.nb_antennas_rx; - int en; for (aa=0; aacommon_vars.rxdata[0][aa][subframe*eNB->frame_parms.samples_per_tti-eNB->N_TA_offset]; From abfeb4ef06633c32f301a06b0adfa37b0df2d214 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 23 Feb 2017 10:49:06 +0100 Subject: [PATCH 331/571] Fix problem in DCI decoding following dci_handling_br branch integration --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 54 ++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index e3fef45815..5fa69b3203 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4756,7 +4756,6 @@ void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb pdci_info_extarcted->tpmi = tpmi; } -#define DEBUG_DL_DECODING int check_dci_format1_1a_coherency(DCI_format_t dci_format, uint8_t N_RB_DL, uint16_t rnti, @@ -4776,7 +4775,19 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, uint8_t rah = pdci_info_extarcted->rah; uint8_t NPRB = 0; - uint32_t RIV_max = 0; + long long int RIV_max = 0; + +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1-1A] dci_format %d\n", dci_format); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti %x\n", rnti); + LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid %d\n", harq_pid); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); + LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); +#endif // I- check dci content minimum coherency if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0) @@ -4835,19 +4846,31 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, switch (N_RB_DL) { case 6: NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; - RIV_max = RIV_max6; + if(rah) + RIV_max = RIV_max6; + else + RIV_max = 0x3F; break; case 25: NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; - RIV_max = RIV_max25; + if(rah) + RIV_max = RIV_max25; + else + RIV_max = 0x1FFF; break; case 50: NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; - RIV_max = RIV_max50; + if(rah) + RIV_max = RIV_max50; + else + RIV_max = 0x1FFFF; break; case 100: NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; - RIV_max = RIV_max100; + if(rah) + RIV_max = RIV_max100; + else + RIV_max = 0x1FFFFFF; break; } } @@ -5871,6 +5894,9 @@ int generate_ue_dlsch_params_from_dci(int frame, case format1A: { // extract dci infomation +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d extarct dci info \n", frame, subframe); +#endif extract_dci1A_info(frame_parms->N_RB_DL, frame_type, dci_pdu, @@ -5881,7 +5907,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0 = dlsch[0]; dlsch0->active = 0; dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; - +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d check dci coherency \n", frame, subframe); +#endif status = check_dci_format1_1a_coherency(format1A, frame_parms->N_RB_DL, rnti, @@ -5895,6 +5923,9 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); // dci is correct ==> update internal structure and prepare dl decoding +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe); +#endif prepare_dl_decoding_format1_1A(format1A, frame_parms->N_RB_DL, &dci_info_extarcted, @@ -5963,6 +5994,9 @@ int generate_ue_dlsch_params_from_dci(int frame, case format1: { // extract dci infomation +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d extarct dci info \n", frame, subframe); +#endif extract_dci1_info(frame_parms->N_RB_DL, frame_type, dci_pdu, @@ -5973,6 +6007,9 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0->active = 0; dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d check dci coherency \n", frame, subframe); +#endif status = check_dci_format1_1a_coherency(format1, frame_parms->N_RB_DL, rnti, @@ -5986,6 +6023,9 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); // dci is correct ==> update internal structure and prepare dl decoding +#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe); +#endif prepare_dl_decoding_format1_1A(format1, frame_parms->N_RB_DL, &dci_info_extarcted, From 60b83d84ea8fb614139d81ef8c7f39df0cb8d786 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 23 Feb 2017 11:01:45 +0100 Subject: [PATCH 332/571] hotfix: pass "%s" to LOG_W to avoid compilation warnings The warning was: ------------------------ In file included from /roux/openairinterface5g/openair2/UTIL/LOG/log.h:306:0, from /roux/openairinterface5g/openair1/PHY/defs.h:54, from /roux/openairinterface5g/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c:33: /roux/openairinterface5g/openair2/UTIL/LOG/log.h: In function 'printMeas': /roux/openairinterface5g/common/utils/T/T.h:94:26: warning: format not a string literal and no format arguments [-Wformat-security] #define T_ID(x) ((struct T_header *)(uintptr_t)(x)) ^ /roux/openairinterface5g/common/utils/T/T.h:29:22: note: in definition of macro 'T_PUT_int' int T_PUT_var = (val); \ ^ /roux/openairinterface5g/common/utils/T/T.h:269:7: note: in expansion of macro 'T_HEADER' T_HEADER(t); \ ^ /roux/openairinterface5g/common/utils/T/T.h:101:76: note: in expansion of macro 'T3' n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n,...) T##n ^ /roux/openairinterface5g/common/utils/T/T.h:102:16: note: in expansion of macro 'TN' #define T(...) TN(__VA_ARGS__) ^ /roux/openairinterface5g/openair2/UTIL/LOG/log.h:308:28: note: in expansion of macro 'T' # define LOG_W(c, x...) T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ^ /roux/openairinterface5g/common/utils/T/T_IDs.h:71:30: note: in expansion of macro 'T_ID' #define T_LEGACY_PHY_WARNING T_ID(68) ^ /roux/openairinterface5g/openair2/UTIL/LOG/log.h:308:30: note: in expansion of macro 'T_LEGACY_PHY_WARNING' # define LOG_W(c, x...) T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ^ /roux/openairinterface5g/openair2/UTIL/LOG/log.h:411:9: note: in expansion of macro 'LOG_W' LOG_W(PHY,txt2); ------------------------ over and over. By replacing LOG_W(PHY,txt2) by LOG_W(PHY,"%s",txt2) all the warnings are removed. --- openair2/UTIL/LOG/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index b31efbcf74..3a67e85d3d 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -408,7 +408,7 @@ static inline void printMeas(char * txt, Meas *M, int period) { M->iterations, M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); - LOG_W(PHY,txt2); + LOG_W(PHY,"%s",txt2); } } From aac9c6119d1fd4dafa07901d2b1bd9b8461af380 Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 23 Feb 2017 17:44:47 +0100 Subject: [PATCH 333/571] RLC AM fix in Retx PDU segment --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 85138afed3..1697b9cac5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -352,6 +352,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( { /* Step 1 */ /* Find the SDU index in the original PDU containing retx_so_start */ + uint16_t temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); sdu_size_t sdu_size = 0; sdu_size_t data_size = 0; sdu_size_t header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; @@ -361,7 +362,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* Read first LI */ - sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); pdu_original_header_p += li_jump_offset; li_bit_offset ^= 0x4; li_jump_offset ^= 0x3; @@ -372,7 +373,8 @@ mem_block_t* rlc_am_retransmit_get_am_segment( sdu_index ++; if (sdu_index < pdu_mngt->nb_sdus) { - sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); + sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); pdu_original_header_p += li_jump_offset; li_bit_offset ^= 0x4; li_jump_offset ^= 0x3; @@ -389,7 +391,8 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* there must be at least one SDU more */ AssertFatal (sdu_index < pdu_mngt->nb_sdus, "RLC AM PDU Segment Error: sdu_index=%d nb_sdus=%d sn=%d LcId=%d !\n", sdu_index,pdu_mngt->nb_sdus,sn,rlc_pP->channel_id); - sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); + sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); pdu_original_header_p += li_jump_offset; li_bit_offset ^= 0x4; li_jump_offset ^= 0x3; @@ -405,7 +408,8 @@ mem_block_t* rlc_am_retransmit_get_am_segment( sdu_segment_index ++; if (sdu_index < pdu_mngt->nb_sdus) { - sdu_size = RLC_AM_PDU_GET_LI(*pdu_original_header_p + *(pdu_original_header_p + 1),li_bit_offset); + temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); + sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); pdu_original_header_p += li_jump_offset; li_bit_offset ^= 0x4; li_jump_offset ^= 0x3; @@ -578,7 +582,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( li_bit_offset ^= 0x4; li_jump_offset ^= 0x3; - temp = ((*pdu_segment_header_p) << 8) + *(pdu_segment_header_p + 1); + temp = ((*pdu_segment_header_p) << 8) | (*(pdu_segment_header_p + 1)); index ++; } } From 3a7fd01f226519c7a5af6412f40fbdd9b54a585e Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Fri, 24 Feb 2017 23:04:05 +0100 Subject: [PATCH 334/571] Fixing dump_dlsch2 --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 8 ++++---- openair1/SCHED/defs.h | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++-- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index a24084e24c..72c572e583 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -5795,7 +5795,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, #ifdef USER_MODE -void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_bits_per_codeword,int round) +void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid) { unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; char fname[32],vname[32]; @@ -5856,12 +5856,12 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_ sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round); sprintf(vname,"dl_rho_r%d_%d",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[round][0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round); sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round); @@ -5869,7 +5869,7 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_ if (ue->frame_parms.nb_antenna_ports_eNB == 2) { sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][round],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); } sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round); diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index b16bbee21f..1316eab941 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -510,7 +510,7 @@ void dump_dlsch(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); -void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, uint16_t coded_bits_per_codeword,int round); +void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid); /*@}*/ diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 8007243a14..af39d92a6b 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2543,7 +2543,7 @@ int main(int argc, char **argv) //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid); write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); @@ -2644,7 +2644,7 @@ int main(int argc, char **argv) } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid); //write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 59091c1e38..b8aeae2123 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -4417,7 +4417,7 @@ int main(int argc, char **argv) UE->frame_parms.ofdm_symbol_size*nsymb,1,1); } //pdsch_vars - dump_dlsch2(UE,eNB_id,coded_bits_per_codeword[0],round,UE->dlsch[0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid); /* write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); From bf6a3b522d04a8c2004b681e6be1d36023141eb4 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Fri, 24 Feb 2017 23:08:12 +0100 Subject: [PATCH 335/571] Removing dlsch1 from arguments of dlsch_modulation_SIC --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 11 ++--------- openair1/PHY/LTE_TRANSPORT/proto.h | 1 - openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 5 +++-- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 3c81085b0e..cbba8b39f1 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -585,8 +585,8 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, int first_layer0; //= dlsch0_harq->first_layer; int Nlayers0; // = dlsch0_harq->Nlayers; - uint8_t mod_order0; // = get_Qm(dlsch0_harq->mcs); - uint8_t mod_order1; //=2; + uint8_t mod_order0=0; // = get_Qm(dlsch0_harq->mcs); + uint8_t mod_order1=0; //=2; uint8_t precoder_index0,precoder_index1; uint8_t *x1=NULL; @@ -2402,17 +2402,12 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, LTE_DL_FRAME_PARMS *frame_parms, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch0, - LTE_eNB_DLSCH_t *dlsch1, int G) { - uint8_t nsymb; uint8_t harq_pid = dlsch0->current_harq_pid; LTE_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid]; - LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid]; uint32_t i,jj,re_allocated=0; - uint16_t l,rb,re_offset, amp; - uint32_t *rb_alloc = dlsch0_harq->rb_alloc; uint8_t mod_order0 = get_Qm(dlsch0_harq->mcs); uint8_t *x0 = dlsch0_harq->e; uint8_t qam64_table_offset_re = 0; @@ -2439,8 +2434,6 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, switch (mod_order0) { case 2: //QPSK - /* TODO: handle more than 1 antenna */ - //printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); ((int16_t*)&sic_buffer[0][i])[0] = (x0[jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 2dbe592377..23ce81a356 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -299,7 +299,6 @@ int32_t dlsch_modulation_SIC(int32_t **sic_buffer, LTE_DL_FRAME_PARMS *frame_parms, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch0, - LTE_eNB_DLSCH_t *dlsch1, int G); /* \brief This function is the top-level routine for generation of the sub-frame signal (frequency-domain) for MCH. diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index b8aeae2123..0f422cfac1 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -193,7 +193,7 @@ int main(int argc, char **argv) unsigned int coded_bits_per_codeword[2],nsymb,dci_cnt,tbs[2]; unsigned int tx_lev=0, tx_lev_dB=0, round=0, trials, errs[2][4]={{0,0,0,0},{0,0,0,0}}, round_trials[2][4]={{0,0,0,0},{0,0,0,0}}, decoded_in_sic[4]={0,0,0,0}, sic_attempt[4]={0,0,0,0}, round_sic=0; - unsigned int dci_errors=0, dlsch_active=0, num_layers; + unsigned int dci_errors=0, dlsch_active=0; unsigned int resend_one[4]={0,0,0,0}, resend_both[4]={0,0,0,0}, TB0_deact[4]={0,0,0,0}, TB1_deact[4]={0,0,0,0}; int re_allocated; @@ -4094,16 +4094,17 @@ int main(int argc, char **argv) &UE->frame_parms, num_pdcch_symbols, &UE->dlsch_eNB[0][0], - NULL, coded_bits_per_codeword[0]); // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1); // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1); + switch (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){ + case 2: dlsch_qpsk_llr_SIC(&UE->frame_parms, From b81ee87f4d24c00ad44fb74f104f8c138bb54bc0 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Fri, 24 Feb 2017 23:33:53 +0100 Subject: [PATCH 336/571] Cleaning up for SIC llrs --- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 212 ++++++++---------- 1 file changed, 97 insertions(+), 115 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 2906c47e45..f7696358ab 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -37,6 +37,9 @@ #include "extern.h" #include "PHY/sse_intrin.h" +//#define DEBUG_LLR_SIC + + int16_t zero[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; int16_t ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; #if defined(__x86_64__) || defined(__i386__) @@ -634,7 +637,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, uint16_t nb_rb, uint16_t pbch_pss_sss_adjust, int16_t **llr32p, - uint8_t beamforming_mode) + uint8_t beamforming_mode) { uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*frame_parms->N_RB_DL*12)]; @@ -702,7 +705,6 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, uint16_t *llr16=(uint16_t*)dlsch_llr; int i, len, nsymb; uint8_t symbol, symbol_mod; - //uint8_t pilots; int len_acc=0; uint16_t *sic_data; uint16_t pbch_pss_sss_adjust; @@ -719,19 +721,17 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) //pilots=1 - amp_tmp=dlsch0->sqrt_rho_b; - else //pilots=0 - amp_tmp=dlsch0->sqrt_rho_a; + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) //pilots=1 + amp_tmp=0x1fff;//dlsch0->sqrt_rho_b; already taken into account + else //pilots=0 + amp_tmp=0x1fff;//1.5*dlsch0->sqrt_rho_a; already taken into account - if (mod_order_0==6) - amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation + if (mod_order_0==6) + amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation to avoid overflow pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,2,subframe,symbol); - // printf("amp_tmp=%d\n", amp_tmp); - if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { if (frame_parms->mode1_flag==0) len = (nb_rb*8) - (2*pbch_pss_sss_adjust/3); @@ -751,26 +751,21 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, 1, len); - - // printf ("Got x0*rho_a\n"); - mult_cpx_vector((int16_t *)rho_1, //Q15 (int16_t *)rho_amp_x0, //Q13 (int16_t*)rho_rho_amp_x0, len, 13); - /* write_output("rho_for_multipl.m","rho_for_multipl", rho_1,len,1, + +#ifdef DEBUG_LLR_SIC + write_output("rho_for_multipl.m","rho_for_m", rho_1,len,1, symbol==num_pdcch_symbols ? 15 : symbol==nsymb-1 ? 14 : 13); write_output("rho_rho_in_llr.m","rho2", rho_rho_amp_x0,len,1, symbol==num_pdcch_symbols ? 15 : symbol==nsymb-1 ? 14 : 13); - // printf ("Computed rho*rho_a*x0\n");*/ - - - //rho_rho_amp_x0_512 = (int16_t)((512*(int16_t *)rho_rho_amp_x0)>>15); - +#endif sub_cpx_vector16((int16_t *)rxF, (int16_t *)rho_rho_amp_x0, @@ -778,23 +773,16 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, (int16_t *)rxF, len*2); - // write_output("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1); - // write_output("clean_x1.m","x1", clean_x1,len,1,1); - // printf ("Interference removed \n"); - /* write_output("clean_x1.m","x1", clean_x1,len,1, - symbol==num_pdcch_symbols ? 15 : - symbol==nsymb-1 ? 14 : 13); - - write_output("rxF_comp1.m","rxF_1_comp", rxF,len,1, - symbol==num_pdcch_symbols ? 15 : - symbol==nsymb-1 ? 14 : 13);*/ - - // printf("dlsch_qpsk_llr_SIC: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); - +#ifdef DEBUG_LLR_SIC + write_output("rxFdata_comp1_after.m","rxF_a", rxF,len,1,1); + write_output("rxF_comp1.m","rxF_1_comp", rxF,len,1, + symbol==num_pdcch_symbols ? 15 : + symbol==nsymb-1 ? 14 : 13); +#endif //this is for QPSK only!!! for (i=0; iNcp))) { + amp_tmp=0x1fff;//dlsch0->sqrt_rho_b; already taken into account + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + } else { + amp_tmp=0x1fff;;//dlsch0->sqrt_rho_a; already taken into account + len = nb_rb*12 - pbch_pss_sss_adjust; + } - if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { - - amp_tmp=dlsch0->sqrt_rho_b; - if (frame_parms->mode1_flag==0) - len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); - else - len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); - } else { - - amp_tmp=dlsch0->sqrt_rho_a; - len = nb_rb*12 - pbch_pss_sss_adjust; - } - - if (mod_order_0==6) - amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation + if (mod_order_0==6) + amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation len_acc+=len; @@ -1248,20 +1232,18 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,6,subframe,symbol); if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) { - - amp_tmp = dlsch0->sqrt_rho_b; - if (frame_parms->mode1_flag==0) - len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); - else - len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); + amp_tmp = 0x1fff;//dlsch0->sqrt_rho_b; already taken into account + if (frame_parms->mode1_flag==0) + len = nb_rb*8 - (2*pbch_pss_sss_adjust/3); + else + len = nb_rb*10 - (5*pbch_pss_sss_adjust/6); } else { - - amp_tmp = dlsch0->sqrt_rho_a; - len = nb_rb*12 - pbch_pss_sss_adjust; + amp_tmp = 0x1fff; //dlsch0->sqrt_rho_a; already taken into account + len = nb_rb*12 - pbch_pss_sss_adjust; } - if (mod_order_0==6) - amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation + if (mod_order_0==6) + amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation len_acc+=len; @@ -1271,93 +1253,93 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms, 1, len); - mult_cpx_vector((int16_t *)rho_1, //Q15 + mult_cpx_vector((int16_t *)rho_1, //Q15 (int16_t *)rho_amp_x0, //Q13 (int16_t*)rho_rho_amp_x0, len, 13); - sub_cpx_vector16((int16_t *)rxF, + sub_cpx_vector16((int16_t *)rxF, (int16_t *)rho_rho_amp_x0, //(int16_t *)clean_x1, (int16_t *)rxF, len*2); - llr2 = llr32; - llr32 += (len*6); + llr2 = llr32; + llr32 += (len*6); - len_mod4 =len&3; - len2=len>>2; // length in quad words (4 REs) - len2+=(len_mod4?0:1); + len_mod4 =len&3; + len2=len>>2; // length in quad words (4 REs) + len2+=(len_mod4?0:1); - for (i=0; i Date: Fri, 24 Feb 2017 23:35:30 +0100 Subject: [PATCH 337/571] Adjusting power level for TM4,5,6. Before that the scaling was aplied in precoder. Now it is done in sqrt_rho_a and sqrt_rho_b. For TM4 there still remains 1/sqrt(2) instead of 1/2 both at the transmitter and receievr side. --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 90 +++++++++++-------- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 82 ++++++++++------- 2 files changed, 103 insertions(+), 69 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 72c572e583..601eacc620 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -107,7 +107,7 @@ int rx_pdsch(PHY_VARS_UE *ue, unsigned char aatx,aarx; - unsigned short nb_rb, round; + unsigned short nb_rb = 0, round; int avgs, rb; LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0; @@ -163,6 +163,10 @@ int rx_pdsch(PHY_VARS_UE *ue, dlsch1_harq = NULL; codeword_TB0 = -1; } + else { + LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe); + return(-1); + } beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]; break; @@ -1552,8 +1556,11 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) #elif defined(__arm__) void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { - __m128i amp; - amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b, + //so removed it + + //__m128i amp; + //amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); switch (pmi) { @@ -1583,8 +1590,8 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { break; } - ch0[0] = _mm_mulhi_epi16(ch0[0],amp); - ch0[0] = _mm_slli_epi16(ch0[0],1); + //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); + //ch0[0] = _mm_slli_epi16(ch0[0],1); _mm_empty(); _m_empty(); @@ -1598,10 +1605,12 @@ short TM3_prec[8]__attribute__((aligned(16))) = {1,1,-1,-1,1,1,-1,-1} ; void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { - // __m128i amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + __m128i amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); __m128i tmp0,tmp1; + // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b, + //so divide by 2 is replaced by divide by sqrt(2). // print_shorts("prec2A_TM3 ch0 (before):",ch0); // print_shorts("prec2A_TM3 ch1 (before):",ch1); @@ -1617,9 +1626,13 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { // print_shorts("prec2A_TM3 ch0 (mid):",&tmp0); // print_shorts("prec2A_TM3 ch1 (mid):",ch1); + ch0[0] = _mm_mulhi_epi16(ch0[0],amp); + ch0[0] = _mm_slli_epi16(ch0[0],1); + ch1[0] = _mm_mulhi_epi16(ch1[0],amp); + ch1[0] = _mm_slli_epi16(ch1[0],1); - ch0[0] = _mm_srai_epi16(ch0[0],1); - ch1[0] = _mm_srai_epi16(ch1[0],1); + // ch0[0] = _mm_srai_epi16(ch0[0],1); + // ch1[0] = _mm_srai_epi16(ch1[0],1); // print_shorts("prec2A_TM3 ch0 (after):",ch0); // print_shorts("prec2A_TM3 ch1 (after):",ch1); @@ -1633,9 +1646,12 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { +// sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b, +//so divide by 2 is replaced by divide by sqrt(2). + // printf ("demod pmi=%d\n", pmi); - // __m128i amp; - // amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + __m128i amp; + amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); __m128i tmp0,tmp1; // print_shorts("prec2A_TM4 ch0 (before):",ch0); @@ -1659,14 +1675,14 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { //print_shorts("prec2A_TM4 ch0 (middle):",ch0); //print_shorts("prec2A_TM4 ch1 (middle):",ch1); - //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); - //ch0[0] = _mm_slli_epi16(ch0[0],1); - //ch1[0] = _mm_mulhi_epi16(ch1[0],amp); - //ch1[0] = _mm_slli_epi16(ch1[0],1); + ch0[0] = _mm_mulhi_epi16(ch0[0],amp); + ch0[0] = _mm_slli_epi16(ch0[0],1); + ch1[0] = _mm_mulhi_epi16(ch1[0],amp); + ch1[0] = _mm_slli_epi16(ch1[0],1); - ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 - ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 + // ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 + // ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 //print_shorts("prec2A_TM4 ch0 (end):",ch0); //print_shorts("prec2A_TM4 ch1 (end):",ch1); _mm_empty(); @@ -2086,7 +2102,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned char aarx=0,symbol_mod,pilots=0; int precoded_signal_strength0=0,precoded_signal_strength1=0; int rx_power_correction; - int output_shift; int **rxdataF_ext = pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext; @@ -3149,7 +3164,6 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned short nb_rb, unsigned char dual_stream_UE) { - unsigned char aatx; int i; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; @@ -3806,7 +3820,7 @@ void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext, #endif } - +//#define ONE_OVER_2_Q15 16384 void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp, int **dl_ch_mag, @@ -3825,9 +3839,9 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, uint8_t pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0; rxF0_128 = (__m128i*) &rxdataF_comp[0][jj]; - //amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); //amp = _mm_set1_epi16(ONE_OVER_2_Q15); + // printf("Doing alamouti!\n"); rxF0 = (short*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y rxF1 = (short*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y @@ -3863,29 +3877,33 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, ch_mag0b[1] = _mm_adds_epi16(ch_mag0b[1],ch_mag1b[1]); // account for 1/sqrt(2) scaling at transmission - /* - ch_mag0[0] = _mm_srai_epi16(ch_mag0[0],1); - ch_mag0[1] = _mm_srai_epi16(ch_mag0[1],1); - ch_mag0b[0] = _mm_srai_epi16(ch_mag0b[0],1); - ch_mag0b[1] = _mm_srai_epi16(ch_mag0b[1],1); + //ch_mag0[0] = _mm_srai_epi16(ch_mag0[0],1); + //ch_mag0[1] = _mm_srai_epi16(ch_mag0[1],1); + //ch_mag0b[0] = _mm_srai_epi16(ch_mag0b[0],1); + //ch_mag0b[1] = _mm_srai_epi16(ch_mag0b[1],1); + + //rxF0_128[0] = _mm_mulhi_epi16(rxF0_128[0],amp); + //rxF0_128[0] = _mm_slli_epi16(rxF0_128[0],1); + //rxF0_128[1] = _mm_mulhi_epi16(rxF0_128[1],amp); + //rxF0_128[1] = _mm_slli_epi16(rxF0_128[1],1); + + //rxF0_128[0] = _mm_srai_epi16(rxF0_128[0],1); + //rxF0_128[1] = _mm_srai_epi16(rxF0_128[1],1); + - rxF0_128[0] = _mm_mulhi_epi16(rxF0_128[0],amp); - rxF0_128[0] = _mm_slli_epi16(rxF0_128[0],1); - rxF0_128[1] = _mm_mulhi_epi16(rxF0_128[1],amp); - rxF0_128[1] = _mm_slli_epi16(rxF0_128[1],1); - */ if (pilots==0) { ch_mag0[2] = _mm_adds_epi16(ch_mag0[2],ch_mag1[2]); ch_mag0b[2] = _mm_adds_epi16(ch_mag0b[2],ch_mag1b[2]); - /* - ch_mag0[2] = _mm_srai_epi16(ch_mag0[2],1); - ch_mag0b[2] = _mm_srai_epi16(ch_mag0b[2],1); + //ch_mag0[2] = _mm_srai_epi16(ch_mag0[2],1); + //ch_mag0b[2] = _mm_srai_epi16(ch_mag0b[2],1); + + //rxF0_128[2] = _mm_mulhi_epi16(rxF0_128[2],amp); + //rxF0_128[2] = _mm_slli_epi16(rxF0_128[2],1); + + //rxF0_128[2] = _mm_srai_epi16(rxF0_128[2],1); - rxF0_128[2] = _mm_mulhi_epi16(rxF0_128[2],amp); - rxF0_128[2] = _mm_slli_epi16(rxF0_128[2],1); - */ ch_mag0+=3; ch_mag1+=3; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index cbba8b39f1..ac722fef60 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1136,13 +1136,24 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, *jj = *jj + 1; //normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + /*((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + }*/ + + // We remove ONE_OVER_SQRT2_Q15 that was coming from precoder, as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function + + ((int16_t*)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t*)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; + + if (frame_parms->nb_antenna_ports_eNB == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; } break; @@ -1171,13 +1182,13 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; if (frame_parms->nb_antennas_tx == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; } break; @@ -1208,13 +1219,13 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[0] += ((int16_t*)&tmp_sample1)[0]; + ((int16_t *)&txdataF[0][tti_offset])[1] += ((int16_t*)&tmp_sample1)[1]; if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; + ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; } break; @@ -1246,15 +1257,18 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, *jj = *jj + 1; //normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + // We remove ONE_OVER_2_Q15 that was coming from precoder, + //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function + //ONE_OVER_SQRT2_Q15 remains from it + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); //printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; @@ -1280,13 +1294,17 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam16_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + + // We remove ONE_OVER_2_Q15 that was coming from precoder, + //as now it applied in computation sqrt_rho_a, sqrt_rho_b, same in the receiver in precoder function + //ONE_OVER_SQRT2_Q15 remains from it + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; @@ -1317,8 +1335,8 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s0[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s0[qam64_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); @@ -1340,13 +1358,13 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, *jj2 = *jj2 + 1; //normalization for 2 tx antennas - ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB== 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; @@ -1373,13 +1391,13 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam16_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam16_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; @@ -1409,13 +1427,13 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t*)&tmp_sample1)[0] = (int16_t)((qam_table_s1[qam64_table_offset_re])); ((int16_t*)&tmp_sample1)[1] = (int16_t)((qam_table_s1[qam64_table_offset_im])); - ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); if (frame_parms->nb_antenna_ports_eNB == 2) { layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index1); - ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_2_Q15)>>15); - ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; @@ -2422,9 +2440,7 @@ int dlsch_modulation_SIC(int32_t **sic_buffer, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_IN); - amp=1; //we do full scale here for SIC gain_lin_QPSK = (int16_t)((ONE_OVER_SQRT2_Q15)); - //printf("gain=%d\n", gain_lin_QPSK); jj = 0; i = 0; From 2edbcbdf660d1f56675e905fc17b2c8564955da3 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Tue, 28 Feb 2017 16:17:48 +0100 Subject: [PATCH 338/571] bugfix: fix copy/paste error mcs1 was taken instead of mcs2 in several places. --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 5fa69b3203..bc617b23e7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4478,7 +4478,7 @@ void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_ pdci_info_extarcted->rah = rah; pdci_info_extarcted->mcs1 = mcs1; - pdci_info_extarcted->mcs1 = mcs2; + pdci_info_extarcted->mcs2 = mcs2; pdci_info_extarcted->rv1 = rv1; pdci_info_extarcted->rv2 = rv2; pdci_info_extarcted->harq_pid = harq_pid; @@ -4978,7 +4978,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, { uint8_t rah = pdci_info_extarcted->rah; uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t mcs2 = pdci_info_extarcted->mcs1; + uint8_t mcs2 = pdci_info_extarcted->mcs2; uint8_t rv1 = pdci_info_extarcted->rv1; uint8_t rv2 = pdci_info_extarcted->rv2; uint8_t harq_pid = pdci_info_extarcted->harq_pid; @@ -5615,7 +5615,7 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, uint8_t rah = pdci_info_extarcted->rah; uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t mcs2 = pdci_info_extarcted->mcs1; + uint8_t mcs2 = pdci_info_extarcted->mcs2; uint8_t rv1 = pdci_info_extarcted->rv1; uint8_t rv2 = pdci_info_extarcted->rv2; uint8_t harq_pid = pdci_info_extarcted->harq_pid; From 25f35fbbb475a205eabca80b8589e128c97754dc Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Tue, 28 Feb 2017 16:18:30 +0100 Subject: [PATCH 339/571] fix: remove verbose printfs --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index bc617b23e7..9f4749cdc6 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5642,9 +5642,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, TB1_active=0; } - //#ifdef DEBUG_HARQ +#ifdef DEBUG_HARQ printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active); - //#endif +#endif dlsch0_harq->mcs = mcs1; dlsch1_harq->mcs = mcs2; @@ -5682,21 +5682,23 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, if (TB0_active==0) { dlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; - //#ifdef DEBUG_HARQ +#ifdef DEBUG_HARQ printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); - //#endif +#endif } if (TB1_active==0) { dlsch1_harq->status = SCH_IDLE; pdlsch1->active = 0; - //#ifdef DEBUG_HARQ +#ifdef DEBUG_HARQ printf("[DCI UE]: TB1 is deactivated, retransmit TB0 transmit in TM6\n"); - //#endif +#endif } +#ifdef DEBUG_HARQ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); +#endif // compute resource allocation if (TB0_active == 1){ @@ -5824,7 +5826,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, dlsch1_harq->Qm = (mcs2-28)<<1; } +#ifdef DEBUG_HARQ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); +#endif #ifdef DEBUG_HARQ if (dlsch0 != NULL && dlsch1 != NULL) From 0a46cc56a2a1d4282847fdffb7b611a889c1bf43 Mon Sep 17 00:00:00 2001 From: khadraou Date: Wed, 1 Mar 2017 10:11:07 +0100 Subject: [PATCH 340/571] fixed PRACH hardcoded size --- targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h index b1e3db1b6e..6c51db64ce 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h @@ -68,7 +68,7 @@ // Packet sizes for IF4p5 interface format #define DATA_BLOCK_SIZE_BYTES(scaled_nblocks) (sizeof(uint16_t)*scaled_nblocks) -#define PRACH_HARD_CODED_NUM_SAMPLES (839*4) +#define PRACH_HARD_CODED_NUM_SAMPLES (839*2) #define PRACH_BLOCK_SIZE_BYTES (sizeof(int16_t)*PRACH_HARD_CODED_NUM_SAMPLES) // FIX hard coded prach size #define RAW_IF4p5_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t + DATA_BLOCK_SIZE_BYTES(nblocks)) From 2e9dfe0fbbdc27db510a439d0ae4dd8c98f3090a Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 1 Mar 2017 15:29:59 +0100 Subject: [PATCH 341/571] Changing names for bler and abstraction output files in dlsim_tm4 to distinguish from the old runs. --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index ad812cf3ec..12e717a6b8 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -788,18 +788,18 @@ int main(int argc, char **argv) else {//abstx=0 if (perfect_ce==1){ if (updated_csi==1){ - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); } else{ - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); } } else{ if (updated_csi==1){ - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); } else{ - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%d.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); } } } @@ -844,9 +844,9 @@ int main(int argc, char **argv) else if (perfect_ce==1) - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_pce_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz); else - sprintf(csv_fname,"dout_tx%d_r%d_mcs%d_mcsi%d_ch%d_ns%d_R%d_sh%d_%d_pnort_r45.m",transmission_mode,rx_type,mcs1,mcs2,channel_model,n_frames,num_rounds, interf_unaw_shift, n_ch_rlz); + sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz); csv_fd = fopen(csv_fname,"w"); fprintf(csv_fd,"data_all%d=[",mcs1); From 7d649f432beeb570c57a387e538e447bc215ea1b Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 1 Mar 2017 16:00:56 +0100 Subject: [PATCH 342/571] Fixing bler limits for different receivers. --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 12e717a6b8..8c45e9d65b 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -166,7 +166,7 @@ int main(int argc, char **argv) RX_type_t rx_type=rx_standard; unsigned char cur_harq_pid; int hold_rank1_precoder=0; - int tpmi_retr=2; + int tpmi_retr=0; bool is_first_time; int updated_csi = 0; @@ -781,9 +781,9 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod); else if (abstx == 1){ if (perfect_ce==1) - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); else - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr); } else {//abstx=0 if (perfect_ce==1){ @@ -799,7 +799,7 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); } else{ - sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); + sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr); } } } @@ -5237,10 +5237,10 @@ int main(int argc, char **argv) printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate[0]*effective_rate, 100*effective_rate, rate[0]); } if (abstx == 1) { - if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard)) { + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_SIC_dual_stream)) { - if (((double)errs[0][0]/(round_trials[0][0]))<1e-2 && ((double)errs[1][0]/(round_trials[1][0]))<1e-2) - if (((double)errs[0][0]/(round_trials[0][0]))<1e-2 && ((double)errs[1][0]/(round_trials[1][0]))<1e-2) + if ((((double)errs[0][0]/(round_trials[0][0]))<1e-2) && (((double)errs[1][0]/(round_trials[1][0]))<1e-2)) + if ((((double)errs[0][0]/(round_trials[0][0]))<1e-2) && (((double)errs[1][0]/(round_trials[1][0]))<1e-2)) break; } else{ @@ -5251,8 +5251,8 @@ int main(int argc, char **argv) } else { - if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_standard) || (rx_type==rx_SIC_dual_stream)) { - if (((double)errs[0][0]/(round_trials[0][0]))<1e-3 && ((double)errs[1][0]/(round_trials[1][0]))<1e-3) + if ((rx_type==rx_IC_dual_stream) || (rx_type==rx_SIC_dual_stream)) { + if ((((double)errs[0][0]/(round_trials[0][0]))<1e-3) && (((double)errs[1][0]/(round_trials[1][0]))<1e-3)) break; } else{ From 74e2cf77fa7e9687999e596f0e2cd55fc5dd3701 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Wed, 1 Mar 2017 16:43:30 +0100 Subject: [PATCH 343/571] Fixing throughput computations for multiple rounds in TM4. --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 30 ++++++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 8c45e9d65b..a51ef3cf23 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -4682,9 +4682,18 @@ int main(int argc, char **argv) if (transmission_mode == 3 || transmission_mode == 4) { // FOR CW0 thr_cw0[0] = rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0])); - thr_cw0[1] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/2)*(((double)errs[0][0] - (double)errs[0][1])/(double)round_trials[0][0]); - thr_cw0[2] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/3)*(((double)errs[0][1] - (double)errs[0][2])/(double)round_trials[0][0]); - thr_cw0[3] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/4)*(((double)errs[0][2] - (double)errs[0][3])/(double)round_trials[0][0]); + if (num_rounds > 1) + thr_cw0[1] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/2)*(((double)errs[0][0] - (double)errs[0][1])/(double)round_trials[0][0]); + else + thr_cw0[1]=0; + if (num_rounds > 2) + thr_cw0[2] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/3)*(((double)errs[0][1] - (double)errs[0][2])/(double)round_trials[0][0]); + else + thr_cw0[2]=0; + if (num_rounds > 3) + thr_cw0[3] = (rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/4)*(((double)errs[0][2] - (double)errs[0][3])/(double)round_trials[0][0]); + else + thr_cw0[3]=0; thr_cw0_tot = (double)thr_cw0[0]+(double)thr_cw0[1]+(double)thr_cw0[2]+(double)thr_cw0[3]; #ifdef PRINT_THROUGHPUT printf("rate %f \n", rate0_init); @@ -4701,9 +4710,18 @@ int main(int argc, char **argv) #endif thr_cw1[0] = rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0])); - thr_cw1[1] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]); - thr_cw1[2] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/3)*(((double)errs[1][1] - (double)errs[1][2])/(double)round_trials[1][0]); - thr_cw1[3] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/4)*(((double)errs[1][2] - (double)errs[1][3])/(double)round_trials[1][0]); + if (num_rounds > 1) + thr_cw1[1] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]); + else + thr_cw1[1] = 0; + if (num_rounds > 2) + thr_cw1[2] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/3)*(((double)errs[1][1] - (double)errs[1][2])/(double)round_trials[1][0]); + else + thr_cw1[2] = 0; + if (num_rounds > 3) + thr_cw1[3] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/4)*(((double)errs[1][2] - (double)errs[1][3])/(double)round_trials[1][0]); + else + thr_cw1[3]=0; thr_cw1_tot = (double)thr_cw1[0]+(double)thr_cw1[1]+(double)thr_cw1[2]+(double)thr_cw1[3]; #ifdef PRINT_THROUGHPUT printf("Throughput cw1 sum = %f \n", thr_cw1_tot); From 52006fc6ea2d0fe9fa0bd1f8166872d336ff9c23 Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 2 Mar 2017 10:37:33 +0100 Subject: [PATCH 344/571] RLC AM : Add Rx PDU Segment handling --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c | 7 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h | 5 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c | 8 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 643 +++++++++++++++++- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h | 19 + .../LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h | 12 + 6 files changed, 681 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index 873e51fbfe..5a6cfef5a6 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -212,7 +212,8 @@ void rlc_am_reassemble_pdu( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP, - mem_block_t * const tb_pP) + mem_block_t * const tb_pP, + boolean_t free_rlc_pdu) { int i,j; @@ -397,5 +398,7 @@ rlc_am_reassemble_pdu( } } - free_mem_block(tb_pP, __func__); + if (free_rlc_pdu) { + free_mem_block(tb_pP, __func__); + } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h index fece9ae570..4b780ce441 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h @@ -72,13 +72,14 @@ private_rlc_am_reassembly( void rlc_am_reassembly (const protocol_ctxt_t* co */ private_rlc_am_reassembly( void rlc_am_send_sdu (const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP);) -/*! \fn void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const mem_block_t* const tb_pP) +/*! \fn void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const mem_block_t* const tb_pP,boolean_t free_rlc_pdu) * \brief Reassembly a RLC AM PDU, depending of the content of this PDU, data will be reassemblied to the current output SDU, the current will be sent to higher layers or not, after or before the reassembly, or no send of SDU will be triggered, depending on FI field in PDU header. * \param[in] ctxtP Running context. * \param[in] rlc_pP RLC AM protocol instance pointer. * \param[in] tb_pP RLC AM PDU embedded in a mem_block_t. +* \param[in] free_rlc_pdu Flag for freeing RLC AM PDU after reassembly. */ -protected_rlc_am_reassembly( void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, mem_block_t* const tb_pP);) +protected_rlc_am_reassembly( void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, mem_block_t* const tb_pP,boolean_t free_rlc_pdu);) /** @} */ #endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c index f2246e45f8..94654f097a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c @@ -31,6 +31,7 @@ #include "LAYER2/MAC/extern.h" #include "UTIL/LOG/log.h" + //----------------------------------------------------------------------------- signed int rlc_am_get_data_pdu_infos( @@ -330,7 +331,8 @@ rlc_am_receive_process_data_pdu ( rlc_pP->vr_ms, rlc_pP->vr_x); - if (rlc_am_rx_list_insert_pdu(ctxt_pP, rlc_pP,tb_pP) < 0) { + pdu_status = rlc_am_rx_list_check_duplicate_insert_pdu(ctxt_pP, rlc_pP,tb_pP); + if (pdu_status != RLC_AM_DATA_PDU_STATUS_OK) { rlc_pP->stat_rx_data_pdu_dropped += 1; rlc_pP->stat_rx_data_bytes_dropped += tb_size_in_bytesP; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED, STATUS REQUESTED:\n", @@ -398,7 +400,7 @@ rlc_am_receive_process_data_pdu ( rlc_pP->vr_mr = (rlc_pP->vr_r + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; } - reassemble = true; + reassemble = rlc_am_rx_check_vr_reassemble(ctxt_pP, rlc_pP); //TODO : optimization : check whether a reassembly is needed by looking at LI, FI, SO, etc... } @@ -446,7 +448,7 @@ rlc_am_receive_process_data_pdu ( } /* 3) Check for triggering a Tx Status PDU if a poll is received or if a pending status was delayed */ - if (pdu_info_p->p) { + if ((pdu_info_p->p) && (pdu_status < RLC_AM_DATA_PDU_STATUS_BUFFER_FULL)) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] POLL BIT SET, STATUS REQUESTED:\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 8e055406a1..e08be44b54 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -31,7 +31,595 @@ #include "UTIL/LOG/log.h" +boolean_t rlc_am_rx_check_vr_reassemble( + const protocol_ctxt_t* const ctxt_pP, + const rlc_am_entity_t* const rlc_pP) +{ + mem_block_t* cursor_p = NULL; + cursor_p = rlc_pP->receiver_buffer.head; + boolean_t reassemble = FALSE; + if (cursor_p != NULL) { + + rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + rlc_usn_t sn_ref = pdu_info_p->sn; + if (sn_ref != rlc_pP->vr_r) { + reassemble = TRUE; + } + + /* jump up to vrR */ + while ((RLC_AM_DIFF_SN(pdu_info_p->sn,sn_ref) < RLC_AM_DIFF_SN(rlc_pP->vr_r,sn_ref)) && (cursor_p != NULL)) { + if ((pdu_info_p->rf) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO)) { + ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; + } + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + + if ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r)) { + /* case vrR = partially received */ + rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + sdu_size_t next_waited_so = 0; + AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly vr=%d should be partly received LCID=%d\n", + rlc_pP->vr_r,rlc_pP->channel_id); + while ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r) && (pdu_info_p->so == next_waited_so)) { + if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) { + pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; + reassemble = TRUE; + } + next_waited_so += pdu_info_p->payload_size; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + } + + } + return reassemble; +} + +mem_block_t * create_new_segment_from_pdu( + mem_block_t* const tb_pP, + uint16_t so_offset, /* offset from the data part of the PDU to copy */ + sdu_size_t data_length_to_copy) +{ + rlc_am_pdu_info_t* pdu_rx_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; + rlc_am_pdu_info_t* pdu_new_segment_info_p = NULL; + mem_block_t * new_segment_p = NULL; + int16_t new_li_list[RLC_AM_MAX_SDU_IN_PDU]; + int16_t header_size = 0; + uint8_t num_li = 0; + boolean_t fi_start, fi_end, lsf; + + /* Init some PDU Segment header fixed parameters */ + fi_start = !((pdu_rx_info_p->fi & 0x2) >> 1); + fi_end = !(pdu_rx_info_p->fi & 0x1); + lsf = ((pdu_rx_info_p->lsf == 1) || (pdu_rx_info_p->rf == 0)); + + /* Handle NO Li case fist */ + if (pdu_rx_info_p->num_li == 0) { + + header_size = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; + + if (so_offset) { + fi_start = FALSE; + } + if (so_offset + data_length_to_copy != pdu_rx_info_p->payload_size) { + fi_end = FALSE; + lsf = FALSE; + } + } // end no LI in original segment + else { + + uint8_t li_index = 0; + uint16_t li_sum = 0; + num_li = pdu_rx_info_p->num_li; + + /* set LSF to false if we know that end of the original segment will not be copied */ + if (so_offset + data_length_to_copy != pdu_rx_info_p->payload_size) { + lsf = FALSE; + } + + /* catch the first LI containing so_offset */ + while ((li_index < pdu_rx_info_p->num_li) && (li_sum + pdu_rx_info_p->li_list[li_index] <= so_offset)) { + li_sum += pdu_rx_info_p->li_list[li_index]; + num_li --; + li_index ++; + } + + /* set FI start if so_offset = LI sum and at least one LI have been read */ + if ((li_index) && (so_offset == li_sum)) { + fi_start = TRUE; + } + + /* Fill LI until the end */ + if (num_li) { + sdu_size_t remaining_size = data_length_to_copy; + uint8_t j = 0; + new_li_list[0] = li_sum + pdu_rx_info_p->li_list[li_index] - so_offset; + if (data_length_to_copy <= new_li_list[0]) { + num_li = 0; + } + else { + remaining_size -= new_li_list[0]; + j++; + li_index ++; + while ((li_index < pdu_rx_info_p->num_li) && (remaining_size >= pdu_rx_info_p->li_list[li_index])) { + remaining_size -= pdu_rx_info_p->li_list[li_index]; + new_li_list[j] = pdu_rx_info_p->li_list[li_index]; + j++; + li_index ++; + } + + /* update number of LI in the segment */ + num_li = j; + /* set FI End if remaining size = 0 */ + if (remaining_size == 0) { + fi_end = TRUE; + } + } + } + + /* compute header size */ + header_size = RLC_AM_PDU_SEGMENT_HEADER_SIZE(num_li); + + } // end LIs in original segment + + /* Allocate new buffer */ + new_segment_p = get_free_mem_block(sizeof (mac_rlc_max_rx_header_size_t) + header_size + data_length_to_copy, __func__); + + /* Fill PDU Segment Infos and Header */ + if (new_segment_p != NULL) { + pdu_new_segment_info_p = &((rlc_am_rx_pdu_management_t*)(new_segment_p->data))->pdu_info; + rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (new_segment_p->data); + uint8_t *pdu_segment_header_p = &(new_segment_p->data[sizeof (mac_rlc_max_rx_header_size_t)]); + + pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO; //to be updated after if SN = vrR + + pdu_new_segment_info_p->d_c = pdu_rx_info_p->d_c; + pdu_new_segment_info_p->sn = pdu_rx_info_p->sn; + pdu_new_segment_info_p->p = pdu_rx_info_p->p; + pdu_new_segment_info_p->rf = 1; + pdu_new_segment_info_p->fi = (((fi_start ? 0: 1) << 1) | (fi_end ? 0: 1)); + pdu_new_segment_info_p->e = (num_li ? 1: 0); + pdu_new_segment_info_p->lsf = (lsf ? 1: 0); + pdu_new_segment_info_p->so = pdu_rx_info_p->so + so_offset; + pdu_new_segment_info_p->payload = pdu_segment_header_p + header_size; + pdu_new_segment_info_p->header_size = header_size; + pdu_new_segment_info_p->payload_size = data_length_to_copy; + pdu_new_segment_info_p->hidden_size = data_length_to_copy; + for (int i=0; i < num_li; i++) { + pdu_new_segment_info_p->li_list[i] = new_li_list[i]; + pdu_new_segment_info_p->hidden_size -= new_li_list[i]; + } + + /* Fill Header part in the buffer */ + /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ + /* copy first two bytes from original: D/C + RF + FI + E+ SN*/ + memset(pdu_segment_header_p, 0, header_size); + RLC_AM_PDU_SET_D_C(*pdu_segment_header_p); + RLC_AM_PDU_SET_RF(*pdu_segment_header_p); + if (pdu_new_segment_info_p->p) { + RLC_AM_PDU_SET_POLL(*pdu_segment_header_p); + } + /* Change FI */ + if (!fi_start) + { + // Set to not starting + (*pdu_segment_header_p) |= (1 << (RLC_AM_PDU_FI_OFFSET + 1)); + + } + if (!fi_end) + { + // Set to not starting + (*pdu_segment_header_p) |= (1 << (RLC_AM_PDU_FI_OFFSET)); + + } + /* E */ + if (pdu_new_segment_info_p->e) { + RLC_AM_PDU_SET_E(*pdu_segment_header_p); + } + /* SN */ + (*pdu_segment_header_p) |= (pdu_new_segment_info_p->sn >> 8) ; + *(pdu_segment_header_p + 1) = (pdu_new_segment_info_p->sn & 0xFF); + + pdu_segment_header_p += 2; + + /* Last Segment Flag (LSF) */ + if (lsf) + { + RLC_AM_PDU_SET_LSF(*pdu_segment_header_p); + } + /* Store SO bytes */ + * (pdu_segment_header_p ) = (pdu_new_segment_info_p->so >> 8) & 0xFF; + * (pdu_segment_header_p + 1) = pdu_new_segment_info_p->so & 0xFF; + + if (num_li) { + uint16_t index = 0; + uint16_t temp = 0; + uint8_t li_bit_offset = 4; /* toggle between 0 and 4 */ + uint8_t li_jump_offset = 1; /* toggle between 1 and 2 */ + + /* loop on nb of LIs */ + pdu_segment_header_p += 2; + + while (index < num_li) + { + /* Set E bit for next LI if present */ + if (index < num_li - 1) + RLC_SET_BIT(temp,li_bit_offset + RLC_AM_LI_BITS); + /* Set LI */ + RLC_AM_PDU_SET_LI(temp,new_li_list[index],li_bit_offset); + *pdu_segment_header_p = temp >> 8; + *(pdu_segment_header_p + 1) = temp & 0xFF; + pdu_segment_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + + temp = ((*pdu_segment_header_p) << 8) | (*(pdu_segment_header_p + 1)); + index ++; + } + } + + /* copy data part */ + /* Fill mem_block contexts */ + ((struct mac_tb_ind *) (new_segment_p->data))->first_bit = 0; + ((struct mac_tb_ind *) (new_segment_p->data))->data_ptr = (uint8_t*)&new_segment_p->data[sizeof (mac_rlc_max_rx_header_size_t)]; + ((struct mac_tb_ind *) (new_segment_p->data))->size = data_length_to_copy + header_size; + memcpy(pdu_new_segment_info_p->payload,pdu_rx_info_p->payload + so_offset,data_length_to_copy); + } + + return new_segment_p; +} + +rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t* const rlc_pP, + mem_block_t* const tb_pP) +{ + rlc_am_pdu_info_t* pdu_rx_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; + rlc_am_pdu_info_t* pdu_info_cursor_p = NULL; + rlc_am_pdu_info_t* pdu_info_previous_cursor_p = NULL; + mem_block_t* cursor_p = NULL; + mem_block_t* previous_cursor_p = NULL; + mem_block_t* next_cursor_p = NULL; + cursor_p = rlc_pP->receiver_buffer.head; + boolean_t prev_segment_found = FALSE; + boolean_t next_segment_found = FALSE; + uint16_t so_start = 0; + uint16_t so_end = 0; + uint16_t so_start_segment = pdu_rx_info_p->so; + uint16_t so_end_segment = pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1; + + /*****************************************************/ + // 1) Find previous cursor to the PDU to insert + /*****************************************************/ + previous_cursor_p = cursor_p; + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + pdu_info_previous_cursor_p = pdu_info_cursor_p; + while (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + + // Stop if Cursor SN >= Received SN + if (RLC_AM_DIFF_SN(pdu_info_cursor_p->sn,rlc_pP->vr_r) >= RLC_AM_DIFF_SN(pdu_rx_info_p->sn,rlc_pP->vr_r)) { + break; + } + + previous_cursor_p = cursor_p; + pdu_info_previous_cursor_p = pdu_info_cursor_p; + cursor_p = cursor_p->next; + } + + /*****************************************************/ + // 2) Store the received Segment + /*****************************************************/ + // First case : cursor_p is NULL or its SN is different from the received one, it means the SN is received for the first time + // Insert PDU after previous_cursor_p + if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + return RLC_AM_DATA_PDU_STATUS_OK; + } + + // Filter out SN duplicate + rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + + if (pdu_cursor_mgnt_p->all_segments_received) { + return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; + } + + // Handle the remaining case : some PDU Segments already received for the same SN + // Try to insert the PDU according to its SO and SO+datalength of stored ones + // First find the segment just before the pdu to insert + while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn)) { + if (pdu_rx_info_p->so < pdu_info_cursor_p->so) { + prev_segment_found = TRUE; + break; + } + + previous_cursor_p = cursor_p; + pdu_info_previous_cursor_p = pdu_info_cursor_p; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + + /* if not previously inserted, it will be put after the last segment if it was not LSF*/ + if ((!prev_segment_found) && (pdu_info_previous_cursor_p->lsf == 0)) { + prev_segment_found = TRUE; + next_segment_found = TRUE; // no more segment after the PDU + next_cursor_p = cursor_p; + AssertFatal(previous_cursor_p->next == next_cursor_p,"AM Rx PDU Segment store at the end error, SN=%d \n",pdu_rx_info_p->sn); + } + else + { + // the segment is duplicate + return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; + } + + + + // Check that the Segment is not duplicate by scanning stored contiguous segments from previous_cursor_p + pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; + if ((previous_cursor_p != NULL) && (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn)) { + so_start = pdu_info_previous_cursor_p->so; + so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - 1; + + cursor_p = previous_cursor_p; + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + cursor_p = cursor_p->next; + rlc_am_pdu_info_t* pdu_info_cursor_next_p = NULL; + if (cursor_p != NULL) { + pdu_info_cursor_next_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + + while ((cursor_p != NULL) && (pdu_info_cursor_next_p->sn == pdu_rx_info_p->sn) + && (pdu_info_cursor_next_p->so == pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size)) { + so_end += pdu_info_cursor_next_p->payload_size; + pdu_info_cursor_p = pdu_info_cursor_next_p; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_next_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + + /* Now discard the PDU segment if it is within so_start so_end */ + if ((so_start <= so_start_segment) && (so_end_segment <= so_end)) { + return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; + } + } + + + // Now found the segment which will be right after the pdu to insert + if (!next_segment_found) { + + cursor_p = previous_cursor_p->next; + next_cursor_p = cursor_p; + if (next_cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + } + + // Discard embedded segments in the received PDU segment + while ((next_cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && + (pdu_rx_info_p->so + pdu_rx_info_p->payload_size >= pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size)) { + /* Discard the segment */ + cursor_p = next_cursor_p; + next_cursor_p = next_cursor_p->next; + list2_remove_element (cursor_p, &rlc_pP->receiver_buffer); + free_mem_block(cursor_p, __func__); + + if (next_cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + } + } + } + + /* Now remove duplicate bytes */ + // remove duplicate at the begining, only valid if the segment is to be inserted after a PDU segment of the same SN + pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; + if (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) { + so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - pdu_rx_info_p->so); + } + // remove duplicate at the end + if (next_cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + + if ((pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && (so_end_segment >= pdu_info_cursor_p->so)) { + so_end_segment = pdu_info_cursor_p->so - 1; + } + } + + AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) && + (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), + " AM RX PDU Segment Duplicate elimination error OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n", + pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn); + + /* Last step : Insertion */ + /* If some duplicate bytes had been removed, build a new PDU segment */ + if ((pdu_rx_info_p->so != so_start_segment) || (so_end_segment != pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1)) { + + mem_block_t* trunc_segment = create_new_segment_from_pdu(tb_pP,so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1); + if (trunc_segment != NULL) { + list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer); + /* Free original PDU Segment */ + free_mem_block(tb_pP, __func__); + + return RLC_AM_DATA_PDU_STATUS_OK; + } + else { + return RLC_AM_DATA_PDU_STATUS_BUFFER_FULL; + } + } + else + { + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + return RLC_AM_DATA_PDU_STATUS_OK; + } +} + +rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t* const rlc_pP, + mem_block_t* const tb_pP) +{ + rlc_am_pdu_info_t* pdu_rx_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; + rlc_am_pdu_info_t* pdu_info_cursor_p = NULL; + mem_block_t* cursor_p = NULL; + mem_block_t* previous_cursor_p = NULL; + cursor_p = rlc_pP->receiver_buffer.head; + rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; + // it is assumed this pdu is in rx window + + + /*****************************************************/ + // 1) Find previous cursor to the PDU to insert + /*****************************************************/ + previous_cursor_p = cursor_p; + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + while (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + + // Stop if Cursor SN >= Received SN + if (RLC_AM_DIFF_SN(pdu_info_cursor_p->sn,rlc_pP->vr_r) >= RLC_AM_DIFF_SN(pdu_rx_info_p->sn,rlc_pP->vr_r)) { + break; + } + + previous_cursor_p = cursor_p; + cursor_p = cursor_p->next; + } + + /*****************************************************/ + // 2) Insert PDU by removing byte duplicate if required + /*****************************************************/ + // First case : cursor_p is NULL, it means the SN is received for the first time + // Insert PDU after previous_cursor_p + if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + return pdu_status; + } + + // Filter out SN duplicate + // SN of received PDU has already data stored + rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + + if (pdu_cursor_mgnt_p->all_segments_received) { + return RLC_AM_DATA_PDU_STATUS_SN_DUPLICATE; + } + + /* check if the received PDU is equal to vrR */ + if ((pdu_rx_info_p->sn != rlc_pP->vr_r) || (pdu_info_cursor_p->so != 0)) { + /* The full received PDU can replace the allready received PDU Segments. */ + /* clean them and append this PDU */ + mem_block_t* cursor_next_p = cursor_p; + while (cursor_next_p) { + cursor_p = cursor_next_p; + cursor_next_p = cursor_next_p->next; + list2_remove_element (cursor_p, &rlc_pP->receiver_buffer); + free_mem_block(cursor_p, __func__); + if (cursor_next_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_next_p->data))->pdu_info; + if (pdu_info_cursor_p->sn != pdu_rx_info_p->sn) { + break; + } + } + } + + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + return pdu_status; + } // End SN != vrR or SO != 0 + else { + /* First update cursor until discontinuity */ + previous_cursor_p = cursor_p; + AssertFatal(pdu_info_cursor_p->rf != 0,"AM Rx PDU Error, stored SN=%d should be a PDU segment\n",pdu_info_cursor_p->sn); + AssertFatal(((rlc_am_rx_pdu_management_t *) (cursor_p->data))->all_segments_received == 0, + "AM Rx PDU Error, stored SN=%d already fully received\n",pdu_info_cursor_p->sn); + sdu_size_t next_waited_so = 0; + while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && (pdu_info_cursor_p->so == next_waited_so)) { + next_waited_so += pdu_info_cursor_p->payload_size; + previous_cursor_p = cursor_p; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + /* Create a new PDU segment by removing first next_waited_so bytes */ + mem_block_t* trunc_pdu = create_new_segment_from_pdu(tb_pP,next_waited_so,pdu_rx_info_p->payload_size - next_waited_so); + + if (trunc_pdu != NULL) { + ((rlc_am_rx_pdu_management_t *) (trunc_pdu->data))->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; + /* Insert PDU Segment */ + list2_insert_after_element(trunc_pdu, previous_cursor_p, &rlc_pP->receiver_buffer); + + /* clean previous stored segments in duplicate */ + if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn)) { + mem_block_t* cursor_next_p = cursor_p; + while (cursor_next_p) { + cursor_p = cursor_next_p; + cursor_next_p = cursor_next_p->next; + list2_remove_element (cursor_p, &rlc_pP->receiver_buffer); + free_mem_block(cursor_p, __func__); + if (cursor_next_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_next_p->data))->pdu_info; + if (pdu_info_cursor_p->sn != pdu_rx_info_p->sn) { + break; + } + } + } + } + + /* Free original PDU */ + free_mem_block(tb_pP, __func__); + + return pdu_status; + } + else { + return RLC_AM_DATA_PDU_STATUS_BUFFER_FULL; + } + } +} + +// returns 0 if success +// returns neg value if failure +//----------------------------------------------------------------------------- +rlc_am_rx_pdu_status_t +rlc_am_rx_list_check_duplicate_insert_pdu( + const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t* const rlc_pP, + mem_block_t* const tb_pP) +{ + rlc_am_pdu_info_t* pdu_rx_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; + mem_block_t* cursor_p = NULL; + cursor_p = rlc_pP->receiver_buffer.head; + rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; + // it is assumed this pdu is in rx window + + if (cursor_p == NULL) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[INSERT PDU] LINE %d RX PDU SN %04d (only inserted)\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + __LINE__, + pdu_rx_info_p->sn); + list2_add_head(tb_pP, &rlc_pP->receiver_buffer); + return pdu_status; + } + + + /* Init Reassembly status */ + ((rlc_am_rx_pdu_management_t*)(tb_pP->data))->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO; + + if (pdu_rx_info_p->rf == 0) { // Case normal PDU received + pdu_status = rlc_am_rx_list_handle_pdu(ctxt_pP,rlc_pP,tb_pP); + } + else { + pdu_status = rlc_am_rx_list_handle_pdu_segment(ctxt_pP,rlc_pP,tb_pP); + } + + return pdu_status; +} +#if 0 // returns 0 if success // returns neg value if failure //----------------------------------------------------------------------------- @@ -483,6 +1071,8 @@ rlc_am_rx_list_insert_pdu( pdu_info_p->sn); return -1; } +#endif + //----------------------------------------------------------------------------- void rlc_am_rx_check_all_byte_segments( @@ -523,8 +1113,10 @@ rlc_am_rx_check_all_byte_segments( // in case all first segments up to tb_pP are in list // the so field of the first PDU should be 0 //cursor_p = list.head; + //we start from the first stored PDU segment of this SN pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + // if the first segment does not have SO = 0 then no need to continue if (pdu_info_p->so != 0) { return; } @@ -553,13 +1145,15 @@ rlc_am_rx_check_all_byte_segments( next_waited_so = next_waited_so + pdu_info_p->payload_size; //msg("rlc_am_rx_check_all_byte_segments(%d) @6\n",sn); } else { // assumed pdu_info_p->so + pdu_info_p->payload_size > next_waited_so - next_waited_so = (next_waited_so + pdu_info_p->payload_size) - (next_waited_so - pdu_info_p->so); + //next_waited_so = (next_waited_so + pdu_info_p->payload_size) - (next_waited_so - pdu_info_p->so); //msg("rlc_am_rx_check_all_byte_segments(%d) @7\n",sn); + return; } if (pdu_info_p->lsf > 0) { //msg("rlc_am_rx_check_all_byte_segments(%d) @8\n",sn); rlc_am_rx_mark_all_segments_received(ctxt_pP, rlc_pP, first_cursor_p); + return; } } @@ -608,8 +1202,9 @@ rlc_am_rx_list_reassemble_rlc_sdus( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlc_pP) { - mem_block_t* cursor_p = NULL; - rlc_am_rx_pdu_management_t* rlc_am_rx_old_pdu_management = NULL; + mem_block_t* cursor_p = NULL; + rlc_am_rx_pdu_management_t* rlc_am_rx_old_pdu_management = NULL; + rlc_am_pdu_info_t* pdu_info_p = NULL; cursor_p = list2_get_head(&rlc_pP->receiver_buffer); @@ -618,11 +1213,31 @@ rlc_am_rx_list_reassemble_rlc_sdus( } rlc_am_rx_pdu_management_t* rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); + pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + + /* Specific process for the first SN if all PDU segments had been reassembled but not freed */ + if ((rlc_am_rx_pdu_management_p->all_segments_received > 0) && (pdu_info_p->rf != 0)) { + rlc_sn_t sn = pdu_info_p->sn; + while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED) + && ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == sn) { + cursor_p = list2_remove_head(&rlc_pP->receiver_buffer); + free_mem_block(cursor_p, __func__); + cursor_p = list2_get_head(&rlc_pP->receiver_buffer); + } + + /* Reset Management pointers */ + if (cursor_p != NULL) { + rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); + } + else { + return; + } + } do { if (rlc_am_rx_pdu_management_p->all_segments_received > 0) { cursor_p = list2_remove_head(&rlc_pP->receiver_buffer); - rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p); + rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,TRUE); rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; cursor_p = list2_get_head(&rlc_pP->receiver_buffer); @@ -631,7 +1246,22 @@ rlc_am_rx_list_reassemble_rlc_sdus( } rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); - } else { + } + else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING) { + rlc_am_rx_pdu_management_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLED; + + cursor_p = list2_remove_head(&rlc_pP->receiver_buffer); + rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,FALSE); + rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; + cursor_p = list2_get_head(&rlc_pP->receiver_buffer); + + if (cursor_p == NULL) { + return; + } + + rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); + } + else { #if RLC_STOP_ON_LOST_PDU if (list2_get_head(&rlc_pP->receiver_buffer) != cursor_p) { @@ -645,7 +1275,8 @@ rlc_am_rx_list_reassemble_rlc_sdus( } } while ((rlc_am_rx_pdu_management_p->pdu_info.sn == ((rlc_am_rx_old_pdu_management->pdu_info.sn + 1) & RLC_AM_SN_MASK)) - || ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && (rlc_am_rx_pdu_management_p->all_segments_received > 0))); + || ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && ( + (rlc_am_rx_pdu_management_p->all_segments_received > 0) || (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING)))); } //----------------------------------------------------------------------------- mem_block_t * diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h index c75255c4fa..e6e043dd0a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h @@ -59,6 +59,16 @@ #include "PHY/defs.h" //----------------------------------------------------------------------------- +/*! \fn rlc_am_rx_pdu_status_t rlc_am_rx_list_check_duplicate_insert_pdu(const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* const rlc_pP,mem_block_t* const tb_pP) +* \brief Insert a PDU in the RX buffer after removing byte duplicate (implemented with a list). +* \param[in] ctxt_pP Running context. +* \param[in] rlcP RLC AM protocol instance pointer. +* \param[in] tbP A PDU embedded in a mem_block_t. +* \return Zero if the PDU could be inserted in the RX buffer, a negative value if the PDU could not be inserted. +*/ +protected_rlc_am_rx_list( rlc_am_rx_pdu_status_t rlc_am_rx_list_check_duplicate_insert_pdu(const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t* const rlc_pP,mem_block_t* const tb_pP);) + +#if 0 /*! \fn signed int rlc_am_rx_list_insert_pdu(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP , mem_block_t* const tbP) * \brief Insert a PDU in the RX buffer (implemented with a list). * \param[in] ctxt_pP Running context. @@ -67,6 +77,15 @@ * \return Zero if the PDU could be inserted in the RX buffer, a negative value if the PDU could not be inserted. */ protected_rlc_am_rx_list( signed int rlc_am_rx_list_insert_pdu(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP, mem_block_t* const tbP);) +#endif + +/*! \fn boolean_t rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP) +* \brief Check if reassembly taking into account potential new vrR value +* \param[in] ctxt_pP Running context. +* \param[in] rlcP RLC AM protocol instance pointer. +* \return TRUE if reassembly must be done, FALSE else +*/ +protected_rlc_am_rx_list( boolean_t rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP);) /*! \fn void rlc_am_rx_check_all_byte_segments(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP, mem_block_t* const tbP) * \brief Check if all sub-segments of a PDU are received, if yes then call rlc_am_rx_mark_all_segments_received() procedure. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h index e79dac57c0..2b75cb21a7 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_structs.h @@ -233,12 +233,24 @@ typedef struct rlc_am_timer { * @{ */ +typedef enum rlc_am_rx_segment_reassemble_info +{ + /** No Reassembly scheduled */ + RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO = 0, + /** Reassembly scheduled */ + RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING = 1, + /** Reassembly done */ + RLC_AM_RX_PDU_SEGMENT_REASSEMBLED = 2 + +} rlc_am_rx_segment_reassemble_info_t; + /*! \struct rlc_am_rx_pdu_management_t * \brief Structure for storing decoded informations from the header of a AMD PDU or AMD PDU segment and information on reassembly. */ typedef struct rlc_am_rx_pdu_management { rlc_am_pdu_info_t pdu_info; /*!< \brief Field for storing decoded informations from the header of a AMD PDU or AMD PDU segment. */ uint8_t all_segments_received; /*!< \brief Is all segments of PDU SN have been received. */ + rlc_am_rx_segment_reassemble_info_t segment_reassembled; /*!< \brief if the segment for SN=vrR is reassembled but not discarded yet. */ } rlc_am_rx_pdu_management_t; /** @} */ From 684ca32e9b86700fccec7c828e3242fd557e2b4f Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 2 Mar 2017 14:51:58 +0100 Subject: [PATCH 345/571] RLC AM Add Log points --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c | 10 ++++++---- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 13 +++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c index 94654f097a..acc047d633 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c @@ -335,8 +335,8 @@ rlc_am_receive_process_data_pdu ( if (pdu_status != RLC_AM_DATA_PDU_STATUS_OK) { rlc_pP->stat_rx_data_pdu_dropped += 1; rlc_pP->stat_rx_data_bytes_dropped += tb_size_in_bytesP; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED, STATUS REQUESTED:\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED CAUSE=%d SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_status,pdu_info_p->sn); #if RLC_STOP_ON_LOST_PDU AssertFatal( 0 == 1, PROTOCOL_RLC_AM_CTXT_FMT" LOST PDU DETECTED\n", @@ -443,8 +443,8 @@ rlc_am_receive_process_data_pdu ( rlc_pP->stat_rx_data_pdu_out_of_window += 1; rlc_pP->stat_rx_data_bytes_out_of_window += tb_size_in_bytesP; pdu_status = RLC_AM_DATA_PDU_STATUS_SN_OUTSIDE_WINDOW; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU OUT OF RX WINDOW, DISCARDED, STATUS REQUESTED:\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU OUT OF RX WINDOW, DISCARDED, SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_info_p->sn); } /* 3) Check for triggering a Tx Status PDU if a poll is received or if a pending status was delayed */ @@ -495,6 +495,8 @@ rlc_am_receive_process_data_pdu ( } else { pdu_status = RLC_AM_DATA_PDU_STATUS_HEADER_ERROR; + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED BAD HEADER FORMAT SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_info_p->sn); } if (pdu_status != RLC_AM_DATA_PDU_STATUS_OK) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index e08be44b54..e8c63a8e40 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -320,6 +320,8 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( // First case : cursor_p is NULL or its SN is different from the received one, it means the SN is received for the first time // Insert PDU after previous_cursor_p if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] STORE FIRST PDU SEGMENT FOR SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); return RLC_AM_DATA_PDU_STATUS_OK; } @@ -389,6 +391,8 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( /* Now discard the PDU segment if it is within so_start so_end */ if ((so_start <= so_start_segment) && (so_end_segment <= so_end)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; } } @@ -444,6 +448,9 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( mem_block_t* trunc_segment = create_new_segment_from_pdu(tb_pP,so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1); if (trunc_segment != NULL) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1,pdu_rx_info_p->sn); + list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer); /* Free original PDU Segment */ free_mem_block(tb_pP, __func__); @@ -528,6 +535,9 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( } } + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU REPLACES STORED PDU SEGMENTS SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); return pdu_status; } // End SN != vrR or SO != 0 @@ -554,6 +564,9 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( /* Insert PDU Segment */ list2_insert_after_element(trunc_pdu, previous_cursor_p, &rlc_pP->receiver_buffer); + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] CREATE PDU SEGMENT FROM PDU OFFSET =%d SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),next_waited_so,pdu_rx_info_p->sn); + /* clean previous stored segments in duplicate */ if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn)) { mem_block_t* cursor_next_p = cursor_p; From b2c57f42fc95b250cc2fe79c009efb982b3e4441 Mon Sep 17 00:00:00 2001 From: Elena_Lukashova Date: Thu, 2 Mar 2017 22:40:54 +0100 Subject: [PATCH 346/571] Fixing bug in modulation for TM4 64QAM. --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 8 ++++---- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index ac722fef60..e24edb8d68 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1338,10 +1338,10 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, ((int16_t *)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15); ((int16_t *)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15); - if (frame_parms->nb_antenna_ports_eNB == 2) { - layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index); - ((int16_t*)&txdataF[1][tti_offset])[0] += ((int16_t*)&tmp_sample2)[0]; - ((int16_t*)&txdataF[1][tti_offset])[1] += ((int16_t*)&tmp_sample2)[1]; + if (frame_parms->nb_antennas_tx == 2) { + layer1prec2A(&tmp_sample1,&tmp_sample2,precoder_index0); + ((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15); + ((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15); } break; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index a51ef3cf23..c3f975006d 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -3163,7 +3163,7 @@ int main(int argc, char **argv) (subframe*2)+2, &eNB->frame_parms); - if (n_frames==2) { + if (n_frames==1) { write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); if (eNB->frame_parms.nb_antennas_tx>1) write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); @@ -3177,7 +3177,7 @@ int main(int argc, char **argv) } tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - if (n_frames==2) { + if (n_frames==1) { write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); if (eNB->frame_parms.nb_antennas_tx>1) write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); From 94229ca59383f4edf29626b81dc00e13f8845564 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 3 Mar 2017 15:17:00 +0100 Subject: [PATCH 347/571] bugfix: = instead of == Bug reported by Bruno Mongazon from Nokia. --- targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c index 0e2a5ceb36..7278c2727d 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -148,7 +148,7 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi int sent_byte; - if (eth->compression = ALAW_COMPRESS) { + if (eth->compression == ALAW_COMPRESS) { sent_byte = RAW_PACKET_SIZE_BYTES_ALAW(nsamps); } else { sent_byte = RAW_PACKET_SIZE_BYTES(nsamps); From f94835becfd9fdd19a1f2517364f6949129b4871 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 3 Mar 2017 15:25:10 +0100 Subject: [PATCH 348/571] bugfix: "if_compress" parameter not taken into account Bug reported by Bruno Mongazon from Nokia. "Without this line, the config file parameter is not properly stored and the FH will always work with compression." --- targets/RT/USER/lte-softmodem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index ed9d955e8a..8303d88218 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1081,6 +1081,7 @@ static void get_options (int argc, char **argv) { } else { (eth_params+j)->rf_preference = 0; } + (eth_params+j)->if_compress = enb_properties->properties[i]->rrh_gw_config[j].if_compress; } else { local_remote_radio = BBU_LOCAL_RADIO_HEAD; } From 709b1fd299c11e9608a190d600475ad501381e22 Mon Sep 17 00:00:00 2001 From: fnabet Date: Sat, 4 Mar 2017 13:40:13 +0100 Subject: [PATCH 349/571] RLC AM: fix TReordering expiry --- .../RLC/AM_v9.3.0/rlc_am_timer_reordering.c | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c index fa214cd5a9..a824c13d15 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c @@ -83,23 +83,22 @@ rlc_am_check_timer_reordering( AssertFatal (cursor != NULL, "RLC AM TReordering Expiry Rx PDU list empty LcId=%d\n", rlc_pP->channel_id); - while ((cursor != NULL) && (vr_ms_new != rlc_pP->vr_h)) { - pdu_info = &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info; + /* go to memblock up to vrX*/ + pdu_info = &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info; + while ((cursor != NULL) && (RLC_AM_DIFF_SN(pdu_info->sn,rlc_pP->vr_r) < RLC_AM_DIFF_SN(vr_ms_new,rlc_pP->vr_r))) { + cursor = cursor->next; + if (cursor != NULL) { + pdu_info = &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info; + } + } - - // First find an element with SN greater or equal than vrX - if (RLC_AM_DIFF_SN(pdu_info->sn,rlc_pP->vr_r) >= RLC_AM_DIFF_SN(rlc_pP->vr_x,rlc_pP->vr_r)) { - if (((rlc_am_rx_pdu_management_t*)(cursor->data))->all_segments_received == 0) { - // Stop at first found discontinuity - // vr_ms_new holds SN following the latest in sequence fully received PDU >= old vrX - break; - } - else { - vr_ms_new = RLC_AM_NEXT_SN(vr_ms_new); - } - - } - cursor = cursor->next; + /* Now find a SN for which either no PDU is received or partially received */ + while ((cursor != NULL) && (pdu_info->sn == vr_ms_new) && (((rlc_am_rx_pdu_management_t*)(cursor->data))->all_segments_received > 0)) { + cursor = cursor->next; + vr_ms_new = RLC_AM_NEXT_SN(vr_ms_new); + if (cursor != NULL) { + pdu_info = &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info; + } } /* Update vr_ms */ From 65040130778c89b2cc0a13c0b64175416d4cf591 Mon Sep 17 00:00:00 2001 From: fnabet Date: Sat, 4 Mar 2017 15:19:58 +0100 Subject: [PATCH 350/571] RLC AM : fix update of vrMS in tReordering expiry --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c index a824c13d15..cec0dffd1d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c @@ -93,9 +93,12 @@ rlc_am_check_timer_reordering( } /* Now find a SN for which either no PDU is received or partially received */ - while ((cursor != NULL) && (pdu_info->sn == vr_ms_new) && (((rlc_am_rx_pdu_management_t*)(cursor->data))->all_segments_received > 0)) { + while ((cursor != NULL) && (vr_ms_new != rlc_pP->vr_h) && (pdu_info->sn == vr_ms_new) && (((rlc_am_rx_pdu_management_t*)(cursor->data))->all_segments_received > 0)) { + /* Increment vrMS if the PDU is fully received or if this is the last PDU segment */ + if ((pdu_info->rf == 0) || (pdu_info->lsf == 1)) { + vr_ms_new = RLC_AM_NEXT_SN(vr_ms_new); + } cursor = cursor->next; - vr_ms_new = RLC_AM_NEXT_SN(vr_ms_new); if (cursor != NULL) { pdu_info = &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info; } From b45e9a68a834474a24d868d6008e76254f5b2e75 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 6 Mar 2017 13:46:41 +0100 Subject: [PATCH 351/571] adding config file for band 38, TM1, usrp --- .../CONF/enb.band38.tm1.usrpb210.conf | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf new file mode 100644 index 0000000000..091997de9b --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf @@ -0,0 +1,175 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "94"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2580000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -24; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + + mme_ip_address = ( { ipv4 = "192.168.12.70"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.146/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.146/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); From dc960a60430153aa97c7e0577b696fba189be543 Mon Sep 17 00:00:00 2001 From: GabrielCouturier Date: Tue, 7 Mar 2017 16:01:35 +0100 Subject: [PATCH 352/571] RLC AM: missing SN setup in Tx Pdu Management at first Tx --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index 27816ccb2c..113ee7d048 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -535,6 +535,7 @@ void rlc_am_segment_10 ( pdu_mngt_p->retx_count_next = 0; pdu_mngt_p->flags.retransmit = 0; pdu_mngt_p->flags.transmitted = 1; + pdu_mngt_p->sn = RLC_AM_PREV_SN(rlc_pP->vt_s); //TBC: What for resetting local pointers at the end ?? From 477a171fbcbb3568ef9fdf8b97f7302f1b0dfd50 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Tue, 7 Mar 2017 16:53:50 +0100 Subject: [PATCH 353/571] adding config file for TDD testing --- .../CONF/enb.band38.tm1.usrpb210.conf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf index 091997de9b..024be3b775 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf @@ -17,7 +17,7 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "94"; + mobile_network_code = "92"; ////////// Physical parameters: @@ -137,7 +137,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.70"; + mme_ip_address = ( { ipv4 = "192.168.12.26"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -147,10 +147,10 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.146/24"; - ENB_INTERFACE_NAME_FOR_S1U = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.146/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; From fd5932c5442e0a910a1a74839b6d9345c877efdd Mon Sep 17 00:00:00 2001 From: GabrielCouturier Date: Tue, 7 Mar 2017 16:58:39 +0100 Subject: [PATCH 354/571] RLC AM Tx: TPollRetx Expiry fix for BO --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c index 7c5d55800f..2dfa472523 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c @@ -92,11 +92,14 @@ rlc_am_check_timer_poll_retransmit( sn, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id); if ((tx_data_pdu_buffer_p->flags.ack == 0) && (tx_data_pdu_buffer_p->flags.max_retransmit == 0)) { tx_data_pdu_buffer_p->flags.retransmit = 1; + tx_data_pdu_buffer_p->retx_payload_size = tx_data_pdu_buffer_p->payload_size; if (tx_data_pdu_buffer_p->retx_count == tx_data_pdu_buffer_p->retx_count_next) { tx_data_pdu_buffer_p->retx_count_next ++; } rlc_pP->retrans_num_pdus += 1; rlc_pP->retrans_num_bytes_to_retransmit += tx_data_pdu_buffer_p->payload_size; + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[T_POLL_RETRANSMIT] TIME-OUT PUT SN=%d in ReTx Buffer\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),tx_data_pdu_buffer_p->sn); break; } else From b5ab7267c24b39d3aa855cc0a004572826733de5 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 7 Mar 2017 17:51:29 +0100 Subject: [PATCH 355/571] RLC AM fix for PDU insertion in case of gaps --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c | 10 +++++++--- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c index acc047d633..d2a5cc985e 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c @@ -323,8 +323,9 @@ rlc_am_receive_process_data_pdu ( if (RLC_AM_SN_IN_WINDOW(pdu_info_p->sn, rlc_pP->vr_r)) { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] VR(R) %04d VR(H) %04d VR(MR) %04d VR(MS) %04d VR(X) %04d\n", + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SN=%04d] VR(R) %04d VR(H) %04d VR(MR) %04d VR(MS) %04d VR(X) %04d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_info_p->sn, rlc_pP->vr_r, rlc_pP->vr_h, rlc_pP->vr_mr, @@ -433,12 +434,15 @@ rlc_am_receive_process_data_pdu ( } } - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] VR(R) %04d VR(H) %04d VR(MS) %04d VR(MR) %04d\n", + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SN=%04d] NEW VR(R) %04d VR(H) %04d VR(MS) %04d VR(MR) %04d VR(X) %04d reassemble=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + pdu_info_p->sn, rlc_pP->vr_r, rlc_pP->vr_h, rlc_pP->vr_ms, - rlc_pP->vr_mr); + rlc_pP->vr_mr, + rlc_pP->vr_x, + reassemble); } else { rlc_pP->stat_rx_data_pdu_out_of_window += 1; rlc_pP->stat_rx_data_bytes_out_of_window += tb_size_in_bytesP; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index e8c63a8e40..f0ae6a7888 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -505,7 +505,20 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( // First case : cursor_p is NULL, it means the SN is received for the first time // Insert PDU after previous_cursor_p if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { - list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + rlc_usn_t sn_prev = ((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info.sn; + if (RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(pdu_rx_info_p->sn,rlc_pP->vr_r)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SN=%d] PDU INSERTED AFTER PDU SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, + ((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info.sn); + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + } + else { /* SN of head of Rx PDU list is higher than received PDU SN */ + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SN=%d] PDU INSERTED BEFORE PDU SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, + pdu_info_cursor_p->sn); + list2_insert_before_element(tb_pP, cursor_p, &rlc_pP->receiver_buffer); + } + return pdu_status; } From ce1ac08b19f1ba1caab64b9e941152fe73c0b9ff Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 7 Mar 2017 18:33:14 +0100 Subject: [PATCH 356/571] RLC AM fix for PDU Segment insertion in case of gaps --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index f0ae6a7888..69201d7066 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -320,9 +320,20 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( // First case : cursor_p is NULL or its SN is different from the received one, it means the SN is received for the first time // Insert PDU after previous_cursor_p if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] STORE FIRST PDU SEGMENT FOR SN=%d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); - list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + rlc_usn_t sn_prev = pdu_info_previous_cursor_p->sn; + if (RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(pdu_rx_info_p->sn,rlc_pP->vr_r)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d] PDU SEGMENT INSERTED AFTER PDU SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, + sn_prev); + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + } + else { /* SN of head of Rx PDU list is higher than received PDU SN */ + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d] PDU SEGMENT INSERTED BEFORE PDU SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, + pdu_info_cursor_p->sn); + list2_insert_before_element(tb_pP, cursor_p, &rlc_pP->receiver_buffer); + } + return RLC_AM_DATA_PDU_STATUS_OK; } From ff6d41b6e83b3daa1d552d6d7379f491785c763e Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 1 Mar 2017 18:36:10 +0100 Subject: [PATCH 357/571] [OAI-UE] Mimo feature --- .../lte_dl_bf_channel_estimation.c | 4 +- openair1/PHY/LTE_TRANSPORT/dci.c | 37 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 83 ++-- openair1/PHY/LTE_TRANSPORT/defs.h | 2 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 39 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 87 +++- openair1/PHY/LTE_TRANSPORT/print_stats.c | 22 +- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 4 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 2 +- openair1/PHY/MODULATION/slot_fep.c | 2 +- openair1/PHY/TOOLS/lte_phy_scope.c | 18 +- openair1/PHY/TOOLS/lte_phy_scope_tm4.c | 28 +- openair1/PHY/defs.h | 10 +- openair1/SCHED/phy_procedures_lte_ue.c | 401 ++++++++++++------ openair1/SCHED/pucch_pc.c | 10 +- openair2/RRC/LITE/L2_interface.c | 8 +- openair3/NAS/TOOLS/network.h | 2 +- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 8 +- targets/RT/USER/lte-ue.c | 9 + targets/SIMU/USER/init_lte.c | 36 +- 20 files changed, 561 insertions(+), 251 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c index 02b5102ae5..7e112342ce 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c @@ -51,10 +51,10 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue, int uespec_pilot[300]; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; - LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch[eNB_id]; + LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch[(Ns>>1)&0x1][eNB_id]; LTE_DL_UE_HARQ_t *dlsch0_harq; - harq_pid = dlsch_ue[0]->current_harq_pid; + harq_pid = dlsch_ue[0]->current_harq_pid; dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid]; if (((frame_parms->Ncp == NORMAL) && (symbol>=7)) || diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 49fe90bf15..44cc3fffbf 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -2893,15 +2893,15 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, break; case 2: - *CCEmap|=(0x03<<(CCEind&0x1f)); + *CCEmap|=(1<<(CCEind&0x1f)); break; case 4: - *CCEmap|=(0x0f<<(CCEind&0x1f)); + *CCEmap|=(1<<(CCEind&0x1f)); break; case 8: - *CCEmap|=(0xff<<(CCEind&0x1f)); + *CCEmap|=(1<<(CCEind&0x1f)); break; } @@ -3518,7 +3518,9 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, } else if (tmode == 3) { + LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1\n"); // Now check UE_SPEC format 2A_2A search spaces at aggregation 1 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3527,7 +3529,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, mi, SI_RNTI, ra_rnti, - P_RNTI, + P_RNTI, 0, format1A, format1A, @@ -3542,14 +3544,18 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, &CCEmap1, &CCEmap2); + LOG_D(PHY," format 2A_2A search CCEmap0 %x, format0_found %d, format_c_found %d \n", CCEmap0, format0_found, format_c_found); if ((CCEmap0==0xffff)|| ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 2 search spaces at aggregation 2 + LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 2\n"); + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3577,10 +3583,13 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); // Now check UE_SPEC format 2_2A search spaces at aggregation 4 + LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n"); + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3589,7 +3598,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, mi, SI_RNTI, ra_rnti, - P_RNTI, + P_RNTI, 2, format1A, format1A, @@ -3608,11 +3617,14 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, ((format0_found==1)&&(format_c_found==1))) return(dci_cnt); + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); if (dci_cnt>old_dci_cnt) return(dci_cnt); //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 2_2A search spaces at aggregation 8 + LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 8 \n"); + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3636,9 +3648,17 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, &CCEmap1, &CCEmap2); //#endif + if ((CCEmap0==0xffff)|| + ((format0_found==1)&&(format_c_found==1))) + return(dci_cnt); + + LOG_D(PHY," format 2A_2A search dci_cnt %d, old_dci_cn t%d \n", dci_cnt, old_dci_cnt); + if (dci_cnt>old_dci_cnt) + return(dci_cnt); } else if (tmode == 4) { // Now check UE_SPEC format 2_2A search spaces at aggregation 1 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3670,6 +3690,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); // Now check UE_SPEC format 2 search spaces at aggregation 2 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3701,6 +3722,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); // Now check UE_SPEC format 2_2A search spaces at aggregation 4 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3733,6 +3755,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 2_2A search spaces at aggregation 8 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3762,6 +3785,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, #ifdef DEBUG_DCI_DECODING LOG_I(PHY," MU-MIMO check UE_SPEC format 1E_2A_M10PRB\n"); #endif + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3794,6 +3818,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 2 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3825,6 +3850,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); // Now check UE_SPEC format 1E_2A_M10PRB search spaces aggregation 4 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, @@ -3858,6 +3884,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 1E_2A_M10PRB search spaces at aggregation 8 + old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, dci_alloc, diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 9f4749cdc6..b9b1f6c0ad 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4769,10 +4769,12 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, uint8_t harq_pid = pdci_info_extarcted->harq_pid; uint32_t rballoc = pdci_info_extarcted->rballoc; uint8_t mcs1 = pdci_info_extarcted->mcs1; - uint8_t rv1 = pdci_info_extarcted->rv1; - uint8_t ndi1 = pdci_info_extarcted->ndi1; uint8_t TPC = pdci_info_extarcted->TPC; uint8_t rah = pdci_info_extarcted->rah; +#ifdef DEBUG_DCI + uint8_t rv1 = pdci_info_extarcted->rv1; + uint8_t ndi1 = pdci_info_extarcted->ndi1; +#endif uint8_t NPRB = 0; long long int RIV_max = 0; @@ -4983,13 +4985,18 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, uint8_t rv2 = pdci_info_extarcted->rv2; uint8_t harq_pid = pdci_info_extarcted->harq_pid; uint32_t rballoc = pdci_info_extarcted->rballoc; + +#ifdef DEBUG_DCI uint8_t ndi1 = pdci_info_extarcted->ndi1; uint8_t ndi2 = pdci_info_extarcted->ndi2; +#endif uint8_t NPRB = 0; long long RIV_max = 0; +#ifdef DEBUG_DCI LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format); + LOG_I(PHY, "extarcted dci - rnti %d \n", rnti); LOG_I(PHY, "extarcted dci - rah %d \n", rah); LOG_I(PHY, "extarcted dci - mcs1 %d \n", mcs1); LOG_I(PHY, "extarcted dci - mcs2 %d \n", mcs2); @@ -5001,6 +5008,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, LOG_I(PHY, "extarcted dci - harq pif %d \n", harq_pid); LOG_I(PHY, "extarcted dci - round0 %d \n", pdlsch0_harq->round); LOG_I(PHY, "extarcted dci - round1 %d \n", pdlsch1_harq->round); +#endif // I- check dci content minimum coherency if(harq_pid >8) @@ -5043,6 +5051,21 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, }*/ + if((pdlsch0_harq->round == 0) && (rv1 > 0)) + { + // DCI false detection + LOG_I(PHY,"bad rv1\n"); + return(0); + } + + if((pdlsch1_harq->round == 0) && (rv2 > 0)) + { + // DCI false detection + LOG_I(PHY,"bad rv2\n"); + return(0); + } + + switch (N_RB_DL) { case 6: if (rah == 0) @@ -5606,6 +5629,7 @@ void compute_precoding_info_format2A(uint8_t tpmi, void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, LTE_DL_FRAME_PARMS *frame_parms, + uint16_t rnti, uint8_t subframe, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq, @@ -5663,15 +5687,17 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, dlsch1_harq->dl_power_off = 1; pdlsch0->current_harq_pid = harq_pid; - pdlsch0->harq_ack[subframe].harq_id = harq_pid; + pdlsch0->harq_ack[subframe].harq_id = harq_pid; pdlsch1->current_harq_pid = harq_pid; - pdlsch1->harq_ack[subframe].harq_id = harq_pid; + pdlsch1->harq_ack[subframe].harq_id = harq_pid; // assume two CW are active dlsch0_harq->status = ACTIVE; dlsch1_harq->status = ACTIVE; pdlsch0->active = 1; pdlsch1->active = 1; + pdlsch0->rnti = rnti; + pdlsch1->rnti = rnti; if (TB0_active && TB1_active && tbswap==1) { @@ -5690,12 +5716,8 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, if (TB1_active==0) { dlsch1_harq->status = SCH_IDLE; pdlsch1->active = 0; -#ifdef DEBUG_HARQ - printf("[DCI UE]: TB1 is deactivated, retransmit TB0 transmit in TM6\n"); -#endif } - #ifdef DEBUG_HARQ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); #endif @@ -5727,6 +5749,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; + + //dlsch0_harq->Nl = 1; + //dlsch1_harq->Nl = 1; } } else if ((TB0_active == 0) && (TB1_active == 1)){ @@ -5774,24 +5799,28 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { dlsch0_harq->round = 0; + //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n", + // subframe,harq_pid,dlsch0_harq->round); if ( dlsch0_harq->first_tx==1) { LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); dlsch0_harq->first_tx = 0; } }else{ if(dlsch0_harq->round == 0) { +#if 0 // skip pdsch decoding and report ack dlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; pdlsch0->harq_ack[subframe].ack = 1; pdlsch0->harq_ack[subframe].harq_id = harq_pid; pdlsch0->harq_ack[subframe].send_harq_status = 1; +#endif } } dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - if(dlsch0_harq->Nl == 2) - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; + //if(dlsch0_harq->Nl == 2) + //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; if (mcs1 <= 28) dlsch0_harq->Qm = get_Qm(mcs1); else if (mcs1<=31) @@ -5801,11 +5830,14 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, if (TB1_active) { if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { dlsch1_harq->round = 0; + //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n", + // subframe,harq_pid,dlsch0_harq->round); if (dlsch1_harq->first_tx==1) { LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); dlsch1_harq->first_tx = 0; } }else{ +#if 0 if(dlsch1_harq->round == 0) { // skip pdsch decoding and report ack dlsch1_harq->status = SCH_IDLE; @@ -5814,11 +5846,12 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, pdlsch1->harq_ack[subframe].harq_id = harq_pid; pdlsch1->harq_ack[subframe].send_harq_status = 1; } +#endif } dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - if(dlsch0_harq->Nl == 2) - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; + //if(dlsch0_harq->Nl == 2) + //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; if (mcs2 <= 28) dlsch1_harq->Qm = get_Qm(mcs2); @@ -6047,7 +6080,7 @@ int generate_ue_dlsch_params_from_dci(int frame, case format2: { // extract dci infomation - LOG_I(PHY,"[DCI-format2] extract dci infomation \n"); + //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame, subframe); extract_dci2_info(frame_parms->N_RB_DL, frame_type, frame_parms->nb_antenna_ports_eNB, @@ -6069,7 +6102,7 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; - LOG_I(PHY,"[DCI-format2] check dci content \n"); + //LOG_I(PHY,"[DCI-format2] check dci content \n"); status = check_dci_format2_2a_coherency(format2, frame_parms->N_RB_DL, &dci_info_extarcted, @@ -6083,10 +6116,11 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); // dci is correct ==> update internal structure and prepare dl decoding - LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n"); + //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n"); prepare_dl_decoding_format2_2A(format2, &dci_info_extarcted, frame_parms, + rnti, subframe, dlsch0_harq, dlsch1_harq, @@ -6099,7 +6133,7 @@ int generate_ue_dlsch_params_from_dci(int frame, case format2A: { // extract dci infomation - LOG_I(PHY,"[DCI-format2A] extract dci infomation \n"); + //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe); extract_dci2A_info(frame_parms->N_RB_DL, frame_type, frame_parms->nb_antenna_ports_eNB, @@ -6107,10 +6141,10 @@ int generate_ue_dlsch_params_from_dci(int frame, &dci_info_extarcted); // check dci content - LOG_I(PHY,"[DCI-format2A] check dci content \n"); - LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid); - dlsch[0]->active = 0; - dlsch[1]->active = 0; + //LOG_I(PHY,"[DCI-format2A] check dci content \n"); + //LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid); + //dlsch[0]->active = 0; + //dlsch[1]->active = 0; if (dci_info_extarcted.tb_swap == 0) { dlsch0 = dlsch[0]; @@ -6122,7 +6156,7 @@ int generate_ue_dlsch_params_from_dci(int frame, dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; - LOG_I(PHY,"[DCI-format2A] check dci content \n"); + //LOG_I(PHY,"[DCI-format2A] check dci content \n"); status = check_dci_format2_2a_coherency(format2A, frame_parms->N_RB_DL, &dci_info_extarcted, @@ -6136,10 +6170,11 @@ int generate_ue_dlsch_params_from_dci(int frame, return(-1); // dci is correct ==> update internal structure and prepare dl decoding - LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n"); + //LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n"); prepare_dl_decoding_format2_2A(format2A, &dci_info_extarcted, frame_parms, + rnti, subframe, dlsch0_harq, dlsch1_harq, @@ -7142,7 +7177,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, uint8_t transmission_mode = ue->transmission_mode[eNB_id]; ANFBmode_t AckNackFBMode; LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - LTE_UE_DLSCH_t **dlsch = ue->dlsch[0]; + LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe&0x1][0]; PHY_MEASUREMENTS *meas = &ue->measurements; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; // uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; @@ -7947,7 +7982,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, if (frame_parms->frame_type == FDD) { int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); - if (ue->dlsch[eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission + if (ue->dlsch[dl_subframe&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission ulsch->harq_processes[harq_pid]->O_ACK = 1; } else { ulsch->harq_processes[harq_pid]->O_ACK = 0; diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index 3b13c01c52..f6293bf1b2 100755 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -708,7 +708,7 @@ typedef struct { int16_t sqrt_rho_a; /// amplitude of PDSCH (compared to RS) in symbols containing pilots int16_t sqrt_rho_b; - /// Current HARQ process id + /// Current HARQ process id threadRx Odd and threadRx Even uint8_t current_harq_pid; /// Current subband antenna selection uint32_t antenna_alloc; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 04794e3ffc..48d6bb86be 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -38,6 +38,7 @@ #include "SIMULATION/TOOLS/defs.h" //#define DEBUG_DLSCH_DECODING +extern double cpuf; void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { @@ -270,7 +271,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, return(max_turbo_iterations); }*/ - /*harq_pid = dlsch->current_harq_pid; + /*harq_pid = dlsch->current_harq_pid[subframe&0x1]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); return(max_turbo_iterations); @@ -341,6 +342,8 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus); #endif + opp_enabled=1; + for (r=0; rC; r++) { @@ -376,7 +379,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, (r==0) ? harq_process->F : 0); #ifdef DEBUG_DLSCH_DECODING - LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", + LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", harq_pid,r, G, Kr*3, harq_process->TBS, @@ -459,6 +462,10 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, #if 1 if (err_flag == 0) { + LOG_D(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", + Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS, + harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations); + if (llr8_flag) { AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); @@ -605,6 +612,13 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); stop_meas(dlsch_turbo_decoding_stats); + printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n", + harq_process->C, + r, + dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0), + dlsch_deinterleaving_stats->p_time/(cpuf*1000.0), + dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0)); + } } } @@ -636,25 +650,28 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, harq_process->round++; - if(is_crnti) - { - LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); - } // printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); if (harq_process->round >= dlsch->Mdlharq) { harq_process->status = SCH_IDLE; + harq_process->round = 0; + } + if(is_crnti) + { + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } return((1+dlsch->max_turbo_iterations)); } else { - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, round %d, subframe %d)\n", - phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->round, subframe); harq_process->status = SCH_IDLE; harq_process->round = 0; dlsch->harq_ack[subframe].ack = 1; dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].send_harq_status = 1; + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, pid status %d, round %d, subframe %d)\n", + phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->status, harq_process->round, subframe); + if(is_crnti) { LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); @@ -908,7 +925,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; case PDSCH: // TB0 - dlsch_ue = phy_vars_ue->dlsch[eNB_id][0]; + dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]; harq_pid = dlsch_ue->current_harq_pid; ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]); DevAssert( ue_id != (uint32_t)-1 ); @@ -954,7 +971,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; case PDSCH1: { // TB1 - dlsch_ue = phy_vars_ue->dlsch[eNB_id][1]; + dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]; harq_pid = dlsch_ue->current_harq_pid; int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] ); DevAssert( UE_id != -1 ); @@ -1008,7 +1025,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; default: - dlsch_ue = phy_vars_ue->dlsch[eNB_id][0]; + dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]; LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id); dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations; return(1+dlsch_ue->max_turbo_iterations); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 601eacc620..9ae212cd27 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -121,6 +121,7 @@ int rx_pdsch(PHY_VARS_UE *ue, + switch (type) { case SI_PDSCH: pdsch_vars = &ue->pdsch_vars_SI[eNB_id]; @@ -138,16 +139,18 @@ int rx_pdsch(PHY_VARS_UE *ue, case PDSCH: pdsch_vars = &ue->pdsch_vars[subframe&0x1][eNB_id]; - dlsch = ue->dlsch[eNB_id]; + dlsch = ue->dlsch[subframe&0x1][eNB_id]; + LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", + frame,subframe,symbol,harq_pid, + dlsch[0]->harq_processes[harq_pid]->status, + dlsch[1]->harq_processes[harq_pid]->status); + if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)){ codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword; codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword; dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid]; dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid]; -#ifdef DEBUG_HARQ - printf("I am assuming both CW active\n"); -#endif } else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) { @@ -159,8 +162,8 @@ int rx_pdsch(PHY_VARS_UE *ue, else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) && (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){ codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword; - dlsch0_harq = dlsch[1]->harq_processes[harq_pid]; - dlsch1_harq = NULL; + dlsch0_harq = dlsch[1]->harq_processes[harq_pid]; + dlsch1_harq = NULL; codeword_TB0 = -1; } else { @@ -230,6 +233,9 @@ int rx_pdsch(PHY_VARS_UE *ue, } } + //LOG_I(PHY,"[rx_pdsch %d] AbsSubframe %d.%d symbol %d rxType %d beamformingMode %d, antennaPorts %d, eNB_id_i %d, n_connected_eNB %d\n", + // harq_pid, frame,subframe, symbol,rx_type, beamforming_mode, frame_parms->nb_antenna_ports_eNB,eNB_id_i,ue->n_connected_eNB); + if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) { #ifdef DEBUG_DLSCH_MOD LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]); @@ -336,7 +342,7 @@ int rx_pdsch(PHY_VARS_UE *ue, LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); } - // printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id); + //printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id); if (nb_rb==0) { LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); return(-1); @@ -383,6 +389,7 @@ int rx_pdsch(PHY_VARS_UE *ue, ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { + //LOG_I(PHY,"Channel Level TM34 !!!!!!!! \n"); dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, pdsch_vars[eNB_id]->pmi_ext, @@ -392,21 +399,23 @@ int rx_pdsch(PHY_VARS_UE *ue, nb_rb, dlsch0_harq->mimo_mode); + LOG_D(PHY,"Channel Level TM34 avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, interf_unaw_shift %d \n", avg_0[0], + avg_1[0], rx_type, rx_standard, interf_unaw_shift); if (rx_type>rx_standard) { - avg_0[0] = (log2_approx(avg_0[0])/2) -13 + interf_unaw_shift; - avg_1[0] = (log2_approx(avg_1[0])/2) -13 + interf_unaw_shift; + avg_0[0] = (log2_approx(avg_0[0])/2) - 5 + 2 ;//+ 2; + avg_1[0] = (log2_approx(avg_1[0])/2) - 5 + 2 ;//+ 2; pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - //printf("TM4 I-A log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - //printf("TM4 I-A log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + //printf("TM4 I-A log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0); + //printf("TM4 I-A log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1); } else { avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - //printf("TM4 I-UA log2_maxh0 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh0); - //printf("TM4 I-UA log2_maxh1 = %d\n", lte_ue_pdsch_vars[eNB_id]->log2_maxh1); + //printf("TM4 I-UA log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0); + //printf("TM4 I-UA log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1); } } else if (dlsch0_harq->mimo_modelog2_maxh,avg[0],avgs); - LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); + LOG_I(PHY,"[DLSCH] log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh, + pdsch_vars[eNB_id]->log2_maxh0, + pdsch_vars[eNB_id]->log2_maxh1, + avg[0],avgs); + LOG_I(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); #endif } @@ -511,6 +523,7 @@ int rx_pdsch(PHY_VARS_UE *ue, } } else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ + //LOG_I(PHY,"channel compensation TM34 !!!!!!!!!!!!!!!!!\n"); dlsch_channel_compensation_TM34(frame_parms, pdsch_vars[eNB_id], measurements, @@ -663,6 +676,7 @@ int rx_pdsch(PHY_VARS_UE *ue, ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 if (frame_parms->nb_antenna_ports_eNB == 2) { + //LOG_I(PHY,"MRC Detection TM34 !!!!!!!!!\n"); dlsch_detection_mrc_TM34(frame_parms, pdsch_vars[eNB_id], harq_pid, @@ -724,6 +738,10 @@ int rx_pdsch(PHY_VARS_UE *ue, //i_mod should have been passed as a parameter } + //LOG_I(PHY,"compute LLRs rx_type dual ? %d rx_standard %d codeword_TB0 %d codeword_TB1 %d\n", rx_type==rx_IC_dual_stream, rx_standard, codeword_TB0, codeword_TB1); + //if (rx_type >= rx_IC_single_stream) + //LOG_I(PHY,"LLR0 Qm ? %d LLR1 Qm \n", dlsch0_harq->Qm, dlsch1_harq->Qm); + switch (dlsch0_harq->Qm) { case 2 : if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { @@ -805,6 +823,7 @@ int rx_pdsch(PHY_VARS_UE *ue, } break; case 4 : + if ((rx_type==rx_standard ) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { dlsch_16qam_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, @@ -978,6 +997,7 @@ int rx_pdsch(PHY_VARS_UE *ue, return(-1); break; } + if (dlsch1_harq) { switch (get_Qm(dlsch1_harq->mcs)) { case 2 : @@ -1023,6 +1043,43 @@ int rx_pdsch(PHY_VARS_UE *ue, } } +#if 0 + if( (symbol == 13) && (dlsch0_harq->mimo_mode == 2) ) + { + LOG_E(PHY,"Dump Phy Chan Est \n"); + if(subframe&0x1) + { +#if 1 + //write_output("rxdataF0.m" , "rxdataF0", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); + //write_output("rxdataF1.m" , "rxdataF1", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); + //write_output("dl_ch_estimates00.m", "dl_ch_estimates00", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1); + //write_output("dl_ch_estimates01.m", "dl_ch_estimates01", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1); + //write_output("dl_ch_estimates10.m", "dl_ch_estimates10", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1); + //write_output("dl_ch_estimates11.m", "dl_ch_estimates11", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1); + + + //write_output("rxdataF_ext00.m" , "rxdataF_ext00", &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("rxdataF_ext01.m" , "rxdataF_ext01", &pdsch_vars[eNB_id]->rxdataF_ext[1][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("rxdataF_ext10.m" , "rxdataF_ext10", &pdsch_vars[eNB_id]->rxdataF_ext[2][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("rxdataF_ext11.m" , "rxdataF_ext11", &pdsch_vars[eNB_id]->rxdataF_ext[3][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("dl_ch_estimates_ext01.m", "dl_ch_estimates_ext01", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[1][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("dl_ch_estimates_ext10.m", "dl_ch_estimates_ext10", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[2][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("dl_ch_estimates_ext11.m", "dl_ch_estimates_ext11", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[3][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp00.m","rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp01.m","rxdataF_comp01", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp10.m","rxdataF_comp10", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp11.m","rxdataF_comp11", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); +#endif + write_output("llr0.m","llr0", &pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + write_output("llr1.m","llr1", &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + + + AssertFatal(0," "); + } + + } +#endif #if T_TRACER T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame%1024), diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c index c8d4292e8d..c3e40e1e72 100644 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c @@ -107,9 +107,9 @@ int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length len += sprintf(&buffer[len], "[UE PROC] Po_PUCCH = %d dBm (Po_NOMINAL_PUCCH %d dBm, g_pucch %d dB)\n", get_PL(ue->Mod_id,ue->CC_id,0)+ ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+ - ue->dlsch[0][0]->g_pucch, + ue->dlsch[0][0][0]->g_pucch, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, - ue->dlsch[0][0]->g_pucch); + ue->dlsch[0][0][0]->g_pucch); } //for (eNB=0;eNBmeasurements.precoded_cqi_dB[eNB][0]); for (harq_pid=0;harq_pid<8;harq_pid++) { - len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 0 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][0]->harq_processes[harq_pid]->mcs); + len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 0 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][0][0]->harq_processes[harq_pid]->mcs); for (round=0;round<8;round++) len+=sprintf(&buffer[len],"%d/%d ", - ue->dlsch[0][0]->harq_processes[harq_pid]->errors[round], - ue->dlsch[0][0]->harq_processes[harq_pid]->trials[round]); + ue->dlsch[0][0][0]->harq_processes[harq_pid]->errors[round], + ue->dlsch[0][0][0]->harq_processes[harq_pid]->trials[round]); len+=sprintf(&buffer[len],"\n"); } - if (ue->dlsch[0] && ue->dlsch[0][0] && ue->dlsch[0][1]) { - len += sprintf(&buffer[len], "[UE PROC] Saved PMI for DLSCH eNB %d : %jx (%p)\n",eNB,pmi2hex_2Ar1(ue->dlsch[0][0]->pmi_alloc),ue->dlsch[0][0]); + if (ue->dlsch[0][0] && ue->dlsch[0][0][0] && ue->dlsch[0][0][1]) { + len += sprintf(&buffer[len], "[UE PROC] Saved PMI for DLSCH eNB %d : %jx (%p)\n",eNB,pmi2hex_2Ar1(ue->dlsch[0][0][0]->pmi_alloc),ue->dlsch[0][0][0]); - len += sprintf(&buffer[len], "[UE PROC] eNB %d: dl_power_off = %d\n",eNB,ue->dlsch[0][0]->harq_processes[0]->dl_power_off); + len += sprintf(&buffer[len], "[UE PROC] eNB %d: dl_power_off = %d\n",eNB,ue->dlsch[0][0][0]->harq_processes[0]->dl_power_off); for (harq_pid=0;harq_pid<8;harq_pid++) { - len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 1 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][1]->harq_processes[0]->mcs); + len+=sprintf(&buffer[len],"[UE PROC] eNB %d: CW 1 harq_pid %d, mcs %d:",eNB,harq_pid,ue->dlsch[0][0][1]->harq_processes[0]->mcs); for (round=0;round<8;round++) len+=sprintf(&buffer[len],"%d/%d ", - ue->dlsch[0][1]->harq_processes[harq_pid]->errors[round], - ue->dlsch[0][1]->harq_processes[harq_pid]->trials[round]); + ue->dlsch[0][0][1]->harq_processes[harq_pid]->errors[round], + ue->dlsch[0][0][1]->harq_processes[harq_pid]->trials[round]); len+=sprintf(&buffer[len],"\n"); } } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 9571ea6cd5..dbb7a16ac9 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -233,7 +233,7 @@ uint32_t ulsch_encoding(uint8_t *a, LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; PHY_MEASUREMENTS *meas = &ue->measurements; LTE_UE_ULSCH_t *ulsch=ue->ulsch[eNB_id]; - LTE_UE_DLSCH_t **dlsch = ue->dlsch[eNB_id]; + LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id]; uint16_t rnti = 0xffff; if (!ulsch) { @@ -966,7 +966,7 @@ int ulsch_encoding_emul(uint8_t *ulsch_buffer, { LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - LTE_UE_DLSCH_t **dlsch = ue->dlsch[eNB_id]; + LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id]; PHY_MEASUREMENTS *meas = &ue->measurements; uint8_t tmode = ue->transmission_mode[eNB_id]; uint16_t rnti=ue->pdcch_vars[eNB_id]->crnti; diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index ca67ccdb3c..bb2a5b3e22 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -2066,7 +2066,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, // get local ue's ack if ((UE_index >= oai_emulation.info.first_ue_local) ||(UE_index <(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local))) { get_ack(&eNB->frame_parms, - PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0]->harq_ack, + PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0][0]->harq_ack, subframe, eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0); } else { // get remote UEs' ack diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index 3a3b3b4c0d..4b663776df 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -48,7 +48,7 @@ int slot_fep(PHY_VARS_UE *ue, unsigned int rx_offset; /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id]; - unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; + unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid]; int uespec_pilot[9][1200];*/ diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index ca08f87519..681ee0b51c 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -510,16 +510,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) { - harq_pid = phy_vars_ue->dlsch[eNB_id][0]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs = phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->mcs; + mcs = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 - if(!phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { + if(!phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { // we are in TM5 fl_show_object(form->button_0); } @@ -530,12 +530,12 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) { + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { coded_bits_per_codeword = get_G(frame_parms, - phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs), - phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, @@ -768,4 +768,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } free(chest_t_abs); -} \ No newline at end of file +} diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index 60c5ace2c5..6807f1f6f4 100755 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -448,11 +448,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int mcs1=0; unsigned char harq_pid = 0; int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) { - harq_pid = phy_vars_ue->dlsch[eNB_id][0]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs0 = phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->mcs; + mcs0 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 /* if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { @@ -461,23 +461,23 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } */ } - if (phy_vars_ue->dlsch[eNB_id][1]!=NULL) { - harq_pid = phy_vars_ue->dlsch[eNB_id][1]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid; if (harq_pid>=8) return; - mcs1 = phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->mcs; + mcs1 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs; } if (phy_vars_ue->pdcch_vars[eNB_id]!=NULL) { num_pdcch_symbols = phy_vars_ue->pdcch_vars[eNB_id]->num_pdcch_symbols; } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - if (phy_vars_ue->dlsch[eNB_id][0]!=NULL) { + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { mod0 = get_Qm(mcs0); coded_bits_per_codeword0 = get_G(frame_parms, - phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs0), - phy_vars_ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, @@ -486,13 +486,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); mod0=0; } - if (phy_vars_ue->dlsch[eNB_id][1]!=NULL) { + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) { mod1 = get_Qm(mcs1); coded_bits_per_codeword1 = get_G(frame_parms, - phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs1), - phy_vars_ue->dlsch[eNB_id][1]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index d70bfb3f72..024e8ddf59 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -706,7 +706,7 @@ typedef struct { LTE_DL_FRAME_PARMS frame_parms_before_ho; LTE_UE_COMMON common_vars; - LTE_UE_PDSCH *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; + LTE_UE_PDSCH *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads LTE_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1]; @@ -715,7 +715,7 @@ typedef struct { LTE_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_PDCCH *pdcch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_DLSCH_t *dlsch[NUMBER_OF_CONNECTED_eNB_MAX][2]; + LTE_UE_DLSCH_t *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads LTE_UE_ULSCH_t *ulsch[NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX]; @@ -872,7 +872,7 @@ typedef struct { time_stats_t phy_proc; time_stats_t phy_proc_tx; - time_stats_t phy_proc_rx; + time_stats_t phy_proc_rx[2]; uint32_t use_ia_receiver; @@ -885,6 +885,10 @@ typedef struct { time_stats_t ulsch_interleaving_stats; time_stats_t ulsch_multiplexing_stats; + time_stats_t generic_stat; + time_stats_t pdsch_procedures_stat; + time_stats_t dlsch_procedures_stat; + time_stats_t ofdm_demod_stats; time_stats_t dlsch_rx_pdcch_stats; time_stats_t rx_dft_stats; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index cd8fbdbc8e..42c75bdc7c 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -75,6 +75,7 @@ fifo_dump_emos_UE emos_dump_UE; extern int oai_exit; +extern double cpuf; @@ -90,10 +91,10 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; coded_bits_per_codeword = get_G(&ue->frame_parms, - ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb, - ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm, - ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, ue->pdcch_vars[eNB_id]->num_pdcch_symbols, proc->frame_rx, subframe, @@ -268,37 +269,39 @@ void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) uint8_t i,j,k,s; PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; - //[NUMBER_OF_CONNECTED_eNB_MAX][2]; - for(i=0; idlsch[i][j]) { - for(k=0; kdlsch[i][j]->harq_processes[k]; k++) { - ue->dlsch[i][j]->harq_processes[k]->status = SCH_IDLE; - for (s=0; s<10; s++) { - // reset ACK/NACK bit to DTX for all subframes s = 0..9 - ue->dlsch[i][j]->harq_ack[s].ack = 2; - ue->dlsch[i][j]->harq_ack[s].send_harq_status = 0; - ue->dlsch[i][j]->harq_ack[s].vDAI_UL = 0xff; - ue->dlsch[i][j]->harq_ack[s].vDAI_DL = 0xff; + //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2]; + for(int l=0; l<2; l++) { + for(i=0; idlsch[l][i][j]) { + for(k=0; kdlsch[l][i][j]->harq_processes[k]; k++) { + ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE; + for (s=0; s<10; s++) { + // reset ACK/NACK bit to DTX for all subframes s = 0..9 + ue->dlsch[l][i][j]->harq_ack[s].ack = 2; + ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0; + ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff; + ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff; + } + } + } } - } - } - } - //UL HARQ - if(ue->ulsch[i]) { - for(k=0; kulsch[i]->harq_processes[k]; k++) { - ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE; - //Set NDIs for all UL HARQs to 0 - // ue->ulsch[i]->harq_processes[k]->Ndi = 0; + //UL HARQ + if(ue->ulsch[i]) { + for(k=0; kulsch[i]->harq_processes[k]; k++) { + ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE; + //Set NDIs for all UL HARQs to 0 + // ue->ulsch[i]->harq_processes[k]->Ndi = 0; + + } + } + + // flush Msg3 buffer + ue->ulsch_Msg3_active[i] = 0; } - } - - // flush Msg3 buffer - ue->ulsch_Msg3_active[i] = 0; - } } @@ -327,7 +330,8 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) for (i=0; i<8; i++) { if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) { PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE; - PHY_vars_UE_g[Mod_id][CC_id]->dlsch[eNB_index][0]->harq_processes[i]->round=0; + PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0; + PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0; } } @@ -364,7 +368,7 @@ void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance) PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!! - LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); + LOG_I(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); } @@ -638,7 +642,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id uint8_t pucch_ack_payload[2]; if (get_ack(&ue->frame_parms, - ue->dlsch[eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx,pucch_ack_payload,0) > 0) { is_sr_an_subframe = 1; @@ -790,6 +794,7 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type, return pucch_format2; } } + return pucch_format1a; } uint16_t get_n1_pucch(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, @@ -929,11 +934,11 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; // set ACK/NAK to values if not DTX - if (ue->dlsch[eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed - harq_ack1 = ue->dlsch[eNB_id][0]->harq_ack[(6+last_dl)%10].ack; + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack; - if (ue->dlsch[eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack0 = ue->dlsch[eNB_id][0]->harq_ack[5+last_dl].ack; + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].ack; if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed @@ -1040,10 +1045,10 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; int ulsch_start; - int overflow=0; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + int overflow=0; int k,l; - int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16))); + int dummy_tx_buffer[3840*4] __attribute__((aligned(16))); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN); @@ -1069,22 +1074,18 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance; #endif //else EXMIMO -//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) if (empty_subframe) { //#if 1 overflow = ulsch_start - 9*frame_parms->samples_per_tti; for (aa=0; aanb_antennas_tx; aa++) { - if (overflow > 0) - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow)); - memset(&ue->common_vars.txdata[aa][0],0,4*overflow); - } - else - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti); - } + memset(&ue->common_vars.txdata[aa][ulsch_start],0, + 4*cmin(frame_parms->samples_per_tti-overflow,frame_parms->samples_per_tti)); + + if (overflow> 0) + memset(&ue->common_vars.txdata[aa][0],0,4*overflow); } /*#else overflow = ulsch_start - 9*frame_parms->samples_per_tti; @@ -1102,7 +1103,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif*/ return; } -//#endif +#endif if ((frame_tx%100) == 0) LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n", @@ -1336,7 +1337,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32))); uint8_t access_mode; uint8_t Nbundled=0; - uint8_t ack_status=0; + uint8_t ack_status_cw0=0; + uint8_t ack_status_cw1=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN); @@ -1437,11 +1439,16 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; } - ack_status = reset_ack(&ue->frame_parms, - ue->dlsch[eNB_id][0]->harq_ack, - subframe_tx, - ue->ulsch[eNB_id]->o_ACK,0); - Nbundled = ack_status; + ack_status_cw0 = reset_ack(&ue->frame_parms, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, + subframe_tx, + ue->ulsch[eNB_id]->o_ACK,0); + ack_status_cw1 = reset_ack(&ue->frame_parms, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack, + subframe_tx, + ue->ulsch[eNB_id]->o_ACK,1); + + Nbundled = ack_status_cw0; first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb; nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; @@ -1449,31 +1456,31 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB - if (ack_status > 0) { + if (ack_status_cw0 > 0) { // check if we received a PDSCH at subframe_tx - 4 // ==> send ACK/NACK on PUSCH - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1; + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; #if T_TRACER if(ue->ulsch[eNB_id]->o_ACK[0]) { LOG_I(PHY,"PUSCH ACK\n"); - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), - T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } else { LOG_I(PHY,"PUSCH NACK\n"); - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), - T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } #endif - LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", + LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", Mod_id, ue->ulsch[eNB_id]->rnti, - frame_tx%1024,subframe_tx, + frame_tx,subframe_tx, ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } @@ -1530,6 +1537,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB mac_xface->macphy_exit("Error in ulsch_coding"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_tx); + printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); return; } } @@ -1636,8 +1644,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif - LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", - Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); start_meas(&ue->ulsch_modulation_stats); ulsch_modulation(ue->common_vars.txdataF, tx_amp, @@ -1770,13 +1778,13 @@ void get_pucch_param(PHY_VARS_UE *ue, { pucch_resource[0] = get_n1_pucch(ue, proc, - ue->dlsch[eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, eNB_id, ack_payload, SR); pucch_payload[0] = ack_payload[0]; - //pucch_payload[1] = ack_payload[1]; - pucch_payload[1] = 1; + pucch_payload[1] = ack_payload[1]; + //pucch_payload[1] = 1; } break; @@ -1785,7 +1793,7 @@ void get_pucch_param(PHY_VARS_UE *ue, pucch_resource[0] = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex; if(cqi_report) { - pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,plength); + pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,(int*)plength); } else { @@ -1806,14 +1814,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin uint8_t pucch_ack_payload[2]; - uint8_t n1_pucch,n2_pucch; + uint8_t n2_pucch; uint16_t pucch_resource; ANFBmode_t bundling_flag; PUCCH_FMT_t format; uint8_t SR_payload; - uint16_t CQI_payload; - uint16_t RI_payload; uint8_t pucch_payload[2]; uint16_t len; @@ -1824,13 +1830,11 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin int CC_id = ue->CC_id; int tx_amp; int16_t Po_PUCCH; - uint8_t ack_status=0; uint8_t ack_status_cw0=0; uint8_t ack_status_cw1=0; uint8_t nb_cw=0; uint8_t cqi_status=0; uint8_t ri_status=0; - uint8_t ack_sr_generated = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN); @@ -1891,13 +1895,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } ack_status_cw0 = reset_ack(&ue->frame_parms, - ue->dlsch[eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx, pucch_ack_payload, 0); ack_status_cw1 = reset_ack(&ue->frame_parms, - ue->dlsch[eNB_id][1]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack, subframe_tx, pucch_ack_payload, 1); @@ -1936,11 +1940,10 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin SR_payload, cqi_status, &pucch_resource, - &pucch_payload, + (uint8_t *)&pucch_payload, &len); - LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", - frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); + LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); // Part - IV @@ -1971,13 +1974,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif if(format == pucch_format1) { LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", Mod_id, - ue->dlsch[eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx, subframe_tx, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, isShortenPucch, @@ -1989,7 +1992,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin if (SR_payload>0) { LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", Mod_id, - ue->dlsch[eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, (format == pucch_format1a? "1a": ( format == pucch_format1b? "1b" : "??")), @@ -2002,7 +2005,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } else { LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, - ue->dlsch[eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, (format == pucch_format1a? "1a": ( format == pucch_format1b? "1b" : "??")), @@ -2017,13 +2020,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #if T_TRACER if(pucch_payload[0]) { - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), - T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } else { - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti), - T_INT(ue->dlsch[eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } #endif @@ -2076,12 +2079,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif - LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", + LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", Mod_id, - ue->dlsch[eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, n2_pucch, Po_PUCCH, @@ -2106,13 +2109,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin case pucch_format2a: LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n", Mod_id, - ue->dlsch[eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); break; case pucch_format2b: LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n", Mod_id, - ue->dlsch[eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); break; default: @@ -2254,7 +2257,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui // reset DL ACK/NACK status reset_ack(&ue->frame_parms, - ue->dlsch[eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx, ue->ulsch[eNB_id]->o_ACK,0); @@ -2451,8 +2454,8 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id) emos_dump_UE.total_TBS_last = ue->total_TBS_last[eNB_id]; emos_dump_UE.bitrate = ue->bitrate[eNB_id]; emos_dump_UE.total_received_bits = ue->total_received_bits[eNB_id]; - emos_dump_UE.pmi_saved = ue->dlsch[eNB_id][0]->pmi_alloc; - emos_dump_UE.mcs = ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->mcs; + emos_dump_UE.pmi_saved = ue->dlsch[subframe&0x1][eNB_id][0]->pmi_alloc; + emos_dump_UE.mcs = ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mcs; emos_dump_UE.use_ia_receiver = openair_daq_vars.use_ia_receiver; bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE)); @@ -2859,7 +2862,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (void *)&dci_alloc_rx[i].dci_pdu, ue->pdcch_vars[eNB_id]->crnti, dci_alloc_rx[i].format, - ue->dlsch[eNB_id], + ue->dlsch[subframe_rx&0x1][eNB_id], &ue->frame_parms, ue->pdsch_config_dedicated, SI_RNTI, @@ -2876,7 +2879,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (dci_alloc_rx[i].format == format2A) || (dci_alloc_rx[i].format == format2B)) { - ue->dlsch[eNB_id][0]->g_pucch += ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->delta_PUCCH; + ue->dlsch[subframe_rx&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH; } ue->dlsch_received[eNB_id]++; @@ -2884,7 +2887,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format); dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[eNB_id][0]->active); + LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_rx&0x1][eNB_id][0]->active); #endif // we received a CRNTI, so we're in PUSCH @@ -3262,7 +3265,14 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC dual_stream_UE = 1; eNB_id_i = ue->n_connected_eNB; i_mod = dlsch0->harq_processes[harq_pid]->Qm; - } else { + } + else if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3)) + { + dual_stream_UE = rx_IC_dual_stream; + eNB_id_i = eNB_id; + i_mod = 0; + } + else { dual_stream_UE = 0; eNB_id_i = eNB_id+1; i_mod = 0; @@ -3401,11 +3411,34 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, int harq_pid; int frame_rx = proc->frame_rx; int subframe_rx = proc->subframe_rx; - int ret=0; + int ret=0, ret1=0; int CC_id = ue->CC_id; LTE_UE_PDSCH *pdsch_vars; + uint8_t is_cw0_active = 0; + uint8_t is_cw1_active = 0; - if (dlsch0 && (!dlsch1)) { + if (dlsch0==NULL) + AssertFatal(0,"dlsch0 should be defined at this level \n"); + + harq_pid = dlsch0->current_harq_pid; + is_cw0_active = dlsch0->harq_processes[harq_pid]->status; + + if(dlsch1) + is_cw1_active = dlsch1->harq_processes[harq_pid]->status; + + LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, subframe_rx, harq_pid, is_cw0_active); + LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, subframe_rx, harq_pid, is_cw1_active); + + if(is_cw0_active && is_cw1_active) + { + dlsch0->Kmimo = 2; + dlsch1->Kmimo = 2; + } + else + { + dlsch0->Kmimo = 1; + } + if (1) { switch (pdsch) { case SI_PDSCH: pdsch_vars = ue->pdsch_vars_SI[eNB_id]; @@ -3431,8 +3464,6 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, break; } - - harq_pid = dlsch0->current_harq_pid; if (frame_rx < *dlsch_errors) *dlsch_errors=0; @@ -3449,6 +3480,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if (abstraction_flag == 0) { + // start turbo decode for CW 0 dlsch0->harq_processes[harq_pid]->G = get_G(&ue->frame_parms, dlsch0->harq_processes[harq_pid]->nb_rb, dlsch0->harq_processes[harq_pid]->rb_alloc_even, @@ -3468,6 +3500,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, subframe_rx<<1); stop_meas(&ue->dlsch_unscrambling_stats); + //LOG_I(PHY,"start turbo decode for CW 0 --> nb_rb %d \n", dlsch0->harq_processes[harq_pid]->nb_rb); + //LOG_I(PHY,"start turbo decode for CW 0 --> rb_alloc_even %x \n", dlsch0->harq_processes[harq_pid]->rb_alloc_even); + //LOG_I(PHY,"start turbo decode for CW 0 --> Qm %d \n", dlsch0->harq_processes[harq_pid]->Qm); + //LOG_I(PHY,"start turbo decode for CW 0 --> Nl %d \n", dlsch0->harq_processes[harq_pid]->Nl); + //LOG_I(PHY,"start turbo decode for CW 0 --> G %d \n", dlsch0->harq_processes[harq_pid]->G); + //LOG_I(PHY,"start turbo decode for CW 0 --> Kmimo %d \n", dlsch0->Kmimo); + start_meas(&ue->dlsch_decoding_stats); ret = dlsch_decoding(ue, pdsch_vars->llr[0], @@ -3480,6 +3519,60 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, pdsch==PDSCH?1:0, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); stop_meas(&ue->dlsch_decoding_stats); + + printf(" --> Unscrambling for CW0 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + printf(" --> Turbo Decoding for CW0 %5.3f\n", + (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + + if(is_cw1_active) + { + // start turbo decode for CW 1 + dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms, + dlsch1->harq_processes[harq_pid]->nb_rb, + dlsch1->harq_processes[harq_pid]->rb_alloc_even, + dlsch1->harq_processes[harq_pid]->Qm, + dlsch1->harq_processes[harq_pid]->Nl, + ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + frame_rx, + subframe_rx, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); + + start_meas(&ue->dlsch_unscrambling_stats); + dlsch_unscrambling(&ue->frame_parms, + 0, + dlsch1, + dlsch1->harq_processes[harq_pid]->G, + pdsch_vars->llr[1], + 1, + subframe_rx<<1); + stop_meas(&ue->dlsch_unscrambling_stats); + + //LOG_I(PHY,"start turbo decode for CW 1 --> nb_rb %d \n", dlsch1->harq_processes[harq_pid]->nb_rb); + //LOG_I(PHY,"start turbo decode for CW 1 --> rb_alloc_even %x \n", dlsch1->harq_processes[harq_pid]->rb_alloc_even); + //LOG_I(PHY,"start turbo decode for CW 1 --> Qm %d \n", dlsch1->harq_processes[harq_pid]->Qm); + //LOG_I(PHY,"start turbo decode for CW 1 --> Nl %d \n", dlsch1->harq_processes[harq_pid]->Nl); + //LOG_I(PHY,"start turbo decode for CW 1 --> G %d \n", dlsch1->harq_processes[harq_pid]->G); + //LOG_I(PHY,"start turbo decode for CW 1 --> Kmimo %d \n", dlsch1->Kmimo); + + start_meas(&ue->dlsch_decoding_stats); + ret1 = dlsch_decoding(ue, + pdsch_vars->llr[1], + &ue->frame_parms, + dlsch1, + dlsch1->harq_processes[harq_pid], + frame_rx, + subframe_rx, + harq_pid, + pdsch==PDSCH?1:0, + dlsch1->harq_processes[harq_pid]->TBS>256?1:0); + stop_meas(&ue->dlsch_decoding_stats); + + printf(" --> Unscrambling for CW1 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + printf(" --> Turbo Decoding for CW1 %5.3f\n", + (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + } } else { @@ -3492,12 +3585,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, #endif } + // Check CRC for CW 0 if (ret == (1+dlsch0->max_turbo_iterations)) { *dlsch_errors=*dlsch_errors+1; if(dlsch0->rnti != 0xffff) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3509,7 +3603,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, } else { if(dlsch0->rnti != 0xffff) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3574,6 +3668,49 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; } + // Check CRC for CW 1 + if(is_cw1_active) + { + if (ret1 == (1+dlsch0->max_turbo_iterations)) { + LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); + + } else { + LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); + + + if (ue->mac_enabled == 1) { + switch (pdsch) { + case PDSCH: + if(is_cw1_active) + mac_xface->ue_send_sdu(ue->Mod_id, + CC_id, + frame_rx, + subframe_rx, + dlsch1->harq_processes[dlsch1->current_harq_pid]->b, + dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3, + eNB_id); + break; + case SI_PDSCH: + case P_PDSCH: + case RA_PDSCH: + case PDSCH1: + case PMCH: + AssertFatal(0,"exiting"); + break; + } + } + } + } #ifdef DEBUG_PHY_PROC @@ -3622,16 +3759,18 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti], ue->frame_parms.samples_per_tti * 4)); - start_meas(&ue->phy_proc_rx); + // start timers + start_meas(&ue->phy_proc_rx[subframe_rx&0x1]); + start_meas(&ue->generic_stat); pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; // deactivate reception until we scan pdcch - if (ue->dlsch[eNB_id][0]) - ue->dlsch[eNB_id][0]->active = 0; - if (ue->dlsch[eNB_id][1]) - ue->dlsch[eNB_id][1]->active = 0; + if (ue->dlsch[subframe_rx&0x1][eNB_id][0]) + ue->dlsch[subframe_rx&0x1][eNB_id][0]->active = 0; + if (ue->dlsch[subframe_rx&0x1][eNB_id][1]) + ue->dlsch[subframe_rx&0x1][eNB_id][1]->active = 0; if (ue->dlsch_SI[eNB_id]) ue->dlsch_SI[eNB_id]->active = 0; @@ -3717,15 +3856,18 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin 0); // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) - + stop_meas(&ue->generic_stat); + printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + + start_meas(&ue->generic_stat); // do procedures for C-RNTI - if (ue->dlsch[eNB_id][0]->active == 1) { + if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[eNB_id][0], + ue->dlsch[subframe_rx&0x1][eNB_id][0], NULL, ue->pdcch_vars[eNB_id]->num_pdcch_symbols, ue->frame_parms.symbols_per_tti>>1, @@ -3809,35 +3951,48 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } } // not an S-subframe + stop_meas(&ue->generic_stat); + printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + // run pbch procedures if subframe is 0 if (subframe_rx == 0) ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); // do procedures for C-RNTI - if (ue->dlsch[eNB_id][0]->active == 1) { + if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + start_meas(&ue->pdsch_procedures_stat); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[eNB_id][0], + ue->dlsch[subframe_rx&0x1][eNB_id][0], NULL, 1+(ue->frame_parms.symbols_per_tti>>1), ue->frame_parms.symbols_per_tti-1, abstraction_flag); + stop_meas(&ue->pdsch_procedures_stat); + + start_meas(&ue->dlsch_procedures_stat); ue_dlsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[eNB_id][0], - NULL, + ue->dlsch[subframe_rx&0x1][eNB_id][0], + ue->dlsch[subframe_rx&0x1][eNB_id][1], &ue->dlsch_errors[eNB_id], mode, abstraction_flag); + stop_meas(&ue->dlsch_procedures_stat); + printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } + start_meas(&ue->generic_stat); + // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { ue_pdsch_procedures(ue, @@ -3932,7 +4087,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } - + stop_meas(&ue->generic_stat); + //printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); #ifdef EMOS phy_procedures_emos_UE_RX(ue,slot,eNB_id); @@ -3940,7 +4096,10 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); - stop_meas(&ue->phy_proc_rx); + stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]); + + printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0)); + return (0); } diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c index 5bc03bb58d..ae83123862 100644 --- a/openair1/SCHED/pucch_pc.c +++ b/openair1/SCHED/pucch_pc.c @@ -51,7 +51,7 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u Po_PUCCH = get_PL(ue->Mod_id,ue->CC_id,eNB_id)+ ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+ - ue->dlsch[eNB_id][0]->g_pucch; + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch; switch (pucch_fmt) { case pucch_format1: @@ -90,19 +90,19 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u if (pucch_fmt!=pucch_format1) { LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->dlsch[eNB_id][0]->g_pucch); + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch); } else { LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->dlsch[eNB_id][0]->g_pucch); + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch); } return(Po_PUCCH); diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index fa5a4d6409..4d0ff134ba 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -199,7 +199,7 @@ mac_rrc_data_req( int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); if (ccch_size > sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size0 (%d, %d)", ccch_size, sdu_size); ccch_size = sdu_size; } @@ -297,7 +297,7 @@ mac_rrc_data_req( int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); if (ccch_size > sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size1 (%d, %d)", ccch_size, sdu_size); ccch_size = sdu_size; } @@ -403,7 +403,7 @@ mac_rrc_data_ind( int msg_sdu_size = CCCH_SDU_SIZE; if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size2 (%d, %d)", sdu_size, msg_sdu_size); sdu_size = msg_sdu_size; } else { sdu_size = sdu_lenP; @@ -471,7 +471,7 @@ mac_rrc_data_ind( int msg_sdu_size = sizeof(RRC_MAC_CCCH_DATA_IND (message_p).sdu); if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size3 (%d, %d)", sdu_lenP, msg_sdu_size); sdu_size = msg_sdu_size; } else { sdu_size = sdu_lenP; diff --git a/openair3/NAS/TOOLS/network.h b/openair3/NAS/TOOLS/network.h index 0d60359c57..d7044c8e51 100644 --- a/openair3/NAS/TOOLS/network.h +++ b/openair3/NAS/TOOLS/network.h @@ -61,7 +61,7 @@ Description Defines a list of PLMN network operators #define VDF5 11 -#define SELECTED_PLMN OAI_LTEBOX //SFR1 +#define SELECTED_PLMN TEST1 //SFR1 #define TEST_PLMN {0,0,0x0f,1,1,0} // 00101 #define SFR_PLMN_1 {0,2,0x0f,8,0,1} // 20810 diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index 84ec59a36b..05db6be4d1 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -86,14 +86,14 @@ UE0: }; SIM: { - MSIN="0100001111"; - USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; + MSIN="000001234"; + USIM_API_K="000102030405060708090A0B0C0D0E0F"; OPC="C42449363BBAD02B66D16BC975D77CC1"; - MSISDN="33611123456"; + MSISDN="000000000000";//"33611123456"; }; # Home PLMN Selector with Access Technology - HPLMN= "20893"; + HPLMN= "00101"; # User controlled PLMN Selector with Access Technology UCPLMN_LIST = (); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 3b6ea9e5c9..5603d86ade 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -56,6 +56,8 @@ #include "T.h" +extern double cpuf; + #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL #define FIFO_PRIORITY 40 @@ -538,6 +540,9 @@ static void *UE_thread_rxn_txnp4(void *arg) { } phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL ); } + + start_meas(&UE->generic_stat); + if (UE->mac_enabled==1) { ret = mac_xface->ue_scheduler(UE->Mod_id, @@ -567,6 +572,10 @@ static void *UE_thread_rxn_txnp4(void *arg) { UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt ); } } + + stop_meas(&UE->generic_stat); + printf("mac_xface->ue_scheduler %5.2f \n",UE->generic_stat.p_time/(cpuf*1000.0)); + // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c index 8ff274be14..a99ccf2c09 100644 --- a/targets/SIMU/USER/init_lte.c +++ b/targets/SIMU/USER/init_lte.c @@ -161,30 +161,32 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms, memcpy(&(PHY_vars_UE->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS)); phy_init_lte_ue(PHY_vars_UE,1,abstraction_flag); - for (i=0; idlsch[i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); + for (int l=0; l<2; l++) { + for (i=0; idlsch[l][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); - if (!PHY_vars_UE->dlsch[i][j]) { - LOG_E(PHY,"Can't get ue dlsch structures\n"); - exit(-1); - } else - LOG_D(PHY,"dlsch[%d][%d] => %p\n",UE_id,i,PHY_vars_UE->dlsch[i][j]); - } + if (!PHY_vars_UE->dlsch[l][i][j]) { + LOG_E(PHY,"Can't get ue dlsch structures\n"); + exit(-1); + } else + LOG_D(PHY,"dlsch[%d][%d] => %p\n",UE_id,i,PHY_vars_UE->dlsch[l][i][j]); + } - PHY_vars_UE->ulsch[i] = new_ue_ulsch(frame_parms->N_RB_UL, abstraction_flag); + PHY_vars_UE->ulsch[i] = new_ue_ulsch(frame_parms->N_RB_UL, abstraction_flag); - if (!PHY_vars_UE->ulsch[i]) { - LOG_E(PHY,"Can't get ue ulsch structures\n"); - exit(-1); - } + if (!PHY_vars_UE->ulsch[i]) { + LOG_E(PHY,"Can't get ue ulsch structures\n"); + exit(-1); + } - PHY_vars_UE->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); - PHY_vars_UE->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); + PHY_vars_UE->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); + PHY_vars_UE->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); - PHY_vars_UE->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2; + PHY_vars_UE->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2; + } } PHY_vars_UE->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; From ba55fcac27fb34dad97beea1bcd609a6dfa8a88d Mon Sep 17 00:00:00 2001 From: hbilel Date: Mon, 6 Mar 2017 12:13:20 +0100 Subject: [PATCH 358/571] [OAI-UE] Mimo LLR computation AVX2 + fix in TM3 deprecoding --- cmake_targets/CMakeLists.txt | 1 + .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 23 +++++++++------ .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 29 +++++++++++++++++++ openair1/PHY/LTE_TRANSPORT/proto.h | 16 ++++++++++ openair1/PHY/Makefile.inc | 1 + openair3/NAS/UE/ESM/esm_ebr_context.c | 2 +- targets/RT/USER/lte-softmodem.c | 8 ++++- 7 files changed, 69 insertions(+), 11 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index e4d3acf4b1..0bf63cfb1a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1034,6 +1034,7 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_modulation.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation.c + ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/power_control.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_decoding.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_scrambling.c diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 9ae212cd27..7b1fb3cd50 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -42,6 +42,7 @@ #define NOCYGWIN_STATIC #endif +extern int16_t dlsch_demod_shift; //#define DEBUG_HARQ //#undef LOG_D @@ -402,8 +403,8 @@ int rx_pdsch(PHY_VARS_UE *ue, LOG_D(PHY,"Channel Level TM34 avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, interf_unaw_shift %d \n", avg_0[0], avg_1[0], rx_type, rx_standard, interf_unaw_shift); if (rx_type>rx_standard) { - avg_0[0] = (log2_approx(avg_0[0])/2) - 5 + 2 ;//+ 2; - avg_1[0] = (log2_approx(avg_1[0])/2) - 5 + 2 ;//+ 2; + avg_0[0] = (log2_approx(avg_0[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4; + avg_1[0] = (log2_approx(avg_1[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4; pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); //printf("TM4 I-A log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0); @@ -1067,9 +1068,9 @@ int rx_pdsch(PHY_VARS_UE *ue, write_output("dl_ch_estimates_ext10.m", "dl_ch_estimates_ext10", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[2][0],14*frame_parms->N_RB_DL*12,1,1); write_output("dl_ch_estimates_ext11.m", "dl_ch_estimates_ext11", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[3][0],14*frame_parms->N_RB_DL*12,1,1); write_output("rxdataF_comp00.m","rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp01.m","rxdataF_comp01", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp10.m","rxdataF_comp10", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp11.m","rxdataF_comp11", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp01.m","rxdataF_comp01", &pdsch_vars[eNB_id]->rxdataF_comp0[1][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp10.m","rxdataF_comp10", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp11.m","rxdataF_comp11", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][0],14*frame_parms->N_RB_DL*12,1,1); #endif write_output("llr0.m","llr0", &pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); write_output("llr1.m","llr1", &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); @@ -1666,9 +1667,8 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { __m128i tmp0,tmp1; - // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b, - //so divide by 2 is replaced by divide by sqrt(2). +//_mm_mulhi_epi16 // print_shorts("prec2A_TM3 ch0 (before):",ch0); // print_shorts("prec2A_TM3 ch1 (before):",ch1); @@ -1679,6 +1679,11 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { ch0[0] = _mm_adds_epi16(ch0[0],tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); + ch0[0] = _mm_mulhi_epi16(ch0[0],amp); + ch0[0] = _mm_slli_epi16(ch0[0],1); + + ch1[0] = _mm_mulhi_epi16(ch1[0],amp); + ch1[0] = _mm_slli_epi16(ch1[0],1); // print_shorts("prec2A_TM3 ch0 (mid):",&tmp0); // print_shorts("prec2A_TM3 ch1 (mid):",ch1); @@ -1688,8 +1693,8 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { ch1[0] = _mm_mulhi_epi16(ch1[0],amp); ch1[0] = _mm_slli_epi16(ch1[0],1); - // ch0[0] = _mm_srai_epi16(ch0[0],1); - // ch1[0] = _mm_srai_epi16(ch1[0],1); + //ch0[0] = _mm_srai_epi16(ch0[0],1); + //ch1[0] = _mm_srai_epi16(ch1[0],1); // print_shorts("prec2A_TM3 ch0 (after):",ch0); // print_shorts("prec2A_TM3 ch1 (after):",ch1); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 0b73e2b023..c33dec87d3 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -8831,6 +8831,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } +#if 0 qam64_qam64((short *)rxF, (short *)rxF_i, (short *)ch_mag, @@ -8838,7 +8839,35 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (short *)llr16, (short *)rho, len); +#else + // Round length up to multiple of 16 words + uint32_t len256i = ((len+16)>>4)*16; + int32_t *rxF_256i = (int32_t*) malloc16_clear(len256i*4); + int32_t *rxF_i_256i = (int32_t*) malloc16_clear(len256i*4); + int32_t *ch_mag_256i = (int32_t*) malloc16_clear(len256i*4); + int32_t *ch_mag_i_256i = (int32_t*) malloc16_clear(len256i*4); + int32_t *rho_256i = (int32_t*) malloc16_clear(len256i*4); + memcpy(rxF_256i, rxF, len*4); + memcpy(rxF_i_256i, rxF_i, len*4); + memcpy(ch_mag_256i, ch_mag, len*4); + memcpy(ch_mag_i_256i, ch_mag_i, len*4); + memcpy(rho_256i, rho, len*4); + + qam64_qam64_avx2((int32_t *)rxF_256i, + (int32_t *)rxF_i_256i, + (int32_t *)ch_mag_256i, + (int32_t *)ch_mag_i_256i, + (int16_t *)llr16, + (int32_t *) rho_256i, + len); + + free16(rxF_256i, sizeof(rxF_256i)); + free16(rxF_i_256i, sizeof(rxF_i_256i)); + free16(ch_mag_256i, sizeof(ch_mag_256i)); + free16(ch_mag_i_256i, sizeof(ch_mag_i_256i)); + free16(rho_256i, sizeof(rho_256i)); +#endif llr16 += (6*len); *llr16p = (short *)llr16; return(0); diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 5fc8dea986..a5aa145e17 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -746,6 +746,22 @@ void qam64_qam64(short *stream0_in, short *rho01, int length); +/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream 64QAM/64QAM reception. + @param stream0_in Input from channel compensated (MR combined) stream 0 + @param stream1_in Input from channel compensated (MR combined) stream 1 + @param ch_mag Input from scaled channel magnitude square of h0'*g0 + @param ch_mag_i Input from scaled channel magnitude square of h0'*g1 + @param stream0_out Output from LLR unit for stream0 + @param rho01 Cross-correlation between channels (MR combined) + @param length in complex channel outputs*/ +void qam64_qam64_avx2(int32_t *stream0_in, + int32_t *stream1_in, + int32_t *ch_mag, + int32_t *ch_mag_i, + int16_t *stream0_out, + int32_t *rho01, + int length); + /** \brief This function perform LLR computation for dual-stream (64QAM/64QAM) transmission. @param frame_parms Frame descriptor structure @param rxdataF_comp Compensated channel output diff --git a/openair1/PHY/Makefile.inc b/openair1/PHY/Makefile.inc index 1586f353c0..90094b31f8 100644 --- a/openair1/PHY/Makefile.inc +++ b/openair1/PHY/Makefile.inc @@ -7,6 +7,7 @@ PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_coding.o PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_modulation.o PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_demodulation.o PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_llr_computation.o +PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.o PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/power_control.o PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_decoding.o PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_scrambling.o diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index bfa4a04cc8..31f215e359 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -286,7 +286,7 @@ int esm_ebr_context_create( LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); - if (system(command_line)) ; /* TODO: what to do? */ + //if (system(command_line)) ; /* TODO: what to do? */ break; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 8303d88218..5761577259 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -151,6 +151,8 @@ uint8_t usim_test = 0; uint8_t nb_antenna_tx = 1; uint8_t nb_antenna_rx = 1; +int16_t dlsch_demod_shift = 0; + char ref[128] = "internal"; char channels[128] = "0"; @@ -635,6 +637,7 @@ static void get_options (int argc, char **argv) { LONG_OPTION_THREADIQ, LONG_OPTION_THREADODDSUBFRAME, LONG_OPTION_THREADEVENSUBFRAME, + LONG_OPTION_DEMOD_SHIFT, #if T_TRACER LONG_OPTION_T_PORT, LONG_OPTION_T_NOWAIT, @@ -670,6 +673,7 @@ static void get_options (int argc, char **argv) { {"threadIQ", required_argument, NULL, LONG_OPTION_THREADIQ}, {"threadOddSubframe", required_argument, NULL, LONG_OPTION_THREADODDSUBFRAME}, {"threadEvenSubframe", required_argument, NULL, LONG_OPTION_THREADEVENSUBFRAME}, + {"dlsch-demod-shift", required_argument, NULL, LONG_OPTION_DEMOD_SHIFT}, #if T_TRACER {"T_port", required_argument, 0, LONG_OPTION_T_PORT}, {"T_nowait", no_argument, 0, LONG_OPTION_T_NOWAIT}, @@ -800,7 +804,9 @@ static void get_options (int argc, char **argv) { case LONG_OPTION_THREADEVENSUBFRAME: threads.even=atoi(optarg); break; - + case LONG_OPTION_DEMOD_SHIFT: + dlsch_demod_shift = atof(optarg); + break; #if T_TRACER case LONG_OPTION_T_PORT: { extern int T_port; From 42b834d64c19928caa9c6addf8ae35e47262236a Mon Sep 17 00:00:00 2001 From: Sebastian Wagner Date: Wed, 1 Mar 2017 18:01:39 +0100 Subject: [PATCH 359/571] Changes for 64qam_64qam for avx2 Conflicts: openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c --- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 38 +- .../dlsch_llr_computation_avx2.c | 4034 +++++++++++++++++ openair1/PHY/LTE_TRANSPORT/proto.h | 16 + 3 files changed, 4076 insertions(+), 12 deletions(-) create mode 100644 openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index c33dec87d3..240758eceb 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -8831,15 +8831,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } -#if 0 - qam64_qam64((short *)rxF, - (short *)rxF_i, - (short *)ch_mag, - (short *)ch_mag_i, - (short *)llr16, - (short *)rho, - len); -#else +//#ifdef __AVX2__ + // Round length up to multiple of 16 words uint32_t len256i = ((len+16)>>4)*16; int32_t *rxF_256i = (int32_t*) malloc16_clear(len256i*4); @@ -8853,7 +8846,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, memcpy(ch_mag_256i, ch_mag, len*4); memcpy(ch_mag_i_256i, ch_mag_i, len*4); memcpy(rho_256i, rho, len*4); - + /* qam64_qam64_avx2((int32_t *)rxF_256i, (int32_t *)rxF_i_256i, (int32_t *)ch_mag_256i, @@ -8861,13 +8854,34 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (int16_t *)llr16, (int32_t *) rho_256i, len); - + */ + qam64_qam16_avx2((short *)rxF_256i, + (short *)rxF_i_256i, + (short *)ch_mag_256i, + (short *)ch_mag_i_256i, + (short *)llr16, + (short *)rho_256i, + len); + free16(rxF_256i, sizeof(rxF_256i)); free16(rxF_i_256i, sizeof(rxF_i_256i)); free16(ch_mag_256i, sizeof(ch_mag_256i)); free16(ch_mag_i_256i, sizeof(ch_mag_i_256i)); free16(rho_256i, sizeof(rho_256i)); -#endif + +//#else +/* + qam64_qam64((short *)rxF, + (short *)rxF_i, + (short *)ch_mag, + (short *)ch_mag_i, + (short *)llr16, + (short *)rho, + len); +*/ + +//#endif + llr16 += (6*len); *llr16p = (short *)llr16; return(0); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c new file mode 100644 index 0000000000..cda5ad0f55 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c @@ -0,0 +1,4034 @@ + /* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/LTE_TRANSPORT/dlsch_llr_computation.c + * \brief Top-level routines for LLR computation of the PDSCH physical channel from 36-211, V8.6 2009-03 + * \author R. Knopp, F. Kaltenberger,A. Bhamri, S. Aubert, S. Wagner, X Jiang + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr,sebastien.aubert@eurecom.fr, sebastian.wagner@eurecom.fr + * \note + * \warning + */ + +#include "PHY/defs.h" +#include "PHY/TOOLS/defs.h" +#include "PHY/extern.h" +#include "defs.h" +#include "extern.h" +#include "PHY/sse_intrin.h" + +int16_t ones256[16] __attribute__ ((aligned(32))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; + +static __m256i rho_rpi __attribute__ ((aligned(32))); +static __m256i rho_rmi __attribute__ ((aligned(32))); +static __m256i rho_rpi_1_1 __attribute__ ((aligned(32))); +static __m256i rho_rpi_1_3 __attribute__ ((aligned(32))); +static __m256i rho_rpi_1_5 __attribute__ ((aligned(32))); +static __m256i rho_rpi_1_7 __attribute__ ((aligned(32))); +static __m256i rho_rpi_3_1 __attribute__ ((aligned(32))); +static __m256i rho_rpi_3_3 __attribute__ ((aligned(32))); +static __m256i rho_rpi_3_5 __attribute__ ((aligned(32))); +static __m256i rho_rpi_3_7 __attribute__ ((aligned(32))); +static __m256i rho_rpi_5_1 __attribute__ ((aligned(32))); +static __m256i rho_rpi_5_3 __attribute__ ((aligned(32))); +static __m256i rho_rpi_5_5 __attribute__ ((aligned(32))); +static __m256i rho_rpi_5_7 __attribute__ ((aligned(32))); +static __m256i rho_rpi_7_1 __attribute__ ((aligned(32))); +static __m256i rho_rpi_7_3 __attribute__ ((aligned(32))); +static __m256i rho_rpi_7_5 __attribute__ ((aligned(32))); +static __m256i rho_rpi_7_7 __attribute__ ((aligned(32))); +static __m256i rho_rmi_1_1 __attribute__ ((aligned(32))); +static __m256i rho_rmi_1_3 __attribute__ ((aligned(32))); +static __m256i rho_rmi_1_5 __attribute__ ((aligned(32))); +static __m256i rho_rmi_1_7 __attribute__ ((aligned(32))); +static __m256i rho_rmi_3_1 __attribute__ ((aligned(32))); +static __m256i rho_rmi_3_3 __attribute__ ((aligned(32))); +static __m256i rho_rmi_3_5 __attribute__ ((aligned(32))); +static __m256i rho_rmi_3_7 __attribute__ ((aligned(32))); +static __m256i rho_rmi_5_1 __attribute__ ((aligned(32))); +static __m256i rho_rmi_5_3 __attribute__ ((aligned(32))); +static __m256i rho_rmi_5_5 __attribute__ ((aligned(32))); +static __m256i rho_rmi_5_7 __attribute__ ((aligned(32))); +static __m256i rho_rmi_7_1 __attribute__ ((aligned(32))); +static __m256i rho_rmi_7_3 __attribute__ ((aligned(32))); +static __m256i rho_rmi_7_5 __attribute__ ((aligned(32))); +static __m256i rho_rmi_7_7 __attribute__ ((aligned(32))); + +static __m256i psi_r_m7_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_m7_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_m7_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_m7_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_m7_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_m7_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_m7_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_m7_p7 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_m5_p7 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_m3_p7 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_m1_p7 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_p1_p7 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_p3_p7 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_p5_p7 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_m7 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_m5 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_m3 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_m1 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_p1 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_p3 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_p5 __attribute__ ((aligned(32))); +static __m256i psi_r_p7_p7 __attribute__ ((aligned(32))); + +static __m256i psi_i_m7_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_m7_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_m7_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_m7_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_m7_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_m7_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_m7_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_m7_p7 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_m5_p7 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_m3_p7 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_m1_p7 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_p1_p7 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_p3_p7 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_p5_p7 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_m7 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_m5 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_m3 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_m1 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_p1 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_p3 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_p5 __attribute__ ((aligned(32))); +static __m256i psi_i_p7_p7 __attribute__ ((aligned(32))); + +static __m256i a_r_m7_m7 __attribute__ ((aligned(32))); +static __m256i a_r_m7_m5 __attribute__ ((aligned(32))); +static __m256i a_r_m7_m3 __attribute__ ((aligned(32))); +static __m256i a_r_m7_m1 __attribute__ ((aligned(32))); +static __m256i a_r_m7_p1 __attribute__ ((aligned(32))); +static __m256i a_r_m7_p3 __attribute__ ((aligned(32))); +static __m256i a_r_m7_p5 __attribute__ ((aligned(32))); +static __m256i a_r_m7_p7 __attribute__ ((aligned(32))); +static __m256i a_r_m5_m7 __attribute__ ((aligned(32))); +static __m256i a_r_m5_m5 __attribute__ ((aligned(32))); +static __m256i a_r_m5_m3 __attribute__ ((aligned(32))); +static __m256i a_r_m5_m1 __attribute__ ((aligned(32))); +static __m256i a_r_m5_p1 __attribute__ ((aligned(32))); +static __m256i a_r_m5_p3 __attribute__ ((aligned(32))); +static __m256i a_r_m5_p5 __attribute__ ((aligned(32))); +static __m256i a_r_m5_p7 __attribute__ ((aligned(32))); +static __m256i a_r_m3_m7 __attribute__ ((aligned(32))); +static __m256i a_r_m3_m5 __attribute__ ((aligned(32))); +static __m256i a_r_m3_m3 __attribute__ ((aligned(32))); +static __m256i a_r_m3_m1 __attribute__ ((aligned(32))); +static __m256i a_r_m3_p1 __attribute__ ((aligned(32))); +static __m256i a_r_m3_p3 __attribute__ ((aligned(32))); +static __m256i a_r_m3_p5 __attribute__ ((aligned(32))); +static __m256i a_r_m3_p7 __attribute__ ((aligned(32))); +static __m256i a_r_m1_m7 __attribute__ ((aligned(32))); +static __m256i a_r_m1_m5 __attribute__ ((aligned(32))); +static __m256i a_r_m1_m3 __attribute__ ((aligned(32))); +static __m256i a_r_m1_m1 __attribute__ ((aligned(32))); +static __m256i a_r_m1_p1 __attribute__ ((aligned(32))); +static __m256i a_r_m1_p3 __attribute__ ((aligned(32))); +static __m256i a_r_m1_p5 __attribute__ ((aligned(32))); +static __m256i a_r_m1_p7 __attribute__ ((aligned(32))); +static __m256i a_r_p1_m7 __attribute__ ((aligned(32))); +static __m256i a_r_p1_m5 __attribute__ ((aligned(32))); +static __m256i a_r_p1_m3 __attribute__ ((aligned(32))); +static __m256i a_r_p1_m1 __attribute__ ((aligned(32))); +static __m256i a_r_p1_p1 __attribute__ ((aligned(32))); +static __m256i a_r_p1_p3 __attribute__ ((aligned(32))); +static __m256i a_r_p1_p5 __attribute__ ((aligned(32))); +static __m256i a_r_p1_p7 __attribute__ ((aligned(32))); +static __m256i a_r_p3_m7 __attribute__ ((aligned(32))); +static __m256i a_r_p3_m5 __attribute__ ((aligned(32))); +static __m256i a_r_p3_m3 __attribute__ ((aligned(32))); +static __m256i a_r_p3_m1 __attribute__ ((aligned(32))); +static __m256i a_r_p3_p1 __attribute__ ((aligned(32))); +static __m256i a_r_p3_p3 __attribute__ ((aligned(32))); +static __m256i a_r_p3_p5 __attribute__ ((aligned(32))); +static __m256i a_r_p3_p7 __attribute__ ((aligned(32))); +static __m256i a_r_p5_m7 __attribute__ ((aligned(32))); +static __m256i a_r_p5_m5 __attribute__ ((aligned(32))); +static __m256i a_r_p5_m3 __attribute__ ((aligned(32))); +static __m256i a_r_p5_m1 __attribute__ ((aligned(32))); +static __m256i a_r_p5_p1 __attribute__ ((aligned(32))); +static __m256i a_r_p5_p3 __attribute__ ((aligned(32))); +static __m256i a_r_p5_p5 __attribute__ ((aligned(32))); +static __m256i a_r_p5_p7 __attribute__ ((aligned(32))); +static __m256i a_r_p7_m7 __attribute__ ((aligned(32))); +static __m256i a_r_p7_m5 __attribute__ ((aligned(32))); +static __m256i a_r_p7_m3 __attribute__ ((aligned(32))); +static __m256i a_r_p7_m1 __attribute__ ((aligned(32))); +static __m256i a_r_p7_p1 __attribute__ ((aligned(32))); +static __m256i a_r_p7_p3 __attribute__ ((aligned(32))); +static __m256i a_r_p7_p5 __attribute__ ((aligned(32))); +static __m256i a_r_p7_p7 __attribute__ ((aligned(32))); + +static __m256i a_i_m7_m7 __attribute__ ((aligned(32))); +static __m256i a_i_m7_m5 __attribute__ ((aligned(32))); +static __m256i a_i_m7_m3 __attribute__ ((aligned(32))); +static __m256i a_i_m7_m1 __attribute__ ((aligned(32))); +static __m256i a_i_m7_p1 __attribute__ ((aligned(32))); +static __m256i a_i_m7_p3 __attribute__ ((aligned(32))); +static __m256i a_i_m7_p5 __attribute__ ((aligned(32))); +static __m256i a_i_m7_p7 __attribute__ ((aligned(32))); +static __m256i a_i_m5_m7 __attribute__ ((aligned(32))); +static __m256i a_i_m5_m5 __attribute__ ((aligned(32))); +static __m256i a_i_m5_m3 __attribute__ ((aligned(32))); +static __m256i a_i_m5_m1 __attribute__ ((aligned(32))); +static __m256i a_i_m5_p1 __attribute__ ((aligned(32))); +static __m256i a_i_m5_p3 __attribute__ ((aligned(32))); +static __m256i a_i_m5_p5 __attribute__ ((aligned(32))); +static __m256i a_i_m5_p7 __attribute__ ((aligned(32))); +static __m256i a_i_m3_m7 __attribute__ ((aligned(32))); +static __m256i a_i_m3_m5 __attribute__ ((aligned(32))); +static __m256i a_i_m3_m3 __attribute__ ((aligned(32))); +static __m256i a_i_m3_m1 __attribute__ ((aligned(32))); +static __m256i a_i_m3_p1 __attribute__ ((aligned(32))); +static __m256i a_i_m3_p3 __attribute__ ((aligned(32))); +static __m256i a_i_m3_p5 __attribute__ ((aligned(32))); +static __m256i a_i_m3_p7 __attribute__ ((aligned(32))); +static __m256i a_i_m1_m7 __attribute__ ((aligned(32))); +static __m256i a_i_m1_m5 __attribute__ ((aligned(32))); +static __m256i a_i_m1_m3 __attribute__ ((aligned(32))); +static __m256i a_i_m1_m1 __attribute__ ((aligned(32))); +static __m256i a_i_m1_p1 __attribute__ ((aligned(32))); +static __m256i a_i_m1_p3 __attribute__ ((aligned(32))); +static __m256i a_i_m1_p5 __attribute__ ((aligned(32))); +static __m256i a_i_m1_p7 __attribute__ ((aligned(32))); +static __m256i a_i_p1_m7 __attribute__ ((aligned(32))); +static __m256i a_i_p1_m5 __attribute__ ((aligned(32))); +static __m256i a_i_p1_m3 __attribute__ ((aligned(32))); +static __m256i a_i_p1_m1 __attribute__ ((aligned(32))); +static __m256i a_i_p1_p1 __attribute__ ((aligned(32))); +static __m256i a_i_p1_p3 __attribute__ ((aligned(32))); +static __m256i a_i_p1_p5 __attribute__ ((aligned(32))); +static __m256i a_i_p1_p7 __attribute__ ((aligned(32))); +static __m256i a_i_p3_m7 __attribute__ ((aligned(32))); +static __m256i a_i_p3_m5 __attribute__ ((aligned(32))); +static __m256i a_i_p3_m3 __attribute__ ((aligned(32))); +static __m256i a_i_p3_m1 __attribute__ ((aligned(32))); +static __m256i a_i_p3_p1 __attribute__ ((aligned(32))); +static __m256i a_i_p3_p3 __attribute__ ((aligned(32))); +static __m256i a_i_p3_p5 __attribute__ ((aligned(32))); +static __m256i a_i_p3_p7 __attribute__ ((aligned(32))); +static __m256i a_i_p5_m7 __attribute__ ((aligned(32))); +static __m256i a_i_p5_m5 __attribute__ ((aligned(32))); +static __m256i a_i_p5_m3 __attribute__ ((aligned(32))); +static __m256i a_i_p5_m1 __attribute__ ((aligned(32))); +static __m256i a_i_p5_p1 __attribute__ ((aligned(32))); +static __m256i a_i_p5_p3 __attribute__ ((aligned(32))); +static __m256i a_i_p5_p5 __attribute__ ((aligned(32))); +static __m256i a_i_p5_p7 __attribute__ ((aligned(32))); +static __m256i a_i_p7_m7 __attribute__ ((aligned(32))); +static __m256i a_i_p7_m5 __attribute__ ((aligned(32))); +static __m256i a_i_p7_m3 __attribute__ ((aligned(32))); +static __m256i a_i_p7_m1 __attribute__ ((aligned(32))); +static __m256i a_i_p7_p1 __attribute__ ((aligned(32))); +static __m256i a_i_p7_p3 __attribute__ ((aligned(32))); +static __m256i a_i_p7_p5 __attribute__ ((aligned(32))); +static __m256i a_i_p7_p7 __attribute__ ((aligned(32))); + +static __m256i psi_a_m7_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_m7_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_m7_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_m7_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_m7_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_m7_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_m7_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_m7_p7 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_m5_p7 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_m3_p7 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_m1_p7 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_p1_p7 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_p3_p7 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_p5_p7 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_m7 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_m5 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_m3 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_m1 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_p1 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_p3 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_p5 __attribute__ ((aligned(32))); +static __m256i psi_a_p7_p7 __attribute__ ((aligned(32))); + +static __m256i a_sq_m7_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_m7_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_m7_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_m7_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_m7_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_m7_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_m7_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_m7_p7 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_m5_p7 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_m3_p7 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_m1_p7 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_p1_p7 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_p3_p7 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_p5_p7 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_m7 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_m5 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_m3 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_m1 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_p1 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_p3 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_p5 __attribute__ ((aligned(32))); +static __m256i a_sq_p7_p7 __attribute__ ((aligned(32))); + +static __m256i bit_met_m7_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_m7_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_m7_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_m7_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_m7_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_m7_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_m7_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_m7_p7 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_m5_p7 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_m3_p7 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_m1_p7 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_p1_p7 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_p3_p7 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_p5_p7 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_m7 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_m5 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_m3 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_m1 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_p1 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_p3 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_p5 __attribute__ ((aligned(32))); +static __m256i bit_met_p7_p7 __attribute__ ((aligned(32))); + +static __m256i y0_p_1_1 __attribute__ ((aligned(32))); +static __m256i y0_p_1_3 __attribute__ ((aligned(32))); +static __m256i y0_p_1_5 __attribute__ ((aligned(32))); +static __m256i y0_p_1_7 __attribute__ ((aligned(32))); +static __m256i y0_p_3_1 __attribute__ ((aligned(32))); +static __m256i y0_p_3_3 __attribute__ ((aligned(32))); +static __m256i y0_p_3_5 __attribute__ ((aligned(32))); +static __m256i y0_p_3_7 __attribute__ ((aligned(32))); +static __m256i y0_p_5_1 __attribute__ ((aligned(32))); +static __m256i y0_p_5_3 __attribute__ ((aligned(32))); +static __m256i y0_p_5_5 __attribute__ ((aligned(32))); +static __m256i y0_p_5_7 __attribute__ ((aligned(32))); +static __m256i y0_p_7_1 __attribute__ ((aligned(32))); +static __m256i y0_p_7_3 __attribute__ ((aligned(32))); +static __m256i y0_p_7_5 __attribute__ ((aligned(32))); +static __m256i y0_p_7_7 __attribute__ ((aligned(32))); +static __m256i y0_m_1_1 __attribute__ ((aligned(32))); +static __m256i y0_m_1_3 __attribute__ ((aligned(32))); +static __m256i y0_m_1_5 __attribute__ ((aligned(32))); +static __m256i y0_m_1_7 __attribute__ ((aligned(32))); +static __m256i y0_m_3_1 __attribute__ ((aligned(32))); +static __m256i y0_m_3_3 __attribute__ ((aligned(32))); +static __m256i y0_m_3_5 __attribute__ ((aligned(32))); +static __m256i y0_m_3_7 __attribute__ ((aligned(32))); +static __m256i y0_m_5_1 __attribute__ ((aligned(32))); +static __m256i y0_m_5_3 __attribute__ ((aligned(32))); +static __m256i y0_m_5_5 __attribute__ ((aligned(32))); +static __m256i y0_m_5_7 __attribute__ ((aligned(32))); +static __m256i y0_m_7_1 __attribute__ ((aligned(32))); +static __m256i y0_m_7_3 __attribute__ ((aligned(32))); +static __m256i y0_m_7_5 __attribute__ ((aligned(32))); +static __m256i y0_m_7_7 __attribute__ ((aligned(32))); + +static __m256i xmm0 __attribute__ ((aligned(32))); +static __m256i xmm1 __attribute__ ((aligned(32))); +static __m256i xmm2 __attribute__ ((aligned(32))); +static __m256i xmm3 __attribute__ ((aligned(32))); +static __m256i xmm4 __attribute__ ((aligned(32))); +static __m256i xmm5 __attribute__ ((aligned(32))); +static __m256i xmm6 __attribute__ ((aligned(32))); +static __m256i xmm7 __attribute__ ((aligned(32))); +static __m256i xmm8 __attribute__ ((aligned(32))); + +static __m256i y0r __attribute__ ((aligned(32))); +static __m256i y0i __attribute__ ((aligned(32))); +static __m256i y1r __attribute__ ((aligned(32))); +static __m256i y1i __attribute__ ((aligned(32))); +static __m256i y2r __attribute__ ((aligned(32))); +static __m256i y2i __attribute__ ((aligned(32))); + +static __m256i logmax_num_re0 __attribute__ ((aligned(32))); +static __m256i logmax_den_re0 __attribute__ ((aligned(32))); + +static __m256i tmp_result __attribute__ ((aligned(32))); +static __m256i tmp_result2 __attribute__ ((aligned(32))); +static __m256i tmp_result3 __attribute__ ((aligned(32))); +static __m256i tmp_result4 __attribute__ ((aligned(32))); + +//============================================================================================== +// Auxiliary Makros + +// calculate interference magnitude +#define interference_abs_epi16(psi,int_ch_mag,int_mag,c1,c2) tmp_result = _mm256_cmpgt_epi16(int_ch_mag,psi); tmp_result2 = _mm256_xor_si256(tmp_result,(*(__m256i*)&ones256[0])); tmp_result = _mm256_and_si256(tmp_result,c1); tmp_result2 = _mm256_and_si256(tmp_result2,c2); int_mag = _mm256_or_si256(tmp_result,tmp_result2); + +// calculate interference magnitude +// tmp_result = ones in shorts corr. to interval 2<=x<=4, tmp_result2 interval < 2, tmp_result3 interval 46 +#define interference_abs_64qam_epi16(psi,int_ch_mag,int_two_ch_mag,int_three_ch_mag,a,c1,c3,c5,c7) tmp_result = _mm256_cmpgt_epi16(int_two_ch_mag,psi); tmp_result3 = _mm256_xor_si256(tmp_result,(*(__m256i*)&ones256[0])); tmp_result2 = _mm256_cmpgt_epi16(int_ch_mag,psi); tmp_result = _mm256_xor_si256(tmp_result,tmp_result2); tmp_result4 = _mm256_cmpgt_epi16(psi,int_three_ch_mag); tmp_result3 = _mm256_xor_si256(tmp_result3,tmp_result4); tmp_result = _mm256_and_si256(tmp_result,c3); tmp_result2 = _mm256_and_si256(tmp_result2,c1); tmp_result3 = _mm256_and_si256(tmp_result3,c5); tmp_result4 = _mm256_and_si256(tmp_result4,c7); tmp_result = _mm256_or_si256(tmp_result,tmp_result2); tmp_result3 = _mm256_or_si256(tmp_result3,tmp_result4); a = _mm256_or_si256(tmp_result,tmp_result3); + +// calculates psi_a = psi_r*a_r + psi_i*a_i +#define prodsum_psi_a_epi16(psi_r,a_r,psi_i,a_i,psi_a) tmp_result = _mm256_mulhi_epi16(psi_r,a_r); tmp_result = _mm256_slli_epi16(tmp_result,1); tmp_result2 = _mm256_mulhi_epi16(psi_i,a_i); tmp_result2 = _mm256_slli_epi16(tmp_result2,1); psi_a = _mm256_adds_epi16(tmp_result,tmp_result2); + +// calculates a_sq = int_ch_mag*(a_r^2 + a_i^2)*scale_factor +#define square_a_epi16(a_r,a_i,int_ch_mag,scale_factor,a_sq) tmp_result = _mm256_mulhi_epi16(a_r,a_r); tmp_result = _mm256_slli_epi16(tmp_result,1); tmp_result = _mm256_mulhi_epi16(tmp_result,scale_factor); tmp_result = _mm256_slli_epi16(tmp_result,1); tmp_result = _mm256_mulhi_epi16(tmp_result,int_ch_mag); tmp_result = _mm256_slli_epi16(tmp_result,1); tmp_result2 = _mm256_mulhi_epi16(a_i,a_i); tmp_result2 = _mm256_slli_epi16(tmp_result2,1); tmp_result2 = _mm256_mulhi_epi16(tmp_result2,scale_factor); tmp_result2 = _mm256_slli_epi16(tmp_result2,1); tmp_result2 = _mm256_mulhi_epi16(tmp_result2,int_ch_mag); tmp_result2 = _mm256_slli_epi16(tmp_result2,1); a_sq = _mm256_adds_epi16(tmp_result,tmp_result2); + +// calculates a_sq = int_ch_mag*(a_r^2 + a_i^2)*scale_factor for 64-QAM +#define square_a_64qam_epi16(a_r,a_i,int_ch_mag,scale_factor,a_sq) tmp_result = _mm256_mulhi_epi16(a_r,a_r); tmp_result = _mm256_slli_epi16(tmp_result,1); tmp_result = _mm256_mulhi_epi16(tmp_result,scale_factor); tmp_result = _mm256_slli_epi16(tmp_result,3); tmp_result = _mm256_mulhi_epi16(tmp_result,int_ch_mag); tmp_result = _mm256_slli_epi16(tmp_result,1); tmp_result2 = _mm256_mulhi_epi16(a_i,a_i); tmp_result2 = _mm256_slli_epi16(tmp_result2,1); tmp_result2 = _mm256_mulhi_epi16(tmp_result2,scale_factor); tmp_result2 = _mm256_slli_epi16(tmp_result2,3); tmp_result2 = _mm256_mulhi_epi16(tmp_result2,int_ch_mag); tmp_result2 = _mm256_slli_epi16(tmp_result2,1); a_sq = _mm256_adds_epi16(tmp_result,tmp_result2); + +void seperate_real_imag_parts(__m256i *out_re, + __m256i *out_im, + __m256i in0, + __m256i in1) +{ + __m256i tmp0; + __m256i tmp1; + + in0 = _mm256_shufflelo_epi16(in0,0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = _mm256_shufflehi_epi16(in0,0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = _mm256_shuffle_epi32(in0,0xd8); //_MM_SHUFFLE(0,2,1,3)); + + in1 = _mm256_shufflelo_epi16(in1,0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = _mm256_shufflehi_epi16(in1,0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = _mm256_shuffle_epi32(in1,0xd8); //_MM_SHUFFLE(0,2,1,3)); + + //in0 = [Re(0,1,2,3) Im(0,1,2,3) Re(4,5,6,7) Im(4,5,6,7)] + //in0 = [Re(8,9,10,11) Im(8,9,10,11) Re(12,13,14,15) Im(12,13,14,15)] + + tmp0 = _mm256_unpacklo_epi64(in0, in1); + //axmm2 = [Re(0,1,2,3) Re(8,9,10,11) Re(4,5,6,7) Re(12,13,14,15)] + tmp0 = _mm256_permute4x64_epi64(tmp0,0xd8); // Re(rho) + + tmp1 = _mm256_unpackhi_epi64(in0, in1); + //axmm3 = [Im(0,1,2,3) Im(8,9,10,11) Im(4,5,6,7) Im(12,13,14,15)] + tmp1 = _mm256_permute4x64_epi64(tmp1,0xd8); // Im(rho) + + *out_re = tmp0; + *out_im = tmp1; +} + +void qam64_qam16_avx2(short *stream0_in, + short *stream1_in, + short *ch_mag, + short *ch_mag_i, + short *stream0_out, + short *rho01, + int length + ) +{ + + /* + Author: S. Wagner + Date: 31-07-12 + + Input: + stream0_in: MF filter for 1st stream, i.e., y0=h0'*y + stream1_in: MF filter for 2nd stream, i.e., y1=h1'*y + ch_mag: 4*h0/sqrt(42), [Re0 Im0 Re1 Im1] s.t. Im0=Re0, Im1=Re1, etc + ch_mag_i: 4*h1/sqrt(42), [Re0 Im0 Re1 Im1] s.t. Im0=Re0, Im1=Re1, etc + rho01: Channel cross correlation, i.e., h1'*h0 + + Output: + stream0_out: output LLRs for 1st stream + */ + +#if defined(__x86_64__) || defined(__i386__) + + __m256i *rho01_256i = (__m256i *)rho01; + __m256i *stream0_256i_in = (__m256i *)stream0_in; + __m256i *stream1_256i_in = (__m256i *)stream1_in; + __m256i *ch_mag_256i = (__m256i *)ch_mag; + __m256i *ch_mag_256i_i = (__m256i *)ch_mag_i; + + __m256i ONE_OVER_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(10112)); // round(1/sqrt(42)*2^16) + __m256i THREE_OVER_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(30337)); // round(3/sqrt(42)*2^16) + __m256i FIVE_OVER_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(25281)); // round(5/sqrt(42)*2^15) + __m256i SEVEN_OVER_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(17697)); // round(5/sqrt(42)*2^15) + __m256i FORTYNINE_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(30969)); // round(49/(4*sqrt(42))*2^14), Q2.14 + __m256i THIRTYSEVEN_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(23385)); // round(37/(4*sqrt(42))*2^14), Q2.14 + __m256i TWENTYFIVE_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(31601)); // round(25/(4*sqrt(42))*2^15) + __m256i TWENTYNINE_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(18329)); // round(29/(4*sqrt(42))*2^15), Q2.14 + __m256i SEVENTEEN_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(21489)); // round(17/(4*sqrt(42))*2^15) + __m256i NINE_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(11376)); // round(9/(4*sqrt(42))*2^15) + __m256i THIRTEEN_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(16433)); // round(13/(4*sqrt(42))*2^15) + __m256i FIVE_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(6320)); // round(5/(4*sqrt(42))*2^15) + __m256i ONE_OVER_FOUR_SQRT_42 = _mm256_broadcastw_epi16(_mm_set1_epi16(1264)); // round(1/(4*sqrt(42))*2^15) + __m256i ONE_OVER_SQRT_10_Q15 = _mm256_broadcastw_epi16(_mm_set1_epi16(10362)); // round(1/sqrt(10)*2^15) + __m256i THREE_OVER_SQRT_10 = _mm256_broadcastw_epi16(_mm_set1_epi16(31086)); // round(3/sqrt(10)*2^15) + __m256i SQRT_10_OVER_FOUR = _mm256_broadcastw_epi16(_mm_set1_epi16(25905)); // round(sqrt(10)/4*2^15) + + + __m256i ch_mag_int; + __m256i ch_mag_des; + __m256i ch_mag_98_over_42_with_sigma2; + __m256i ch_mag_74_over_42_with_sigma2; + __m256i ch_mag_58_over_42_with_sigma2; + __m256i ch_mag_50_over_42_with_sigma2; + __m256i ch_mag_34_over_42_with_sigma2; + __m256i ch_mag_18_over_42_with_sigma2; + __m256i ch_mag_26_over_42_with_sigma2; + __m256i ch_mag_10_over_42_with_sigma2; + __m256i ch_mag_2_over_42_with_sigma2; + __m256i y0r_one_over_sqrt_21; + __m256i y0r_three_over_sqrt_21; + __m256i y0r_five_over_sqrt_21; + __m256i y0r_seven_over_sqrt_21; + __m256i y0i_one_over_sqrt_21; + __m256i y0i_three_over_sqrt_21; + __m256i y0i_five_over_sqrt_21; + __m256i y0i_seven_over_sqrt_21; + +#elif defined(__arm__) + +#endif + int i,j; + uint32_t len256 = (length)>>3; + + for (i=0; i>3; + + for (i=0; i Date: Wed, 8 Mar 2017 10:55:06 +0100 Subject: [PATCH 360/571] [OAI-UE] MIMO fixes + disabling MIB/SIB decoding on connected mode --- openair1/PHY/INIT/lte_init.c | 9 +++ openair1/PHY/LTE_TRANSPORT/dci.c | 48 ++++++------ openair1/PHY/LTE_TRANSPORT/dci_tools.c | 75 ++++++++++++------- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 8 +- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 8 +- openair1/PHY/defs.h | 2 + openair1/SCHED/phy_procedures_lte_ue.c | 34 +++++---- 7 files changed, 114 insertions(+), 70 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index d0556a0235..de83506bb3 100755 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -948,6 +948,11 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, // fill cqi parameters for periodic CQI reporting get_cqipmiri_params(phy_vars_ue,eNB_id); + // disable MIB SIB decoding once we are on connected mode + LOG_I(PHY,"Disabling SIB MIB decoding \n"); + phy_vars_ue->decode_SIB = 0; + phy_vars_ue->decode_MIB = 0; + } void phy_config_cba_rnti (module_id_t Mod_id,int CC_id,eNB_flag_t eNB_flag, uint8_t index, rnti_t cba_rnti, uint8_t cba_group_id, uint8_t num_active_cba_groups) @@ -1306,6 +1311,10 @@ int phy_init_lte_ue(PHY_VARS_UE *ue, ue->high_speed_flag = 1; ue->ch_est_alpha = 24576; + // enable MIB/SIB decoding by default + ue->decode_MIB = 1; + ue->decode_SIB = 1; + init_prach_tables(839); diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 44cc3fffbf..af25e33ff7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -3149,7 +3149,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0) , ra_rnti, P_RNTI, 2, @@ -3177,7 +3177,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 2, @@ -3209,7 +3209,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), P_RNTI, ra_rnti, 3, @@ -3237,7 +3237,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 3, @@ -3271,7 +3271,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 0, @@ -3300,7 +3300,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 1, @@ -3333,7 +3333,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 2, @@ -3362,7 +3362,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 3, @@ -3395,7 +3395,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 0, @@ -3426,7 +3426,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 1, @@ -3458,7 +3458,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 2, @@ -3490,7 +3490,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 3, @@ -3527,7 +3527,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 0, @@ -3562,7 +3562,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 1, @@ -3596,7 +3596,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 2, @@ -3631,7 +3631,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 3, @@ -3665,7 +3665,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 0, @@ -3697,7 +3697,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 1, @@ -3729,7 +3729,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 2, @@ -3762,7 +3762,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 3, @@ -3792,7 +3792,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 0, @@ -3825,7 +3825,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 1, @@ -3857,7 +3857,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 2, @@ -3891,7 +3891,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, eNB_id, frame_parms, mi, - SI_RNTI, + ((ue->decode_SIB == 1) ? SI_RNTI : 0), ra_rnti, P_RNTI, 3, diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index b9b1f6c0ad..1fb842b837 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4763,6 +4763,8 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, + uint32_t frame, + uint8_t subframe, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, LTE_DL_UE_HARQ_t *pdlsch0_harq) { @@ -4779,17 +4781,17 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, uint8_t NPRB = 0; long long int RIV_max = 0; -#ifdef DEBUG_DCI - LOG_I(PHY,"[DCI-FORMAT-1-1A] dci_format %d\n", dci_format); +//#ifdef DEBUG_DCI + LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, subframe, dci_format); LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti %x\n", rnti); LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid %d\n", harq_pid); - LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); - LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); - LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); - LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); - LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); - LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); -#endif + // LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); + // LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); + // LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); + // LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); + // LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); + // LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); +//#endif // I- check dci content minimum coherency if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0) @@ -5002,10 +5004,10 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, LOG_I(PHY, "extarcted dci - mcs2 %d \n", mcs2); LOG_I(PHY, "extarcted dci - rv1 %d \n", rv1); LOG_I(PHY, "extarcted dci - rv2 %d \n", rv2); - LOG_I(PHY, "extarcted dci - ndi1 %d \n", ndi1); - LOG_I(PHY, "extarcted dci - ndi2 %d \n", ndi2); + //LOG_I(PHY, "extarcted dci - ndi1 %d \n", ndi1); + //LOG_I(PHY, "extarcted dci - ndi2 %d \n", ndi2); LOG_I(PHY, "extarcted dci - rballoc %x \n", rballoc); - LOG_I(PHY, "extarcted dci - harq pif %d \n", harq_pid); + LOG_I(PHY, "extarcted dci - harq pid %d \n", harq_pid); LOG_I(PHY, "extarcted dci - round0 %d \n", pdlsch0_harq->round); LOG_I(PHY, "extarcted dci - round1 %d \n", pdlsch1_harq->round); #endif @@ -5818,12 +5820,24 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, } } - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; - //if(dlsch0_harq->Nl == 2) - //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; - if (mcs1 <= 28) + // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest + // PDCCH for the same trasport block using Imcs in [0 .. 28] + if(dlsch0_harq->mcs <= 28) + { + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; + LOG_D(PHY,"[UE] DLSCH: New TBS CW0 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); + } + else + { + LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW0 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); + } + //if(dlsch0_harq->Nl == 2) + //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; + if (mcs1 <= 28) dlsch0_harq->Qm = get_Qm(mcs1); - else if (mcs1<=31) + else if (mcs1<=31) dlsch0_harq->Qm = (mcs1-28)<<1; } @@ -5849,13 +5863,22 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, #endif } - dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; - //if(dlsch0_harq->Nl == 2) - //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; - - if (mcs2 <= 28) + // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest + // PDCCH for the same trasport block using Imcs in [0 .. 28] + if(dlsch1_harq->mcs <= 28) + { + dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; + LOG_D(PHY,"[UE] DLSCH: New TBS CW1 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); + } + else + { + LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW1 subframe %d (pid %d, round %d) TBS %d \n", + subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); + } + if (mcs2 <= 28) dlsch1_harq->Qm = get_Qm(mcs2); - else if (mcs1<=31) + else if (mcs1<=31) dlsch1_harq->Qm = (mcs2-28)<<1; } @@ -5953,7 +5976,7 @@ int generate_ue_dlsch_params_from_dci(int frame, tc_rnti, si_rnti, ra_rnti, - p_rnti, + p_rnti,frame,subframe, &dci_info_extarcted, dlsch0_harq); if(status == 0) @@ -6053,7 +6076,7 @@ int generate_ue_dlsch_params_from_dci(int frame, tc_rnti, si_rnti, ra_rnti, - p_rnti, + p_rnti,frame,subframe, &dci_info_extarcted, dlsch0_harq); if(status == 0) @@ -6133,7 +6156,7 @@ int generate_ue_dlsch_params_from_dci(int frame, case format2A: { // extract dci infomation - //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe); + //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe); extract_dci2A_info(frame_parms->N_RB_DL, frame_type, frame_parms->nb_antenna_ports_eNB, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 7b1fb3cd50..dbe938e3ae 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -364,12 +364,18 @@ int rx_pdsch(PHY_VARS_UE *ue, symbol, nb_rb); - if ((dlsch0_harq->mimo_moden_connected_eNB) && (dlsch0_harq->dl_power_off==0)) // TM5 two-user + if ((dlsch0_harq->mimo_moden_connected_eNB) && + (dlsch0_harq->dl_power_off==0) + ) // TM5 two-user + { dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, frame_parms, dlsch, symbol, nb_rb); + } if (first_symbol_flag==1) { if (beamforming_mode==0){ diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 240758eceb..7497f2e119 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -8846,7 +8846,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, memcpy(ch_mag_256i, ch_mag, len*4); memcpy(ch_mag_i_256i, ch_mag_i, len*4); memcpy(rho_256i, rho, len*4); - /* + + qam64_qam64_avx2((int32_t *)rxF_256i, (int32_t *)rxF_i_256i, (int32_t *)ch_mag_256i, @@ -8854,7 +8855,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (int16_t *)llr16, (int32_t *) rho_256i, len); - */ + + /* qam64_qam16_avx2((short *)rxF_256i, (short *)rxF_i_256i, (short *)ch_mag_256i, @@ -8862,7 +8864,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (short *)llr16, (short *)rho_256i, len); - +*/ free16(rxF_256i, sizeof(rxF_256i)); free16(rxF_i_256i, sizeof(rxF_i_256i)); free16(ch_mag_256i, sizeof(ch_mag_256i)); diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 024e8ddf59..5c1b1158ba 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -802,6 +802,8 @@ typedef struct { uint8_t prach_cnt; uint8_t prach_PreambleIndex; // uint8_t prach_timer; + uint8_t decode_SIB; + uint8_t decode_MIB; int rx_offset; /// Timing offset int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP int timing_advance; ///timing advance signalled from eNB diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 42c75bdc7c..c4938f3f76 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -2082,7 +2082,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif - LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", + LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", Mod_id, ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, @@ -3520,10 +3520,10 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); stop_meas(&ue->dlsch_decoding_stats); - printf(" --> Unscrambling for CW0 %5.3f\n", - (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - printf(" --> Turbo Decoding for CW0 %5.3f\n", - (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + //printf(" --> Unscrambling for CW0 %5.3f\n", + // (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + //printf(" --> Turbo Decoding for CW0 %5.3f\n", + // (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); if(is_cw1_active) { @@ -3568,10 +3568,10 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch1->harq_processes[harq_pid]->TBS>256?1:0); stop_meas(&ue->dlsch_decoding_stats); - printf(" --> Unscrambling for CW1 %5.3f\n", - (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - printf(" --> Turbo Decoding for CW1 %5.3f\n", - (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + //printf(" --> Unscrambling for CW1 %5.3f\n", + // (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + //printf(" --> Turbo Decoding for CW1 %5.3f\n", + // (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); } } @@ -3591,7 +3591,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(dlsch0->rnti != 0xffff) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3603,7 +3603,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, } else { if(dlsch0->rnti != 0xffff) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3857,7 +3857,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) stop_meas(&ue->generic_stat); - printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + //printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); start_meas(&ue->generic_stat); // do procedures for C-RNTI @@ -3952,11 +3952,13 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } // not an S-subframe stop_meas(&ue->generic_stat); - printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + //printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); // run pbch procedures if subframe is 0 - if (subframe_rx == 0) + if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) + { ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); + } // do procedures for C-RNTI if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { @@ -3984,8 +3986,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin mode, abstraction_flag); stop_meas(&ue->dlsch_procedures_stat); - printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0)); - printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); + //printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0)); + //printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); From bb8c6b2c5270e61539b2c18cd1fa7cd988f72c0c Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 8 Mar 2017 11:10:12 +0100 Subject: [PATCH 361/571] [OAI-UE] code clean up for merge --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 16 ++++++++-------- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 14 +------------- openair1/PHY/MODULATION/slot_fep.c | 2 +- openair1/PHY/TOOLS/lte_phy_scope.c | 2 +- openair1/SCHED/phy_procedures_lte_ue.c | 2 +- openair2/RRC/LITE/L2_interface.c | 8 ++++---- 7 files changed, 18 insertions(+), 30 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 1fb842b837..0812e9c6dd 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4781,17 +4781,17 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, uint8_t NPRB = 0; long long int RIV_max = 0; -//#ifdef DEBUG_DCI +#ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, subframe, dci_format); LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti %x\n", rnti); LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid %d\n", harq_pid); - // LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); - // LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); - // LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); - // LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); - // LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); - // LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); -//#endif + LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); + LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); + LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); +#endif // I- check dci content minimum coherency if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 48d6bb86be..d683decc9f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -612,12 +612,12 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); stop_meas(dlsch_turbo_decoding_stats); - printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n", + /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n", harq_process->C, r, dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0), dlsch_deinterleaving_stats->p_time/(cpuf*1000.0), - dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0)); + dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/ } } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index dbe938e3ae..c407a535b5 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -122,7 +122,6 @@ int rx_pdsch(PHY_VARS_UE *ue, - switch (type) { case SI_PDSCH: pdsch_vars = &ue->pdsch_vars_SI[eNB_id]; @@ -234,9 +233,6 @@ int rx_pdsch(PHY_VARS_UE *ue, } } - //LOG_I(PHY,"[rx_pdsch %d] AbsSubframe %d.%d symbol %d rxType %d beamformingMode %d, antennaPorts %d, eNB_id_i %d, n_connected_eNB %d\n", - // harq_pid, frame,subframe, symbol,rx_type, beamforming_mode, frame_parms->nb_antenna_ports_eNB,eNB_id_i,ue->n_connected_eNB); - if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) { #ifdef DEBUG_DLSCH_MOD LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]); @@ -396,7 +392,6 @@ int rx_pdsch(PHY_VARS_UE *ue, ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { - //LOG_I(PHY,"Channel Level TM34 !!!!!!!! \n"); dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, pdsch_vars[eNB_id]->pmi_ext, @@ -530,7 +525,6 @@ int rx_pdsch(PHY_VARS_UE *ue, } } else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ - //LOG_I(PHY,"channel compensation TM34 !!!!!!!!!!!!!!!!!\n"); dlsch_channel_compensation_TM34(frame_parms, pdsch_vars[eNB_id], measurements, @@ -683,7 +677,6 @@ int rx_pdsch(PHY_VARS_UE *ue, ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 if (frame_parms->nb_antenna_ports_eNB == 2) { - //LOG_I(PHY,"MRC Detection TM34 !!!!!!!!!\n"); dlsch_detection_mrc_TM34(frame_parms, pdsch_vars[eNB_id], harq_pid, @@ -745,10 +738,6 @@ int rx_pdsch(PHY_VARS_UE *ue, //i_mod should have been passed as a parameter } - //LOG_I(PHY,"compute LLRs rx_type dual ? %d rx_standard %d codeword_TB0 %d codeword_TB1 %d\n", rx_type==rx_IC_dual_stream, rx_standard, codeword_TB0, codeword_TB1); - //if (rx_type >= rx_IC_single_stream) - //LOG_I(PHY,"LLR0 Qm ? %d LLR1 Qm \n", dlsch0_harq->Qm, dlsch1_harq->Qm); - switch (dlsch0_harq->Qm) { case 2 : if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { @@ -830,7 +819,6 @@ int rx_pdsch(PHY_VARS_UE *ue, } break; case 4 : - if ((rx_type==rx_standard ) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { dlsch_16qam_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, @@ -1004,7 +992,6 @@ int rx_pdsch(PHY_VARS_UE *ue, return(-1); break; } - if (dlsch1_harq) { switch (get_Qm(dlsch1_harq->mcs)) { case 2 : @@ -1050,6 +1037,7 @@ int rx_pdsch(PHY_VARS_UE *ue, } } +// Please keep it: useful for debugging #if 0 if( (symbol == 13) && (dlsch0_harq->mimo_mode == 2) ) { diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index 4b663776df..3a3b3b4c0d 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -48,7 +48,7 @@ int slot_fep(PHY_VARS_UE *ue, unsigned int rx_offset; /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id]; - unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; + unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid]; int uespec_pilot[9][1200];*/ diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 681ee0b51c..7a53346453 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -768,4 +768,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } free(chest_t_abs); -} +} \ No newline at end of file diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index c4938f3f76..8fd0048f45 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -368,7 +368,7 @@ void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance) PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!! - LOG_I(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); + LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); } diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index 4d0ff134ba..fa5a4d6409 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -199,7 +199,7 @@ mac_rrc_data_req( int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); if (ccch_size > sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size0 (%d, %d)", ccch_size, sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); ccch_size = sdu_size; } @@ -297,7 +297,7 @@ mac_rrc_data_req( int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); if (ccch_size > sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size1 (%d, %d)", ccch_size, sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); ccch_size = sdu_size; } @@ -403,7 +403,7 @@ mac_rrc_data_ind( int msg_sdu_size = CCCH_SDU_SIZE; if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size2 (%d, %d)", sdu_size, msg_sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); sdu_size = msg_sdu_size; } else { sdu_size = sdu_lenP; @@ -471,7 +471,7 @@ mac_rrc_data_ind( int msg_sdu_size = sizeof(RRC_MAC_CCCH_DATA_IND (message_p).sdu); if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size3 (%d, %d)", sdu_lenP, msg_sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); sdu_size = msg_sdu_size; } else { sdu_size = sdu_lenP; From 3d1e01e283ada734e5de62a387f4b6c6e307ee57 Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 8 Mar 2017 11:25:41 +0100 Subject: [PATCH 362/571] [OAI-UE] llr computation clean up --- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 7497f2e119..b08836762c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -8831,7 +8831,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } -//#ifdef __AVX2__ +#ifdef __AVX2__ // Round length up to multiple of 16 words uint32_t len256i = ((len+16)>>4)*16; @@ -8847,7 +8847,6 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, memcpy(ch_mag_i_256i, ch_mag_i, len*4); memcpy(rho_256i, rho, len*4); - qam64_qam64_avx2((int32_t *)rxF_256i, (int32_t *)rxF_i_256i, (int32_t *)ch_mag_256i, @@ -8856,23 +8855,13 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (int32_t *) rho_256i, len); - /* - qam64_qam16_avx2((short *)rxF_256i, - (short *)rxF_i_256i, - (short *)ch_mag_256i, - (short *)ch_mag_i_256i, - (short *)llr16, - (short *)rho_256i, - len); -*/ free16(rxF_256i, sizeof(rxF_256i)); free16(rxF_i_256i, sizeof(rxF_i_256i)); free16(ch_mag_256i, sizeof(ch_mag_256i)); free16(ch_mag_i_256i, sizeof(ch_mag_i_256i)); free16(rho_256i, sizeof(rho_256i)); -//#else -/* +#else qam64_qam64((short *)rxF, (short *)rxF_i, (short *)ch_mag, @@ -8880,9 +8869,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (short *)llr16, (short *)rho, len); -*/ - -//#endif +#endif llr16 += (6*len); *llr16p = (short *)llr16; From 05fe029a6228ddf86403d6bddfc4d6a7cb39977b Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 8 Mar 2017 13:59:49 +0100 Subject: [PATCH 363/571] [OAI-UE] fix in de-precoding for tm3/4 --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index c407a535b5..65fc807aa8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -1682,10 +1682,10 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { // print_shorts("prec2A_TM3 ch0 (mid):",&tmp0); // print_shorts("prec2A_TM3 ch1 (mid):",ch1); - ch0[0] = _mm_mulhi_epi16(ch0[0],amp); - ch0[0] = _mm_slli_epi16(ch0[0],1); - ch1[0] = _mm_mulhi_epi16(ch1[0],amp); - ch1[0] = _mm_slli_epi16(ch1[0],1); + //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); + //ch0[0] = _mm_slli_epi16(ch0[0],1); + //ch1[0] = _mm_mulhi_epi16(ch1[0],amp); + //ch1[0] = _mm_slli_epi16(ch1[0],1); //ch0[0] = _mm_srai_epi16(ch0[0],1); //ch1[0] = _mm_srai_epi16(ch1[0],1); From 9dd65f28016e595d878d36ff61794c3dd138ff63 Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 8 Mar 2017 14:21:14 +0100 Subject: [PATCH 364/571] [OAI-UE] remove unused debug-printf --- openair1/SCHED/phy_procedures_lte_ue.c | 12 +-- openair3/NAS/TOOLS/ue_tcl_test.conf | 114 +++++++++++++++++++++++++ targets/RT/USER/lte-ue.c | 2 +- 3 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 openair3/NAS/TOOLS/ue_tcl_test.conf diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 8fd0048f45..4a75d5d9e7 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1537,7 +1537,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB mac_xface->macphy_exit("Error in ulsch_coding"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_tx); - printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); + //printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); return; } } @@ -3591,7 +3591,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(dlsch0->rnti != 0xffff) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3603,7 +3603,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, } else { if(dlsch0->rnti != 0xffff) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3672,7 +3672,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(is_cw1_active) { if (ret1 == (1+dlsch0->max_turbo_iterations)) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3680,7 +3680,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[harq_pid]->TBS); } else { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -4100,7 +4100,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]); - printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0)); + //printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0)); return (0); } diff --git a/openair3/NAS/TOOLS/ue_tcl_test.conf b/openair3/NAS/TOOLS/ue_tcl_test.conf new file mode 100644 index 0000000000..05db6be4d1 --- /dev/null +++ b/openair3/NAS/TOOLS/ue_tcl_test.conf @@ -0,0 +1,114 @@ +# List of known PLMNS +PLMN: { + PLMN0: { + FULLNAME="Test network"; + SHORTNAME="OAI4G"; + MNC="01"; + MCC="001"; + + }; + PLMN1: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="10"; + MCC="208"; + + }; + PLMN2: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="11"; + MCC="208"; + }; + PLMN3: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="13"; + MCC="208"; + }; + PLMN4: { + FULLNAME="OAI LTEBOX"; + SHORTNAME="OAIALU"; + MNC="93"; + MCC="208"; + }; + PLMN5: { + FULLNAME="T-Mobile USA"; + SHORTNAME="T-Mobile"; + MNC="280"; + MCC="310"; + }; + PLMN6: { + FULLNAME="FICTITIOUS USA"; + SHORTNAME="FICTITIO"; + MNC="028"; + MCC="310"; + }; + PLMN7: { + FULLNAME="Vodafone Italia"; + SHORTNAME="VODAFONE"; + MNC="10"; + MCC="222"; + }; + PLMN8: { + FULLNAME="Vodafone Spain"; + SHORTNAME="VODAFONE"; + MNC="01"; + MCC="214"; + }; + PLMN9: { + FULLNAME="Vodafone Spain"; + SHORTNAME="VODAFONE"; + MNC="06"; + MCC="214"; + }; + PLMN10: { + FULLNAME="Vodafone Germ"; + SHORTNAME="VODAFONE"; + MNC="02"; + MCC="262"; + }; + PLMN11: { + FULLNAME="Vodafone Germ"; + SHORTNAME="VODAFONE"; + MNC="04"; + MCC="262"; + }; +}; + +UE0: +{ + USER: { + IMEI="356113022094149"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="000001234"; + USIM_API_K="000102030405060708090A0B0C0D0E0F"; + OPC="C42449363BBAD02B66D16BC975D77CC1"; + MSISDN="000000000000";//"33611123456"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "00101"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20893", "310280", "310028"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 5603d86ade..1ddc06f33b 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -574,7 +574,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { } stop_meas(&UE->generic_stat); - printf("mac_xface->ue_scheduler %5.2f \n",UE->generic_stat.p_time/(cpuf*1000.0)); + //printf("mac_xface->ue_scheduler %5.2f \n",UE->generic_stat.p_time/(cpuf*1000.0)); // Prepare the future Tx data From 305ebf5c4b8904081a226e7a2fb85a3253d6f14c Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 8 Mar 2017 14:57:30 +0100 Subject: [PATCH 365/571] rebase branch to develop 2017.w09 --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3 +-- openair3/NAS/TOOLS/network.h | 2 +- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 8 ++++---- openair3/NAS/UE/ESM/esm_ebr_context.c | 2 +- targets/RT/USER/lte-ue.c | 1 - 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 0812e9c6dd..c4e379b45a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5710,9 +5710,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, if (TB0_active==0) { dlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; -#ifdef DEBUG_HARQ + #ifdef DEBUG_HARQ printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); -#endif + #endif } if (TB1_active==0) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 65fc807aa8..72b486c042 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -1661,8 +1661,7 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { __m128i tmp0,tmp1; - -//_mm_mulhi_epi16 + //_mm_mulhi_epi16 // print_shorts("prec2A_TM3 ch0 (before):",ch0); // print_shorts("prec2A_TM3 ch1 (before):",ch1); diff --git a/openair3/NAS/TOOLS/network.h b/openair3/NAS/TOOLS/network.h index d7044c8e51..0d60359c57 100644 --- a/openair3/NAS/TOOLS/network.h +++ b/openair3/NAS/TOOLS/network.h @@ -61,7 +61,7 @@ Description Defines a list of PLMN network operators #define VDF5 11 -#define SELECTED_PLMN TEST1 //SFR1 +#define SELECTED_PLMN OAI_LTEBOX //SFR1 #define TEST_PLMN {0,0,0x0f,1,1,0} // 00101 #define SFR_PLMN_1 {0,2,0x0f,8,0,1} // 20810 diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index 05db6be4d1..84ec59a36b 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -86,14 +86,14 @@ UE0: }; SIM: { - MSIN="000001234"; - USIM_API_K="000102030405060708090A0B0C0D0E0F"; + MSIN="0100001111"; + USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; OPC="C42449363BBAD02B66D16BC975D77CC1"; - MSISDN="000000000000";//"33611123456"; + MSISDN="33611123456"; }; # Home PLMN Selector with Access Technology - HPLMN= "00101"; + HPLMN= "20893"; # User controlled PLMN Selector with Access Technology UCPLMN_LIST = (); diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 31f215e359..bfa4a04cc8 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -286,7 +286,7 @@ int esm_ebr_context_create( LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); - //if (system(command_line)) ; /* TODO: what to do? */ + if (system(command_line)) ; /* TODO: what to do? */ break; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 1ddc06f33b..49093ed2de 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -574,7 +574,6 @@ static void *UE_thread_rxn_txnp4(void *arg) { } stop_meas(&UE->generic_stat); - //printf("mac_xface->ue_scheduler %5.2f \n",UE->generic_stat.p_time/(cpuf*1000.0)); // Prepare the future Tx data From 7c7172ca18f67c1f86a8e1c8eaf6d532efa2c5a0 Mon Sep 17 00:00:00 2001 From: GabrielCouturier Date: Wed, 8 Mar 2017 17:16:30 +0100 Subject: [PATCH 366/571] RLC AM fix bad pointer init in ReSegmentation --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 1697b9cac5..a4805df368 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -352,13 +352,13 @@ mem_block_t* rlc_am_retransmit_get_am_segment( { /* Step 1 */ /* Find the SDU index in the original PDU containing retx_so_start */ - uint16_t temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); sdu_size_t sdu_size = 0; sdu_size_t data_size = 0; sdu_size_t header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; pdu_original_header_p = pdu_mngt->first_byte + 2; li_bit_offset = 4; /* toggle between 0 and 4 */ li_jump_offset = 1; /* toggle between 1 and 2 */ + uint16_t temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); /* Read first LI */ From 4342595ea8379630bc48a78c1ae678fbd7e1f8b9 Mon Sep 17 00:00:00 2001 From: "Raymond.Knopp" Date: Thu, 9 Mar 2017 02:43:31 +0100 Subject: [PATCH 367/571] calibration (RX) for LimeSDR. Use of new API for RF gains. --- targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 28 +++++++++---------- .../CONF/enb.band13.tm1.50PRB.lmssdr.conf | 12 ++++---- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index 1e3e1a8cbf..4d020aa319 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -134,15 +134,15 @@ int trx_lms_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) int ret=0; - double rxg_ratio = openair0_cfg[0].rx_gain[0]/openair0_cfg[0].rx_gain_offset[0]; - if (rxg_ratio > 1) { - printf("[LMS] Reduce RX Gain 0 by %f dB\n",openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]); + // double rxg_ratio = openair0_cfg[0].rx_gain[0]/openair0_cfg[0].rx_gain_offset[0]; + if (openair0_cfg->rx_gain[0] > 70+openair0_cfg->rx_gain_offset[0]) { + printf("[LMS] Reduce RX Gain 0 by %f dB\n",openair0_cfg->rx_gain[0]-openair0_cfg->rx_gain_offset[0]-70); ret = -1; - rxg_ratio = 1; + // rxg_ratio = 1; } - LMS_SetNormalizedGain(lms_device, LMS_CH_TX, 0, openair0_cfg[0].tx_gain[0]/100.0); - LMS_SetNormalizedGain(lms_device, LMS_CH_RX, 0, .8*rxg_ratio); + LMS_SetGaindB(lms_device, LMS_CH_TX, 0, openair0_cfg->tx_gain[0]); + LMS_SetGaindB(lms_device, LMS_CH_RX, 0, openair0_cfg->rx_gain[0]-openair0_cfg->rx_gain_offset[0]); /* // RX gains, use low-level setting double gv = openair0_cfg[0].rx_gain[0] - openair0_cfg[0].rx_gain_offset[0]; @@ -309,18 +309,18 @@ int trx_lms_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,in // V1.2 board rx_gain_calib_table_t calib_table_lmssdr_1v2[] = { {3500000000.0,44.0}, // on L PAD - {2660000000.0,62.0}, // on L PAD - {2300000000.0,62.0}, // on L PAD - {1880000000.0,64.0}, // on L PAD + {2660000000.0,55.0}, // on L PAD + {2300000000.0,54.0}, // on L PAD + {1880000000.0,54.0}, // on L PAD {816000000.0,79.0}, // on W PAD {-1,0}}; // V1.4 board rx_gain_calib_table_t calib_table_lmssdr[] = { - {3500000000.0,97.0}, // on H PAD - {2660000000.0,110.0}, // on H PAD - {2300000000.0,106.0}, // on H PAD - {1880000000.0,106.0}, // on H PAD - {816000000.0,116.0}, // on W PAD + {3500000000.0,44.0}, // on H PAD + {2660000000.0,55.0}, // on H PAD + {2300000000.0,54.0}, // on H PAD + {1880000000.0,54.0}, // on H PAD + {816000000.0,79.0}, // on L PAD {-1,0}}; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf index 3eea96059b..1083aa382a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.lmssdr.conf @@ -40,7 +40,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 20; - rx_gain = 116; + rx_gain = 100; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -136,7 +136,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.70"; + mme_ip_address = ( { ipv4 = "127.0.0.3"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -145,11 +145,11 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.150/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; - ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.150/24"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; From 28c009a0727cc25e43fd9daf8154912e1bc421d4 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 9 Mar 2017 10:20:52 +0100 Subject: [PATCH 368/571] Chenge LOG_I to LOG_D --- openair1/SCHED/phy_procedures_lte_ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 4a75d5d9e7..4affba6814 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1477,7 +1477,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } #endif - LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", + LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", Mod_id, ue->ulsch[eNB_id]->rnti, frame_tx,subframe_tx, From 7f60e38fee2f9f14cda568348cc5043ea656128e Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 9 Mar 2017 16:04:31 +0100 Subject: [PATCH 369/571] RCL AM: fixes on Tx resegmentation --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 223 +++++++++++------- 1 file changed, 141 insertions(+), 82 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index a4805df368..314bdc56c1 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -314,6 +314,10 @@ mem_block_t* rlc_am_retransmit_get_am_segment( retx_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; retx_so_stop = pdu_mngt->hole_so_stop[pdu_mngt->retx_hole_index]; + AssertFatal (retx_so_start <= retx_so_stop, + "RLC AM Tx PDU Segment Data SO Error: retx_so_start=%d retx_so_stop=%d sn=%d LcId=%d!\n", + retx_so_start,retx_so_stop,sn,rlc_pP->channel_id); + /* Init FI to the same value as original PDU */ fi_start = (!(RLC_AM_PDU_GET_FI_START(*(pdu_mngt->first_byte)))); fi_end = (!(RLC_AM_PDU_GET_FI_END(*(pdu_mngt->first_byte)))); @@ -328,6 +332,11 @@ mem_block_t* rlc_am_retransmit_get_am_segment( } *payload_sizeP = retx_so_stop - retx_so_start + 1; + + AssertFatal (retx_so_stop <= pdu_mngt->payload_size - 1, + "RLC AM Tx PDU Segment Data Error noLI: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d sn=%d LcId=%d !\n", + retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,sn,rlc_pP->channel_id); + mem_pdu_segment_p = get_free_mem_block((*payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + sizeof(struct mac_tb_req)), __func__); pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; @@ -354,6 +363,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* Find the SDU index in the original PDU containing retx_so_start */ sdu_size_t sdu_size = 0; sdu_size_t data_size = 0; + *payload_sizeP = 0; sdu_size_t header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; pdu_original_header_p = pdu_mngt->first_byte + 2; li_bit_offset = 4; /* toggle between 0 and 4 */ @@ -368,29 +378,10 @@ mem_block_t* rlc_am_retransmit_get_am_segment( li_jump_offset ^= 0x3; data_size += sdu_size; - while ((data_size - 1 < retx_so_start) && (sdu_index < pdu_mngt->nb_sdus)) + /* Loop on all original LIs */ + while ((data_size < retx_so_start + 1) && (sdu_index + 1 < pdu_mngt->nb_sdus - 1)) { sdu_index ++; - if (sdu_index < pdu_mngt->nb_sdus) - { - temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); - sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); - pdu_original_header_p += li_jump_offset; - li_bit_offset ^= 0x4; - li_jump_offset ^= 0x3; - data_size += sdu_size; - } - } - - /* Set FI Start if retx_so_start = cumulated data size */ - if (retx_so_start == data_size) - { - fi_start = TRUE; - /* jump to next SDU */ - sdu_index ++; - /* there must be at least one SDU more */ - AssertFatal (sdu_index < pdu_mngt->nb_sdus, "RLC AM PDU Segment Error: sdu_index=%d nb_sdus=%d sn=%d LcId=%d !\n", - sdu_index,pdu_mngt->nb_sdus,sn,rlc_pP->channel_id); temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); pdu_original_header_p += li_jump_offset; @@ -398,15 +389,25 @@ mem_block_t* rlc_am_retransmit_get_am_segment( li_jump_offset ^= 0x3; data_size += sdu_size; } - /* Set first SDU portion of the segment */ - sdus_segment_size[0] = data_size - retx_so_start; - /* Now look for the end */ - while ((data_size - 1 < retx_so_stop) && (sdu_index < pdu_mngt->nb_sdus)) + /* if retx_so_start is still not included then set data_size with full original PDU data size */ + /* Set fi_start to FALSE in this case */ + if ((data_size < retx_so_start + 1) && (sdu_index == pdu_mngt->nb_sdus - 1)) { + data_size = pdu_mngt->payload_size; + fi_start = FALSE; + + } + else if (retx_so_start == data_size) + { + /* Set FI Start if retx_so_start = cumulated data size */ + fi_start = TRUE; + /* jump to next SDU */ sdu_index ++; - sdu_segment_index ++; - if (sdu_index < pdu_mngt->nb_sdus) + /* there must be at least one SDU more */ + AssertFatal (sdu_index < pdu_mngt->nb_sdus, "RLC AM Tx PDU Segment Error: sdu_index=%d nb_sdus=%d sn=%d LcId=%d !\n", + sdu_index,pdu_mngt->nb_sdus,sn,rlc_pP->channel_id); + if (sdu_index < pdu_mngt->nb_sdus - 1) { temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); @@ -414,69 +415,132 @@ mem_block_t* rlc_am_retransmit_get_am_segment( li_bit_offset ^= 0x4; li_jump_offset ^= 0x3; data_size += sdu_size; - sdus_segment_size[sdu_segment_index] = sdu_size; - } - } - - /* Set FI End if retx_so_stop = cumulated data size */ - if (retx_so_stop == data_size - 1) - { - fi_end = TRUE; - } - /* Set last SDU portion of the segment even if it will be out of LI */ - if (sdu_segment_index) - { - sdus_segment_size[sdu_segment_index] = retx_so_stop - (data_size - sdu_size) + 1; - } - else - { - sdus_segment_size[0] = retx_so_stop - retx_so_start + 1; - } - - /* Set number of LIs in the segment */ - num_LIs_pdu_segment = sdu_segment_index; - - /* Memory allocation taking into account available TBS */ - /* Compute Header Length and Data Length */ - /* Init Segment Payload data size */ - *payload_sizeP = sdus_segment_size[0]; - - /* Bound to available TBS taking into account min PDU segment header*/ - if (*payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE > rlc_pP->nb_bytes_requested_by_mac) - { - *payload_sizeP = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; - } - - sdu_segment_index = 1; - while ((sdu_segment_index < num_LIs_pdu_segment + 1) && (rlc_pP->nb_bytes_requested_by_mac > *payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index))) - { - /* Add next sdu_segment_index to data part */ - if (RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index) + sdus_segment_size[sdu_segment_index] < rlc_pP->nb_bytes_requested_by_mac) - { - (*payload_sizeP) += sdus_segment_size[sdu_segment_index]; } else { - /* bound to available TBS size */ - (*payload_sizeP) += (rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index)); - sdus_segment_size[sdu_segment_index] = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); + /* It was the last LI, then set data_size to full original PDU size */ + data_size = pdu_mngt->payload_size; } - header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); - sdu_segment_index ++; + } + else if (retx_so_start != 0) + { + /* in all other cases set fi_start to FALSE if it SO Start is not 0 */ + fi_start = FALSE; } - num_LIs_pdu_segment = sdu_segment_index - 1; + /* Set first SDU portion of the segment */ + sdus_segment_size[0] = data_size - retx_so_start; + + /* Check if so end is in the first SDU portion */ + if (sdus_segment_size[0] > retx_so_stop - retx_so_start + 1) + { + sdus_segment_size[0] = retx_so_stop - retx_so_start + 1; + *payload_sizeP = sdus_segment_size[0]; + num_LIs_pdu_segment = 0; + } + + /* Bound first SDU segment to available TBS if necessary */ + if (sdus_segment_size[0] + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE >= rlc_pP->nb_bytes_requested_by_mac) + { + sdus_segment_size[0] = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; + *payload_sizeP = sdus_segment_size[0]; + num_LIs_pdu_segment = 0; + } + + + /* Now look for the end if it was not set previously */ + if (*payload_sizeP == 0) + { + sdu_index ++; + sdu_segment_index ++; + while (sdu_index < pdu_mngt->nb_sdus) + { + if (sdu_index < pdu_mngt->nb_sdus - 1) + { + temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); + sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); + pdu_original_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + data_size += sdu_size; + } + else + { + sdu_size = pdu_mngt->payload_size - data_size; + data_size = pdu_mngt->payload_size; + } + + if (data_size >= retx_so_stop + 1) + { + sdus_segment_size[sdu_segment_index] = retx_so_stop - (data_size - sdu_size) + 1; + break; + } + + sdus_segment_size[sdu_segment_index] = sdu_size; + sdu_index ++; + sdu_segment_index ++; + } + + + /* Set number of LIs in the segment */ + num_LIs_pdu_segment = sdu_segment_index; + + AssertFatal (num_LIs_pdu_segment <= pdu_mngt->nb_sdus - 1, "RLC AM Tx PDU Segment Data Error: nbLISegment=%d nbLIPDU=%d sn=%d LcId=%d !\n", + num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id); + + /* Bound to available TBS taking into account min PDU segment header*/ + sdu_segment_index = 0; + while ((sdu_segment_index < num_LIs_pdu_segment + 1) && (rlc_pP->nb_bytes_requested_by_mac > *payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index))) + { + /* Add next sdu_segment_index to data part */ + if (RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index) + sdus_segment_size[sdu_segment_index] <= rlc_pP->nb_bytes_requested_by_mac) + { + (*payload_sizeP) += sdus_segment_size[sdu_segment_index]; + } + else + { + /* bound to available TBS size */ + (*payload_sizeP) += (rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index)); + sdus_segment_size[sdu_segment_index] = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); + } + header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); + sdu_segment_index ++; + } + + num_LIs_pdu_segment = sdu_segment_index - 1; + } + + + /* update retx_so_stop */ + retx_so_stop = retx_so_start + (*payload_sizeP) - 1; + + AssertFatal (retx_so_stop <= pdu_mngt->payload_size - 1, + "RLC AM Tx PDU Segment Data Error: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d numLISegment=%d sn=%d LcId=%d !\n", + retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,num_LIs_pdu_segment,sn,rlc_pP->channel_id); + + /* init FI End to FALSE if retx_so_stop is not end of PDU */ + if (retx_so_stop != pdu_mngt->payload_size - 1) + { + fi_end = FALSE; + } /* Check consistency between sdus_segment_size and payload_sizeP */ + /* And Set FI End if retx_so_stop = cumulated data size and this is not last SDU */ data_size = 0; for (int i = 0; i < num_LIs_pdu_segment + 1; i++) { data_size += sdus_segment_size[i]; + if ((retx_so_stop == data_size - 1) && (i < num_LIs_pdu_segment)) + { + fi_end = TRUE; + } } AssertFatal (data_size == *payload_sizeP, "RLC AM PDU Segment Data Error: SduSum=%d Data=%d sn=%d LcId=%d !\n", data_size,*payload_sizeP,sn,rlc_pP->channel_id); + + /* Allocation */ AssertFatal (header_segment_length + *payload_sizeP <= pdu_mngt->header_and_payload_size + 2, "RLC AM PDU Segment Error: Hdr=%d Data=%d Original Hdr+Data =%d sn=%d LcId=%d !\n", header_segment_length,*payload_sizeP,pdu_mngt->header_and_payload_size,sn,rlc_pP->channel_id); @@ -521,27 +585,22 @@ mem_block_t* rlc_am_retransmit_get_am_segment( pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ - /* copy first two bytes from original: D/C + RF + FI + E+ SN*/ - *pdu_segment_header_p = *(pdu_mngt->first_byte); - *(pdu_segment_header_p + 1) = *(pdu_mngt->first_byte + 1); - - /* Set Segmentation Flag */ + RLC_AM_PDU_SET_D_C(*pdu_segment_header_p); RLC_AM_PDU_SET_RF(*pdu_segment_header_p); - /* clear polling */ - RLC_AM_PDU_CLEAR_POLL(*pdu_segment_header_p); /* Change FI */ if (!fi_start) { // Set to not starting (*pdu_segment_header_p) |= (1 << (RLC_AM_PDU_FI_OFFSET + 1)); - } if (!fi_end) { // Set to not starting (*pdu_segment_header_p) |= (1 << (RLC_AM_PDU_FI_OFFSET)); - } + /* Set SN */ + (*pdu_segment_header_p) |= ((sn >> 8) & 0x3); + (*(pdu_segment_header_p + 1)) |= (sn & 0xFF); /* Segment Offset */ header_so_part = retx_so_start; From 4abc1d21e345eaabf74bb03a1c6342ffa7a11cc3 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 9 Mar 2017 16:33:07 +0100 Subject: [PATCH 370/571] 20 MHz UE fix --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 23 ++++++++++++------- openair1/SCHED/phy_procedures_lte_ue.c | 23 +++++++++++-------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 72b486c042..9ed40ce162 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -3356,7 +3356,7 @@ ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); //compute average channel_level on each (TX,RX) antenna pair void dlsch_channel_level(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, - int *avg, + int32_t *avg, uint8_t symbol, unsigned short nb_rb) { @@ -3365,10 +3365,16 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, short rb; unsigned char aatx,aarx,nre=12,symbol_mod; - __m128i *dl_ch128, avg128D; + __m128i *dl_ch128, avg128D, coeff128; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; + float one_over_nb_re = 0; + one_over_nb_re = 1/(nb_rb *12); + int16_t one_over_nb_re_q1_15 = (int16_t)(one_over_nb_re * (float)(1<<15) ); + coeff128 = _mm_set_epi16(one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15, + one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15); + for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) for (aarx=0; aarxnb_antennas_rx; aarx++) { //clear average level @@ -3380,8 +3386,9 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, for (rb=0;rbNcp-1)))&&(frame_parms->mode1_flag==0)) { dl_ch128+=2; } @@ -3405,10 +3412,10 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, else nre=12; - avg[(aatx<<1)+aarx] = (((int*)&avg128D)[0] + - ((int*)&avg128D)[1] + - ((int*)&avg128D)[2] + - ((int*)&avg128D)[3])/(nb_rb*nre); + avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] + + ((int32_t*)&avg128D)[1] + + ((int32_t*)&avg128D)[2] + + ((int32_t*)&avg128D)[3]); // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); } diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 4affba6814..96082340b9 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1048,7 +1048,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int overflow=0; int k,l; - int dummy_tx_buffer[3840*4] __attribute__((aligned(16))); + int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16))); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN); @@ -1081,11 +1081,15 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt overflow = ulsch_start - 9*frame_parms->samples_per_tti; for (aa=0; aanb_antennas_tx; aa++) { - memset(&ue->common_vars.txdata[aa][ulsch_start],0, - 4*cmin(frame_parms->samples_per_tti-overflow,frame_parms->samples_per_tti)); - - if (overflow> 0) + if (overflow > 0) + { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow)); memset(&ue->common_vars.txdata[aa][0],0,4*overflow); + } + else + { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti); + } } /*#else overflow = ulsch_start - 9*frame_parms->samples_per_tti; @@ -1480,7 +1484,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", Mod_id, ue->ulsch[eNB_id]->rnti, - frame_tx,subframe_tx, + frame_tx%1024,subframe_tx, ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } @@ -1644,8 +1648,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", - Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); + LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); start_meas(&ue->ulsch_modulation_stats); ulsch_modulation(ue->common_vars.txdataF, tx_amp, @@ -1943,7 +1947,8 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin (uint8_t *)&pucch_payload, &len); - LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); + LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", + frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); // Part - IV From 0ce73b4d0ec72e6ece27fc2d0f19ae672f01f20a Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 9 Mar 2017 18:08:43 +0100 Subject: [PATCH 371/571] RLC AM Rx PDU Segment fixes --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 97 +++++++++++++------ 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 69201d7066..cc84ef9ab5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -298,9 +298,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( /*****************************************************/ // 1) Find previous cursor to the PDU to insert /*****************************************************/ - previous_cursor_p = cursor_p; pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - pdu_info_previous_cursor_p = pdu_info_cursor_p; while (cursor_p != NULL) { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; @@ -320,11 +318,10 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( // First case : cursor_p is NULL or its SN is different from the received one, it means the SN is received for the first time // Insert PDU after previous_cursor_p if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { - rlc_usn_t sn_prev = pdu_info_previous_cursor_p->sn; - if (RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(pdu_rx_info_p->sn,rlc_pP->vr_r)) { + if (previous_cursor_p != NULL) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d] PDU SEGMENT INSERTED AFTER PDU SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, - sn_prev); + pdu_info_previous_cursor_p->sn); list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); } else { /* SN of head of Rx PDU list is higher than received PDU SN */ @@ -337,6 +334,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( return RLC_AM_DATA_PDU_STATUS_OK; } + /* Now handle case cursor->sn = received SN */ // Filter out SN duplicate rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); @@ -362,29 +360,29 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( } /* if not previously inserted, it will be put after the last segment if it was not LSF*/ - if ((!prev_segment_found) && (pdu_info_previous_cursor_p->lsf == 0)) { - prev_segment_found = TRUE; - next_segment_found = TRUE; // no more segment after the PDU - next_cursor_p = cursor_p; - AssertFatal(previous_cursor_p->next == next_cursor_p,"AM Rx PDU Segment store at the end error, SN=%d \n",pdu_rx_info_p->sn); + if (!prev_segment_found) { + if (pdu_info_previous_cursor_p->lsf == 0) { + prev_segment_found = TRUE; + next_segment_found = TRUE; // no more segment after the PDU + next_cursor_p = cursor_p; + AssertFatal(previous_cursor_p->next == next_cursor_p,"AM Rx PDU Segment store at the end error, SN=%d \n",pdu_rx_info_p->sn); + } + else + { + // the segment is duplicate + return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; + } } - else - { - // the segment is duplicate - return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; - } - // Check that the Segment is not duplicate by scanning stored contiguous segments from previous_cursor_p - pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; if ((previous_cursor_p != NULL) && (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn)) { + so_start = pdu_info_previous_cursor_p->so; so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - 1; - cursor_p = previous_cursor_p; - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - cursor_p = cursor_p->next; + pdu_info_cursor_p = pdu_info_previous_cursor_p; + cursor_p = previous_cursor_p->next; rlc_am_pdu_info_t* pdu_info_cursor_next_p = NULL; if (cursor_p != NULL) { pdu_info_cursor_next_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; @@ -403,7 +401,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( /* Now discard the PDU segment if it is within so_start so_end */ if ((so_start <= so_start_segment) && (so_end_segment <= so_end)) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; } } @@ -411,8 +409,37 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( // Now found the segment which will be right after the pdu to insert if (!next_segment_found) { + /* special case if SN=vrR and some segments have been previously reassembled and not yet discarded */ + /* update previous_cursor_p up to the last reassembled Segment */ + if ((previous_cursor_p != NULL) && (pdu_rx_info_p->sn == rlc_pP->vr_r)) { + if (((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED) { + pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; + so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size; + cursor_p = previous_cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + + while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && + (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED)) { + AssertFatal(pdu_info_cursor_p->so == so_end,"AM Rx PDU Segment store contiguous reassembled error, SN=%d \n",pdu_rx_info_p->sn); + so_end += pdu_info_cursor_p->payload_size; + previous_cursor_p = cursor_p; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + } + } + + if (previous_cursor_p != NULL) { + cursor_p = previous_cursor_p->next; + } + else { + cursor_p = rlc_pP->receiver_buffer.head; + } - cursor_p = previous_cursor_p->next; next_cursor_p = cursor_p; if (next_cursor_p != NULL) { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; @@ -435,10 +462,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( /* Now remove duplicate bytes */ // remove duplicate at the begining, only valid if the segment is to be inserted after a PDU segment of the same SN - pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; - if (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) { - so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - pdu_rx_info_p->so); + if (previous_cursor_p != NULL) { + pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; + if (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) { + so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - pdu_rx_info_p->so); + } } + // remove duplicate at the end if (next_cursor_p != NULL) { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; @@ -448,6 +478,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( } } + AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) && (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), " AM RX PDU Segment Duplicate elimination error OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n", @@ -462,7 +493,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1,pdu_rx_info_p->sn); - list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer); + if (previous_cursor_p != NULL) { + list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer); + } + else { + list2_insert_before_element(trunc_segment, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer); + } + /* Free original PDU Segment */ free_mem_block(tb_pP, __func__); @@ -474,7 +511,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( } else { - list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + if (previous_cursor_p != NULL) { + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + } + else { + list2_insert_before_element(tb_pP, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer); + } + return RLC_AM_DATA_PDU_STATUS_OK; } } From e6cd9873cdc0e3e5c9cf32f735bd8868f36e30da Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Mar 2017 12:19:29 +0100 Subject: [PATCH 372/571] cleanup test setup README file --- cmake_targets/autotests/README.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index 8156e31bee..ca53680f36 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -213,7 +213,7 @@ Obj.# Case# Test# Description 01 63 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX 01 63 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX -01 65 00 lte-softmodem tests with BladeRF RF as eNB and ALU EPC w/ Bandrich COTS UE for 1TX/1RX +01 65 lte-softmodem tests with BladeRF RF as eNB and ALU EPC w/ Bandrich COTS UE for 1TX/1RX 01 65 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX 01 65 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX 01 65 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX @@ -222,7 +222,7 @@ Obj.# Case# Test# Description 01 65 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX -01 70 00 lte-softmodem tests with SoDeRa RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX +01 70 lte-softmodem tests with SoDeRa RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX 01 70 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX 01 70 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX 01 70 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX @@ -231,7 +231,7 @@ Obj.# Case# Test# Description 01 70 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX -01 75 00 lte-softmodem + RRU (NGFI IF4P5, RAW) tests with B210 RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX +01 75 lte-softmodem + RRU (NGFI IF4P5, RAW) tests with B210 RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX 01 75 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX 01 75 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX 01 75 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX @@ -239,7 +239,7 @@ Obj.# Case# Test# Description 01 75 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX 01 75 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX -01 80 00 lte-softmodem + RRU (NGFI) tests with BladeRF RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX +01 80 lte-softmodem + RRU (NGFI) tests with BladeRF RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX 01 80 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX 01 80 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX 01 80 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX @@ -247,7 +247,7 @@ Obj.# Case# Test# Description 01 80 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX 01 80 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX -01 85 00 lte-softmodem + RRU (NGFI) tests with USRP X310 RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX +01 85 lte-softmodem + RRU (NGFI) tests with USRP X310 RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX 01 85 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX 01 85 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX 01 85 02 Band 7 FDD 20MHz UL Throughput for 300 sec for 1TX/1RX From 7f24927c43a0b450d4f474b68520716dba58e3ef Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 10 Mar 2017 12:42:04 +0100 Subject: [PATCH 373/571] WIP: SRS configuration of PUSCH and PUCCH. No SRS detection yet. To be tested on HW --- openair1/PHY/impl_defs_lte.h | 2 +- openair1/SCHED/defs.h | 4 + openair1/SCHED/phy_procedures_lte_common.c | 145 +++++++++++++++ openair1/SCHED/phy_procedures_lte_eNb.c | 40 ++-- openair1/SCHED/phy_procedures_lte_ue.c | 176 ++---------------- openair1/SIMULATION/LTE_PHY/ulsim.c | 2 + openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- .../CONF/enb.band7.tm1.usrpb210.conf | 10 +- 8 files changed, 206 insertions(+), 175 deletions(-) diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h index e9604a36f6..5707aedd27 100755 --- a/openair1/PHY/impl_defs_lte.h +++ b/openair1/PHY/impl_defs_lte.h @@ -320,7 +320,7 @@ typedef struct { uint16_t srs_ConfigIndex; /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value. uint8_t cyclicShift; - // Parameter: ue srs subframe for internal implementation + // Parameter: internal implementation: UE SRS configured uint8_t srsConfigDedicatedSetup; // Parameter: cell srs subframe for internal implementation uint8_t srsCellSubframe; diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index ac2d7957f2..f283014af7 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -514,6 +514,10 @@ void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid); +int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx); + +void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); + /*@}*/ diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index ae61f7be0d..e5753483da 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -942,3 +942,148 @@ MU_MIMO_mode *get_mu_mimo_mode (module_id_t Mod_id, uint8_t CC_id, rnti_t rnti) return &PHY_vars_eNB_g[Mod_id][CC_id]->mu_mimo_mode[UE_id]; } + +int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subframe_tx) +{ + uint8_t isSubframeSRS = 0; // SRS Cell Occasion + + //ue->ulsch[eNB_id]->srs_active = 0; + //ue->ulsch[eNB_id]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active; + if(frame_parms->soundingrs_ul_config_common.enabled_flag) + { + + LOG_D(PHY," SRS SUBFRAMECONFIG: %d\n", frame_parms->soundingrs_ul_config_common.srs_SubframeConfig); + + uint8_t TSFC; + uint16_t deltaTSFC; // bitmap + uint8_t srs_SubframeConfig; + + // table resuming TSFC (Period) and deltaSFC (offset) + const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD + const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD + + srs_SubframeConfig = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; + if (FDD == frame_parms->frame_type) + { + // srs_SubframeConfig =< 14 + deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; + } + else + { + // srs_SubframeConfig =< 13 + deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; + } + + // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC + uint16_t tmp = (subframe_tx % TSFC); + if((1<frame_type, TSFC, deltaTSFC, frame_tx, subframe_tx); + } + return(isSubframeSRS); +} + +void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset) +{ + if(TDD == frameType) + { + if(isrs<10) + { + mac_xface->macphy_exit("2 ms SRS periodicity not supported"); + } + + if((isrs>9)&&(isrs<15)) + { + *psrsPeriodicity=5; + *psrsOffset=isrs-10; + } + if((isrs>14)&&(isrs<25)) + { + *psrsPeriodicity=10; + *psrsOffset=isrs-15; + } + if((isrs>24)&&(isrs<45)) + { + *psrsPeriodicity=20; + *psrsOffset=isrs-25; + } + if((isrs>44)&&(isrs<85)) + { + *psrsPeriodicity=40; + *psrsOffset=isrs-45; + } + if((isrs>84)&&(isrs<165)) + { + *psrsPeriodicity=80; + *psrsOffset=isrs-85; + } + if((isrs>164)&&(isrs<325)) + { + *psrsPeriodicity=160; + *psrsOffset=isrs-165; + } + if((isrs>324)&&(isrs<645)) + { + *psrsPeriodicity=320; + *psrsOffset=isrs-325; + } + + if(isrs>644) + { + mac_xface->macphy_exit("Isrs out of range"); + } + + } + else + { + if(isrs<2) + { + *psrsPeriodicity=2; + *psrsOffset=isrs; + } + if((isrs>1)&&(isrs<7)) + { + *psrsPeriodicity=5; + *psrsOffset=isrs-2; + } + if((isrs>6)&&(isrs<17)) + { + *psrsPeriodicity=10; + *psrsOffset=isrs-7; + } + if((isrs>16)&&(isrs<37)) + { + *psrsPeriodicity=20; + *psrsOffset=isrs-17; + } + if((isrs>36)&&(isrs<77)) + { + *psrsPeriodicity=40; + *psrsOffset=isrs-37; + } + if((isrs>76)&&(isrs<157)) + { + *psrsPeriodicity=80; + *psrsOffset=isrs-77; + } + if((isrs>156)&&(isrs<317)) + { + *psrsPeriodicity=160; + *psrsOffset=isrs-157; + } + if((isrs>316)&&(isrs<637)) + { + *psrsPeriodicity=320; + *psrsOffset=isrs-317; + } + if(isrs>636) + { + mac_xface->macphy_exit("Isrs out of range"); + } + } +} diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index e9f1125a34..9257b0d48f 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -307,8 +307,6 @@ void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *eNB) } #endif - - void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,relaying_type_t r_type) { UNUSED(r_type); @@ -824,6 +822,9 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int frame = proc->frame_tx; int subframe = proc->subframe_tx; + uint16_t srsPeriodicity; + uint16_t srsOffset; + uint16_t do_srs=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"), aggregation %d\n", @@ -839,6 +840,12 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC dci_alloc->dci_pdu[0], 1<L); + if (is_srs_occasion_common(fp,frame,subframe)) { + compute_srs_pos(fp->frame_type, eNB->physicalConfigDedicated[UE_id]->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset); + if ((((10*frame+subframe) % srsPeriodicity) == srsOffset)) + do_srs = 1; + } + generate_eNB_ulsch_params_from_dci(eNB, proc, &dci_alloc->dci_pdu[0], @@ -849,7 +856,7 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC 0, P_RNTI, CBA_RNTI, - 0); // do_srs + do_srs); // do_srs LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n", eNB->Mod_id,frame,subframe,dci_alloc->rnti, @@ -1344,7 +1351,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, // Apply physicalConfigDedicated if needed // This is for UEs that have received this IE, which changes these DL and UL configuration, we apply after a delay for the eNodeB UL parameters phy_config_dedicated_eNB_step2(eNB); - + // Now loop again over the DCIs for UL configuration for (i=0; iNum_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) { dci_alloc = &DCI_pdu->dci_alloc[i]; @@ -2083,6 +2090,9 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq PUCCH_FMT_t format; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; + uint16_t srsPeriodicity; + uint16_t srsOffset; + uint16_t do_srs=0; if ((eNB->dlsch[UE_id][0]) && (eNB->dlsch[UE_id][0]->rnti>0) && @@ -2092,6 +2102,14 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq do_SR = is_SR_subframe(eNB,proc,UE_id); // do_SR = 0; + // check if there is SRS and we have to use shortened format + // TODO: check for exceptions in transmission of SRS together with ACK/NACK + if (is_srs_occasion_common(fp,frame,subframe)) { + compute_srs_pos(fp->frame_type, eNB->physicalConfigDedicated[UE_id]->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset); + if ((((10*frame+subframe) % srsPeriodicity) == srsOffset)) + do_srs = 1; + } + // Now ACK/NAK // First check subframe_tx flag for earlier subframes @@ -2150,7 +2168,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq UE_id, eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex, 0, // n2_pucch - 0, // shortened format, should be use_srs flag, later + do_srs, // shortened format &SR_payload, frame, subframe, @@ -2190,7 +2208,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq UE_id, (uint16_t)n1_pucch0, 0, //n2_pucch - 0, // shortened format + do_srs, // shortened format pucch_payload0, frame, subframe, @@ -2220,7 +2238,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq UE_id, eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex, 0, //n2_pucch - 0, // shortened format + do_srs, // shortened format pucch_payload0, frame, subframe, @@ -2281,7 +2299,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq UE_id, eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex, 0, //n2_pucch - 0, // shortened format + do_srs, // shortened format pucch_payload0, frame, subframe, @@ -2313,7 +2331,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq UE_id, (uint16_t)n1_pucch0, 0, // n2_pucch - 0, // shortened format + do_srs, // shortened format pucch_payload0, frame, subframe, @@ -2338,7 +2356,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq UE_id, (uint16_t)n1_pucch1, 0, //n2_pucch - 0, // shortened format + do_srs, // shortened format pucch_payload1, frame, subframe, @@ -2886,8 +2904,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->rb_mask_ul[2]=0; eNB->rb_mask_ul[3]=0; - - // Check for active processes in current subframe harq_pid = subframe2harq_pid(fp, frame,subframe); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index cd8fbdbc8e..381ea547e4 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -435,163 +435,26 @@ uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) return(0); } -void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset) + + +void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS) { - if(TDD == frameType) - { - if(isrs<10) - { - mac_xface->macphy_exit("2 ms SRS periodicity not supported"); - } - - if((isrs>9)&&(isrs<15)) - { - *psrsPeriodicity=5; - *psrsOffset=isrs-10; - } - if((isrs>14)&&(isrs<25)) - { - *psrsPeriodicity=10; - *psrsOffset=isrs-15; - } - if((isrs>24)&&(isrs<45)) - { - *psrsPeriodicity=20; - *psrsOffset=isrs-25; - } - if((isrs>44)&&(isrs<85)) - { - *psrsPeriodicity=40; - *psrsOffset=isrs-45; - } - if((isrs>84)&&(isrs<165)) - { - *psrsPeriodicity=80; - *psrsOffset=isrs-85; - } - if((isrs>164)&&(isrs<325)) - { - *psrsPeriodicity=160; - *psrsOffset=isrs-165; - } - if((isrs>324)&&(isrs<645)) - { - *psrsPeriodicity=320; - *psrsOffset=isrs-325; - } - - if(isrs>644) - { - mac_xface->macphy_exit("Isrs out of range"); - } - - } - else - { - if(isrs<2) - { - *psrsPeriodicity=2; - *psrsOffset=isrs; - } - if((isrs>1)&&(isrs<7)) - { - *psrsPeriodicity=5; - *psrsOffset=isrs-2; - } - if((isrs>6)&&(isrs<17)) - { - *psrsPeriodicity=10; - *psrsOffset=isrs-7; - } - if((isrs>16)&&(isrs<37)) - { - *psrsPeriodicity=20; - *psrsOffset=isrs-17; - } - if((isrs>36)&&(isrs<77)) - { - *psrsPeriodicity=40; - *psrsOffset=isrs-37; - } - if((isrs>76)&&(isrs<157)) - { - *psrsPeriodicity=80; - *psrsOffset=isrs-77; - } - if((isrs>156)&&(isrs<317)) - { - *psrsPeriodicity=160; - *psrsOffset=isrs-157; - } - if((isrs>316)&&(isrs<637)) - { - *psrsPeriodicity=320; - *psrsOffset=isrs-317; - } - if(isrs>636) - { - mac_xface->macphy_exit("Isrs out of range"); - } - } -} - -void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) -{ - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - int frame_tx = proc->frame_tx; - int subframe_tx = proc->subframe_tx; - uint8_t isSubframeSRS = 0; // SRS Cell Occasion - - uint8_t is_pucch2_subframe = 0; - uint8_t is_sr_an_subframe = 0; - - SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id]; + + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + int frame_tx = proc->frame_tx; + int subframe_tx = proc->subframe_tx; + SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id]; + uint16_t srsPeriodicity; + uint16_t srsOffset; + uint8_t is_pucch2_subframe = 0; + uint8_t is_sr_an_subframe = 0; // check for SRS opportunity pSoundingrs_ul_config_dedicated->srsUeSubframe = 0; - pSoundingrs_ul_config_dedicated->srsCellSubframe = 0; + pSoundingrs_ul_config_dedicated->srsCellSubframe = isSubframeSRS; - ue->ulsch[eNB_id]->srs_active = 0; - ue->ulsch[eNB_id]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active; - if(frame_parms->soundingrs_ul_config_common.enabled_flag) - { - - LOG_D(PHY," SRS SUBFRAMECONFIG: %d, Isrs: %d \n", frame_parms->soundingrs_ul_config_common.srs_SubframeConfig, pSoundingrs_ul_config_dedicated->srs_ConfigIndex); - - uint8_t TSFC; - uint16_t deltaTSFC; // bitmap - uint8_t srs_SubframeConfig; - uint16_t srsPeriodicity; - uint16_t srsOffset; - - // table resuming TSFC (Period) and deltaSFC (offset) - const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD - const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD - - srs_SubframeConfig = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; - if (FDD == frame_parms->frame_type) - { - // srs_SubframeConfig =< 14 - deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; - } - else - { - // srs_SubframeConfig =< 13 - deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; - } - - // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC - uint16_t tmp = (subframe_tx % TSFC); - if((1<srsCellSubframe = 1; - } - LOG_D(PHY," ISTDD: %d, TSFC: %d, deltaTSFC: %d, AbsSubframeTX: %d.%d, srsCellSubframe: %d \n", frame_parms->frame_type, TSFC, deltaTSFC, frame_tx, subframe_tx, pSoundingrs_ul_config_dedicated->srsCellSubframe); - LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup); + if (isSubframeSRS) { + LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup); if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup) { compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset); @@ -666,6 +529,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id } } + void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id) { @@ -2131,9 +1995,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; unsigned int aa; - - - + uint8_t isSubframeSRS; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); @@ -2161,7 +2023,9 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui if (ue->UE_mode[eNB_id] != PRACH) { // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding - ue_compute_srs_occasion(ue,proc,eNB_id); + isSubframeSRS = is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->subframe_tx); + + ue_compute_srs_occasion(ue,proc,eNB_id,isSubframeSRS); ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 55c6b8387e..543cc8023e 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -632,12 +632,14 @@ int main(int argc, char **argv) UE->pdcch_vars[0]->crnti = 14; + UE->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7; UE->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = 0; UE->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = 0; UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0; + eNB->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 6d0044b346..585d9c2c1c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -885,7 +885,7 @@ abort(); rb_table_index=UE_template->pre_allocated_rb_table_index_ul; } else { mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index=5; // for PHR + rb_table_index=13; // for PHR } UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index 5ef5a4f50b..19a77a04ec 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -62,11 +62,11 @@ eNBs = pusch_nDMRS1 = 1; phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; - srs_SubframeConfig =; - srs_ackNackST =; - srs_MaxUpPts =;*/ + srs_enable = "ENBABLE"; + srs_BandwidthConfig = 2; + srs_SubframeConfig = 3; + srs_ackNackST = "FALSE"; + srs_MaxUpPts = "DISABLE"; pusch_p0_Nominal = -90; pusch_alpha = "AL1"; From a587e35a9dbf177bb56e238a5389fe0caac81380 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Fri, 10 Mar 2017 15:37:26 +0100 Subject: [PATCH 374/571] removal and renaming of LimeSDR configuration files --- ....conf => enb.band13.tm1.25PRB.lmssdr.conf} | 2 +- .../CONF/enb.band7.tm1.25PRB.lmssdr.conf | 174 ++++++++++++++++ .../CONF/enb.band7.tm1.50PRB.rrh.lmssdr.conf | 192 ------------------ .../CONF/enb.band7.tm1.lmssdr.conf | 176 ---------------- .../CONF/enb.band7.tm1.rrh.lmssdr.conf | 192 ------------------ 5 files changed, 175 insertions(+), 561 deletions(-) rename targets/PROJECTS/GENERIC-LTE-EPC/CONF/{enb.band13.tm1.lmssdr.conf => enb.band13.tm1.25PRB.lmssdr.conf} (99%) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf delete mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.rrh.lmssdr.conf delete mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf delete mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.lmssdr.conf diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.25PRB.lmssdr.conf similarity index 99% rename from targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf rename to targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.25PRB.lmssdr.conf index 02ff6b3e0b..3315b953da 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.25PRB.lmssdr.conf @@ -31,7 +31,7 @@ eNBs = downlink_frequency = 751000000L; uplink_frequency_offset = 31000000; Nid_cell = 0; - N_RB_DL = 50; + N_RB_DL = 25; Nid_cell_mbsfn = 0; nb_antennas_tx = 1; nb_antennas_rx = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf new file mode 100644 index 0000000000..5aa544cd85 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf @@ -0,0 +1,174 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 20; + rx_gain = 116; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -30; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.70"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.150/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.150/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.rrh.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.rrh.lmssdr.conf deleted file mode 100644 index 4cd761645b..0000000000 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.rrh.lmssdr.conf +++ /dev/null @@ -1,192 +0,0 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); -# Asn1_verbosity, choice in: none, info, annoying -Asn1_verbosity = "none"; - -eNBs = -( - { - ////////// Identification parameters: - eNB_ID = 0xe00; - - cell_type = "CELL_MACRO_ENB"; - - eNB_name = "eNB_Eurecom_LTEBox"; - - // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "93"; - - ////////// Physical parameters: - - component_carriers = ( - { - frame_type = "FDD"; - tdd_config = 3; - tdd_config_s = 0; - prefix_type = "NORMAL"; - eutra_band = 7; - downlink_frequency = 2660000000L; - uplink_frequency_offset = -120000000; - Nid_cell = 0; - N_RB_DL = 50; - Nid_cell_mbsfn = 0; - nb_antennas_tx = 1; - nb_antennas_rx = 1; - tx_gain = 60; - rx_gain = 111; - prach_root = 0; - prach_config_index = 0; - prach_high_speed = "DISABLE"; - prach_zero_correlation = 1; - prach_freq_offset = 2; - pucch_delta_shift = 1; - pucch_nRB_CQI = 1; - pucch_nCS_AN = 0; - pucch_n1_AN = 32; - pdsch_referenceSignalPower = -29; - pdsch_p_b = 0; - pusch_n_SB = 1; - pusch_enable64QAM = "DISABLE"; - pusch_hoppingMode = "interSubFrame"; - pusch_hoppingOffset = 0; - pusch_groupHoppingEnabled = "ENABLE"; - pusch_groupAssignment = 0; - pusch_sequenceHoppingEnabled = "DISABLE"; - pusch_nDMRS1 = 1; - phich_duration = "NORMAL"; - phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; - srs_SubframeConfig =; - srs_ackNackST =; - srs_MaxUpPts =;*/ - - pusch_p0_Nominal = -85; - pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; - msg3_delta_Preamble = 6; - pucch_deltaF_Format1 = "deltaF2"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; - pucch_deltaF_Format2b = "deltaF0"; - - rach_numberOfRA_Preambles = 64; - rach_preamblesGroupAConfig = "DISABLE"; -/* - rach_sizeOfRA_PreamblesGroupA = ; - rach_messageSizeGroupA = ; - rach_messagePowerOffsetGroupB = ; -*/ - rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -100; - rach_preambleTransMax = 10; - rach_raResponseWindowSize = 10; - rach_macContentionResolutionTimer = 48; - rach_maxHARQ_Msg3Tx = 4; - - pcch_default_PagingCycle = 128; - pcch_nB = "oneT"; - bcch_modificationPeriodCoeff = 2; - ue_TimersAndConstants_t300 = 1000; - ue_TimersAndConstants_t301 = 1000; - ue_TimersAndConstants_t310 = 1000; - ue_TimersAndConstants_t311 = 10000; - ue_TimersAndConstants_n310 = 20; - ue_TimersAndConstants_n311 = 1; - - } - ); - - - srb1_parameters : - { - # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] - timer_poll_retransmit = 80; - - # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] - timer_reordering = 35; - - # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] - timer_status_prohibit = 0; - - # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] - poll_pdu = 4; - - # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] - poll_byte = 99999; - - # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] - max_retx_threshold = 4; - } - - # ------- SCTP definitions - SCTP : - { - # Number of streams to use in input/output - SCTP_INSTREAMS = 2; - SCTP_OUTSTREAMS = 2; - }; - - - ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.170"; - ipv6 = "192:168:30::17"; - active = "yes"; - preference = "ipv4"; - } - ); - -rrh_gw_config = ( - { - local_if_name = "eth0"; - #remote_address = "169.254.10.158"; - #local_address = "169.254.8.15"; - remote_address = "74:d4:35:cc:88:45"; - local_address = "d4:be:d9:22:0a:ac"; - local_port = 50000; #for raw option local port must be the same to remote - remote_port = 50000; - rrh_gw_active = "yes"; - tr_preference = "raw"; - rf_preference = "lmssdr"; - iq_txshift = 0; - tx_sample_advance = 45; - tx_scheduling_advance = 8; - -} -); - - NETWORK_INTERFACES : - { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.118/24"; - - ENB_INTERFACE_NAME_FOR_S1U = "eth6"; - - - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.118/24"; - ENB_PORT_FOR_S1U = 2152; # Spec 2152 - }; - - log_config : - { - global_log_level ="info"; - global_log_verbosity ="medium"; - hw_log_level ="info"; - hw_log_verbosity ="medium"; - phy_log_level ="info"; - phy_log_verbosity ="medium"; - mac_log_level ="info"; - mac_log_verbosity ="high"; - rlc_log_level ="info"; - rlc_log_verbosity ="medium"; - pdcp_log_level ="info"; - pdcp_log_verbosity ="medium"; - rrc_log_level ="info"; - rrc_log_verbosity ="medium"; - }; - } -); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf deleted file mode 100644 index d912b1a102..0000000000 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.lmssdr.conf +++ /dev/null @@ -1,176 +0,0 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); -# Asn1_verbosity, choice in: none, info, annoying -Asn1_verbosity = "none"; - -eNBs = -( - { - ////////// Identification parameters: - eNB_ID = 0xe00; - - cell_type = "CELL_MACRO_ENB"; - - eNB_name = "eNB_Eurecom_LTEBox"; - - // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - - ////////// Physical parameters: - - component_carriers = ( - { - node_function = "eNodeB_3GPP"; - node_timing = "synch_to_ext_device"; - node_synch_ref = 0; - frame_type = "FDD"; - tdd_config = 3; - tdd_config_s = 0; - prefix_type = "NORMAL"; - eutra_band = 7; - downlink_frequency = 2660000000L; - uplink_frequency_offset = -120000000; - Nid_cell = 0; - N_RB_DL = 25; - Nid_cell_mbsfn = 0; - nb_antennas_ports = 1; - nb_antennas_tx = 1; - nb_antennas_rx = 1; - tx_gain = 100; - rx_gain = 111; - prach_root = 0; - prach_config_index = 0; - prach_high_speed = "DISABLE"; - prach_zero_correlation = 1; - prach_freq_offset = 2; - pucch_delta_shift = 1; - pucch_nRB_CQI = 1; - pucch_nCS_AN = 0; - pucch_n1_AN = 32; - pdsch_referenceSignalPower = -29; - pdsch_p_b = 0; - pusch_n_SB = 1; - pusch_enable64QAM = "DISABLE"; - pusch_hoppingMode = "interSubFrame"; - pusch_hoppingOffset = 0; - pusch_groupHoppingEnabled = "ENABLE"; - pusch_groupAssignment = 0; - pusch_sequenceHoppingEnabled = "DISABLE"; - pusch_nDMRS1 = 1; - phich_duration = "NORMAL"; - phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; - srs_SubframeConfig =; - srs_ackNackST =; - srs_MaxUpPts =;*/ - - pusch_p0_Nominal = -85; - pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; - msg3_delta_Preamble = 6; - pucch_deltaF_Format1 = "deltaF2"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; - pucch_deltaF_Format2b = "deltaF0"; - - rach_numberOfRA_Preambles = 64; - rach_preamblesGroupAConfig = "DISABLE"; -/* - rach_sizeOfRA_PreamblesGroupA = ; - rach_messageSizeGroupA = ; - rach_messagePowerOffsetGroupB = ; -*/ - rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -100; - rach_preambleTransMax = 10; - rach_raResponseWindowSize = 10; - rach_macContentionResolutionTimer = 48; - rach_maxHARQ_Msg3Tx = 4; - - pcch_default_PagingCycle = 128; - pcch_nB = "oneT"; - bcch_modificationPeriodCoeff = 2; - ue_TimersAndConstants_t300 = 1000; - ue_TimersAndConstants_t301 = 1000; - ue_TimersAndConstants_t310 = 1000; - ue_TimersAndConstants_t311 = 10000; - ue_TimersAndConstants_n310 = 20; - ue_TimersAndConstants_n311 = 1; - - ue_TransmissionMode = 1; - } - ); - - - srb1_parameters : - { - # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] - timer_poll_retransmit = 80; - - # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] - timer_reordering = 35; - - # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] - timer_status_prohibit = 0; - - # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] - poll_pdu = 4; - - # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] - poll_byte = 99999; - - # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] - max_retx_threshold = 4; - } - - # ------- SCTP definitions - SCTP : - { - # Number of streams to use in input/output - SCTP_INSTREAMS = 2; - SCTP_OUTSTREAMS = 2; - }; - - ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.170"; - ipv6 = "192:168:30::17"; - active = "yes"; - preference = "ipv4"; - } - ); - - NETWORK_INTERFACES : - { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth4"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.242/24"; - - ENB_INTERFACE_NAME_FOR_S1U = "eth4"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.242/24"; - ENB_PORT_FOR_S1U = 2152; # Spec 2152 - }; - - log_config : - { - global_log_level ="info"; - global_log_verbosity ="medium"; - hw_log_level ="info"; - hw_log_verbosity ="medium"; - phy_log_level ="info"; - phy_log_verbosity ="medium"; - mac_log_level ="info"; - mac_log_verbosity ="high"; - rlc_log_level ="info"; - rlc_log_verbosity ="medium"; - pdcp_log_level ="info"; - pdcp_log_verbosity ="medium"; - rrc_log_level ="info"; - rrc_log_verbosity ="medium"; - }; - - } -); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.lmssdr.conf deleted file mode 100644 index 9b052bf7ba..0000000000 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.rrh.lmssdr.conf +++ /dev/null @@ -1,192 +0,0 @@ -Active_eNBs = ( "eNB_Eurecom_LTEBox"); -# Asn1_verbosity, choice in: none, info, annoying -Asn1_verbosity = "none"; - -eNBs = -( - { - ////////// Identification parameters: - eNB_ID = 0xe00; - - cell_type = "CELL_MACRO_ENB"; - - eNB_name = "eNB_Eurecom_LTEBox"; - - // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; - - mobile_country_code = "208"; - - mobile_network_code = "92"; - - ////////// Physical parameters: - - component_carriers = ( - { - frame_type = "FDD"; - tdd_config = 3; - tdd_config_s = 0; - prefix_type = "NORMAL"; - eutra_band = 7; - downlink_frequency = 2660000000L; - uplink_frequency_offset = -120000000; - Nid_cell = 0; - N_RB_DL = 25; - Nid_cell_mbsfn = 0; - nb_antennas_tx = 1; - nb_antennas_rx = 1; - tx_gain = 60; - rx_gain = 111; - prach_root = 0; - prach_config_index = 0; - prach_high_speed = "DISABLE"; - prach_zero_correlation = 1; - prach_freq_offset = 2; - pucch_delta_shift = 1; - pucch_nRB_CQI = 1; - pucch_nCS_AN = 0; - pucch_n1_AN = 32; - pdsch_referenceSignalPower = -29; - pdsch_p_b = 0; - pusch_n_SB = 1; - pusch_enable64QAM = "DISABLE"; - pusch_hoppingMode = "interSubFrame"; - pusch_hoppingOffset = 0; - pusch_groupHoppingEnabled = "ENABLE"; - pusch_groupAssignment = 0; - pusch_sequenceHoppingEnabled = "DISABLE"; - pusch_nDMRS1 = 1; - phich_duration = "NORMAL"; - phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; - srs_SubframeConfig =; - srs_ackNackST =; - srs_MaxUpPts =;*/ - - pusch_p0_Nominal = -85; - pusch_alpha = "AL1"; - pucch_p0_Nominal = -96; - msg3_delta_Preamble = 6; - pucch_deltaF_Format1 = "deltaF2"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; - pucch_deltaF_Format2b = "deltaF0"; - - rach_numberOfRA_Preambles = 64; - rach_preamblesGroupAConfig = "DISABLE"; -/* - rach_sizeOfRA_PreamblesGroupA = ; - rach_messageSizeGroupA = ; - rach_messagePowerOffsetGroupB = ; -*/ - rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -100; - rach_preambleTransMax = 10; - rach_raResponseWindowSize = 10; - rach_macContentionResolutionTimer = 48; - rach_maxHARQ_Msg3Tx = 4; - - pcch_default_PagingCycle = 128; - pcch_nB = "oneT"; - bcch_modificationPeriodCoeff = 2; - ue_TimersAndConstants_t300 = 1000; - ue_TimersAndConstants_t301 = 1000; - ue_TimersAndConstants_t310 = 1000; - ue_TimersAndConstants_t311 = 10000; - ue_TimersAndConstants_n310 = 20; - ue_TimersAndConstants_n311 = 1; - - } - ); - - - srb1_parameters : - { - # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] - timer_poll_retransmit = 80; - - # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] - timer_reordering = 35; - - # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] - timer_status_prohibit = 0; - - # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] - poll_pdu = 4; - - # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] - poll_byte = 99999; - - # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] - max_retx_threshold = 4; - } - - # ------- SCTP definitions - SCTP : - { - # Number of streams to use in input/output - SCTP_INSTREAMS = 2; - SCTP_OUTSTREAMS = 2; - }; - - - ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.170"; - ipv6 = "192:168:30::17"; - active = "yes"; - preference = "ipv4"; - } - ); - -rrh_gw_config = ( - { - local_if_name = "eth0"; - #remote_address = "169.254.10.158"; - #local_address = "169.254.8.15"; - remote_address = "74:d4:35:cc:88:45"; - local_address = "d4:be:d9:22:0a:ac"; - local_port = 50000; #for raw option local port must be the same to remote - remote_port = 50000; - rrh_gw_active = "yes"; - tr_preference = "raw"; - rf_preference = "lmssdr"; - iq_txshift = 0; - tx_sample_advance = 70; - tx_scheduling_advance = 8; - -} -); - - NETWORK_INTERFACES : - { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.118/24"; - - ENB_INTERFACE_NAME_FOR_S1U = "eth6"; - - - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.118/24"; - ENB_PORT_FOR_S1U = 2152; # Spec 2152 - }; - - log_config : - { - global_log_level ="info"; - global_log_verbosity ="medium"; - hw_log_level ="info"; - hw_log_verbosity ="medium"; - phy_log_level ="info"; - phy_log_verbosity ="medium"; - mac_log_level ="info"; - mac_log_verbosity ="high"; - rlc_log_level ="info"; - rlc_log_verbosity ="medium"; - pdcp_log_level ="info"; - pdcp_log_verbosity ="medium"; - rrc_log_level ="info"; - rrc_log_verbosity ="medium"; - }; - } -); From 02f3298a583cf4e38bc242bb72e303f0ecc13715 Mon Sep 17 00:00:00 2001 From: Rohit Gupta Date: Fri, 10 Mar 2017 14:10:00 +0100 Subject: [PATCH 375/571] several fixes to previous commit. First tests in FDD with USRP and UE ok. --- openair1/PHY/INIT/lte_init.c | 3 +- openair1/SCHED/phy_procedures_lte_eNb.c | 28 +++++++++++++------ openair2/RRC/LITE/MESSAGES/asn1_msg.c | 2 +- .../CONF/enb.band7.tm1.usrpb210.conf | 16 +++++------ 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index d0556a0235..9d8818a444 100755 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -483,7 +483,8 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB) if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { - + + eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup = 1; eNB->soundingrs_ul_config_dedicated[UE_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 9257b0d48f..5b12008a99 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -822,9 +822,11 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int frame = proc->frame_tx; int subframe = proc->subframe_tx; - uint16_t srsPeriodicity; - uint16_t srsOffset; + uint16_t srsPeriodicity=0; + uint16_t srsOffset=0; + uint16_t srsConfigIndex=0; uint16_t do_srs=0; + uint16_t is_srs_pos=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"), aggregation %d\n", @@ -840,12 +842,19 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC dci_alloc->dci_pdu[0], 1<L); - if (is_srs_occasion_common(fp,frame,subframe)) { - compute_srs_pos(fp->frame_type, eNB->physicalConfigDedicated[UE_id]->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset); - if ((((10*frame+subframe) % srsPeriodicity) == srsOffset)) + is_srs_pos = is_srs_occasion_common(fp,pdcch_alloc2ul_frame(fp,frame,subframe),pdcch_alloc2ul_subframe(fp,subframe)); + if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup) { + srsConfigIndex = eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex; + compute_srs_pos(fp->frame_type, srsConfigIndex, &srsPeriodicity, &srsOffset); + if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) { do_srs = 1; + } } + LOG_D(PHY,"frame %d (%d), subframe %d (%d), UE_id %d: is_srs_pos %d, do_SRS %d, index %d, period %d, offset %d \n", + frame,pdcch_alloc2ul_frame(fp,frame,subframe),subframe,pdcch_alloc2ul_subframe(fp,subframe), + UE_id,is_srs_pos,do_srs,srsConfigIndex,srsPeriodicity,srsOffset); + generate_eNB_ulsch_params_from_dci(eNB, proc, &dci_alloc->dci_pdu[0], @@ -2093,6 +2102,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq uint16_t srsPeriodicity; uint16_t srsOffset; uint16_t do_srs=0; + uint16_t is_srs_pos=0; if ((eNB->dlsch[UE_id][0]) && (eNB->dlsch[UE_id][0]->rnti>0) && @@ -2104,10 +2114,12 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq // check if there is SRS and we have to use shortened format // TODO: check for exceptions in transmission of SRS together with ACK/NACK - if (is_srs_occasion_common(fp,frame,subframe)) { - compute_srs_pos(fp->frame_type, eNB->physicalConfigDedicated[UE_id]->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset); - if ((((10*frame+subframe) % srsPeriodicity) == srsOffset)) + is_srs_pos = is_srs_occasion_common(fp,pdcch_alloc2ul_frame(fp,frame,subframe),pdcch_alloc2ul_subframe(fp,subframe)); + if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup ) { + compute_srs_pos(fp->frame_type, eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex, &srsPeriodicity, &srsOffset); + if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) { do_srs = 1; + } } // Now ACK/NAK diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 4537303fca..67f93a960e 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -1593,7 +1593,7 @@ do_RRCConnectionSetup( SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=45; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=19; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift= SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index 19a77a04ec..debed67f72 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -17,7 +17,7 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "94"; + mobile_network_code = "92"; ////////// Physical parameters: @@ -62,10 +62,10 @@ eNBs = pusch_nDMRS1 = 1; phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; - srs_enable = "ENBABLE"; + srs_enable = "ENABLE"; srs_BandwidthConfig = 2; srs_SubframeConfig = 3; - srs_ackNackST = "FALSE"; + srs_ackNackST = "DISABLE"; srs_MaxUpPts = "DISABLE"; pusch_p0_Nominal = -90; @@ -137,7 +137,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.70"; + mme_ip_address = ( { ipv4 = "192.168.12.26"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -147,10 +147,10 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.147/24"; - ENB_INTERFACE_NAME_FOR_S1U = "eth1"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.147/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 }; From e14f3677e5cd54617a681b5ea14467280df58892 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 16 Feb 2017 17:33:43 +0100 Subject: [PATCH 376/571] sending full rx signal to T in TDD mode --- openair1/SCHED/phy_procedures_lte_eNb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 5b12008a99..2947ce2ce7 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2896,6 +2896,11 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const const int frame = proc->frame_rx; int offset = eNB->CC_id;//(proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1; + T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); + + T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), + T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti], + eNB->frame_parms.samples_per_tti * 4)); if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; @@ -2905,11 +2910,6 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe); #endif - T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); - - T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), - T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti], - eNB->frame_parms.samples_per_tti * 4)); eNB->rb_mask_ul[0]=0; eNB->rb_mask_ul[1]=0; From c135dd611bb88592da791fa24e850020f6639988 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 16 Feb 2017 17:34:20 +0100 Subject: [PATCH 377/571] scheduling also UL SF 4 in TDD mode 3 --- openair2/LAYER2/MAC/eNB_scheduler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index dee7c51a6e..cab865754e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -383,10 +383,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, if (mac_xface->frame_parms->frame_type == FDD) { //FDD schedule_ulsch(module_idP,frameP,cooperation_flag,0,4);//,calibration_flag); - } else if ((mac_xface->frame_parms->tdd_config == TDD) || //TDD + } else if ((mac_xface->frame_parms->tdd_config == 0) || //TDD (mac_xface->frame_parms->tdd_config == 3) || (mac_xface->frame_parms->tdd_config == 6)) { - //schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag); + schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag); } #ifndef FLEXRAN_AGENT_SB_IF schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); From 39c7e629fbd6fb40a91155bcc19108166c4f6d83 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Mon, 20 Feb 2017 13:48:54 +0100 Subject: [PATCH 378/571] bugfix: bundling flag was initialized after its use --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 9f4749cdc6..9876b4b169 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -7943,6 +7943,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL); + ulsch->bundling = 1-AckNackFBMode; if (frame_parms->frame_type == FDD) { int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); @@ -7974,7 +7975,6 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, ulsch->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); ulsch->srs_active = use_srs; - ulsch->bundling = 1-AckNackFBMode; if ((rnti >= cba_rnti) && (rnti < p_rnti)) ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; @@ -8577,6 +8577,8 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; } + ulsch->bundling = 1-AckNackFBMode; + if (frame_parms->frame_type == FDD) { int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); @@ -8600,7 +8602,6 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); ulsch->harq_processes[harq_pid]->srs_active = use_srs; - ulsch->bundling = 1-AckNackFBMode; //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) if(cshift == 0) From 8e8fec1e1996ad800950292255f8829ceb2e846a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 10 Mar 2017 20:18:36 +0100 Subject: [PATCH 379/571] test setup v2: add TDD tests New tests: 0186xx for TDD with the huawei 3276 dongle. All necessary files to configure and use it have been added. Existing code has been adapted for the TDD tests. Only the test setup v2 has been adapted. The file test_case_list.xml has been changed to add tests 0186xx, but only to work with test setup v2. It won't work with test setup v1. To be completed if needed. The tests are similar to FDD tests. Throughputs for TDD have to be adjusted, the throughputs of FDD are used for the moment. --- cmake_targets/autotests/README.txt | 26 +++ cmake_targets/autotests/test_case_list.xml | 24 +++ .../autotests/v2/actions/start_3276.bash | 11 ++ .../autotests/v2/actions/start_3276.py | 59 ++++++ .../autotests/v2/actions/stop_3276.py | 29 +++ .../autotests/v2/actions/wvdial.3276.conf | 27 +++ cmake_targets/autotests/v2/alu_test.py | 165 ++++++++++------- .../enb.band38.tm1.usrpb210.tdd.10MHz.conf | 175 ++++++++++++++++++ .../enb.band38.tm1.usrpb210.tdd.20MHz.conf | 175 ++++++++++++++++++ .../enb.band38.tm1.usrpb210.tdd.5MHz.conf | 175 ++++++++++++++++++ ... => enb.band7.tm1.usrpb210.fdd.10MHz.conf} | 0 ... => enb.band7.tm1.usrpb210.fdd.20MHz.conf} | 0 ...f => enb.band7.tm1.usrpb210.fdd.5MHz.conf} | 0 cmake_targets/autotests/v2/main.py | 105 +++++++---- 14 files changed, 867 insertions(+), 104 deletions(-) create mode 100644 cmake_targets/autotests/v2/actions/start_3276.bash create mode 100644 cmake_targets/autotests/v2/actions/start_3276.py create mode 100644 cmake_targets/autotests/v2/actions/stop_3276.py create mode 100644 cmake_targets/autotests/v2/actions/wvdial.3276.conf create mode 100644 cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf create mode 100644 cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf create mode 100644 cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf rename cmake_targets/autotests/v2/config/{enb.band7.tm1.usrpb210.10MHz.conf => enb.band7.tm1.usrpb210.fdd.10MHz.conf} (100%) rename cmake_targets/autotests/v2/config/{enb.band7.tm1.usrpb210.20MHz.conf => enb.band7.tm1.usrpb210.fdd.20MHz.conf} (100%) rename cmake_targets/autotests/v2/config/{enb.band7.tm1.usrpb210.5MHz.conf => enb.band7.tm1.usrpb210.fdd.5MHz.conf} (100%) diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index ca53680f36..6cd0307b48 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -255,6 +255,32 @@ Obj.# Case# Test# Description 01 85 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX 01 85 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX +01 86 lte-softmodem tests with USRP B210 RF as eNB and ALU EPC w/ Huawei e3276 COTS UE for 1TX/1RX (TM1), 2TX/2RX (TM2) +01 86 00 Band 38 TDD 5MHz UL Throughput (UDP) for 300 sec for 1TX/1RX +01 86 01 Band 38 TDD 10MHz UL Throughput (UDP) for 300 sec for 1TX/1RX +01 86 02 Band 38 TDD 20MHz UL Throughput (UDP) for 300 sec for 1TX/1RX +01 86 03 Band 38 TDD 5MHz DL Throughput (UDP) for 300 sec for 1TX/1RX +01 86 04 Band 38 TDD 10MHz DL Throughput (UDP) for 300 sec for 1TX/1RX +01 86 05 Band 38 TDD 20MHz DL Throughput (UDP) for 300 sec for 1TX/1RX +01 86 06 Band 38 TDD 5MHz UL Throughput (UDP) for 300 sec for 2TX/2RX (TM2) +01 86 07 Band 38 TDD 10MHz UL Throughput (UDP) for 300 sec for 2TX/2RX (TM2) +01 86 08 Band 38 TDD 20MHz UL Throughput (UDP) for 300 sec for 2TX/2RX (TM2) +01 86 09 Band 38 TDD 5MHz DL Throughput (UDP) for 300 sec for 2TX/2RX (TM2) +01 86 10 Band 38 TDD 10MHz DL Throughput (UDP) for 300 sec for 2TX/2RX (TM2) +01 86 11 Band 38 TDD 20MHz DL Throughput (UDP) for 300 sec for 2TX/2RX (TM2) +01 86 12 Band 38 TDD 5MHz UL Throughput (TCP) for 300 sec for 1TX/1RX +01 86 13 Band 38 TDD 10MHz UL Throughput (TCP) for 300 sec for 1TX/1RX +01 86 14 Band 38 TDD 20MHz UL Throughput (TCP) for 300 sec for 1TX/1RX +01 86 15 Band 38 TDD 5MHz DL Throughput (TCP) for 300 sec for 1TX/1RX +01 86 16 Band 38 TDD 10MHz DL Throughput (TCP) for 300 sec for 1TX/1RX +01 86 17 Band 38 TDD 20MHz DL Throughput (TCP) for 300 sec for 1TX/1RX +01 86 18 Band 38 TDD 5MHz UL Throughput (TCP) for 300 sec for 2TX/2RX (TM2) +01 86 19 Band 38 TDD 10MHz UL Throughput (TCP) for 300 sec for 2TX/2RX (TM2) +01 86 20 Band 38 TDD 20MHz UL Throughput (TCP) for 300 sec for 2TX/2RX (TM2) +01 86 21 Band 38 TDD 5MHz DL Throughput (TCP) for 300 sec for 2TX/2RX (TM2) +01 86 22 Band 38 TDD 10MHz DL Throughput (TCP) for 300 sec for 2TX/2RX (TM2) +01 86 23 Band 38 TDD 20MHz DL Throughput (TCP) for 300 sec for 2TX/2RX (TM2) + 02 55 lte-softmodem tests with USRP B210 RF as eNB and ALU EPC w/ Sony Experia M4 COTS UE for 1TX/1RX and 2TX/2RX (TM2) 02 55 00 Band 7 FDD 5MHz UL Throughput (UDP) for 300 sec for 1TX/1RX 02 55 01 Band 7 FDD 10MHz UL Throughput (UDP) for 300 sec for 1TX/1RX diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index f37c265462..c55a29c975 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -8664,6 +8664,30 @@ c 10 + + + + + + + + + + + + + + + + + + + + + + + + lte-softmodem diff --git a/cmake_targets/autotests/v2/actions/start_3276.bash b/cmake_targets/autotests/v2/actions/start_3276.bash new file mode 100644 index 0000000000..c6fbdcedd9 --- /dev/null +++ b/cmake_targets/autotests/v2/actions/start_3276.bash @@ -0,0 +1,11 @@ +#enable control+C reception (to be refined if it does not work) +stty isig intr ^C + +cd /tmp/oai_test_setup/oai +source oaienv +cd cmake_targets/autotests/v2/actions +sudo python start_3276.py + +sudo wvdial -C wvdial.3276.conf || true + +sudo python stop_3276.py diff --git a/cmake_targets/autotests/v2/actions/start_3276.py b/cmake_targets/autotests/v2/actions/start_3276.py new file mode 100644 index 0000000000..cf0629213a --- /dev/null +++ b/cmake_targets/autotests/v2/actions/start_3276.py @@ -0,0 +1,59 @@ +import time + +from modem import quit, Modem + +try: + modem = Modem("/dev/ttyUSB0") + + #test that modem is there + print "INFO: check modem's presence" + modem.send('AT') + if modem.wait().ret != True: + print "ERROR: no modem?" + quit(1) + + #first deactivate + print "INFO: deactivate the modem" + modem.send('AT+CFUN=0') + if modem.wait().ret != True: + print "ERROR: failed deactivating the modem" + quit(1) + + #activate the modem + print "INFO: activate the modem" + modem.send('AT+CFUN=1') + if modem.wait().ret != True: + print "ERROR: failed asking modem for activation" + quit(1) + + #wait for modem to be connected + #timeout after one minute + print "INFO: wait for modem to be connected (timeout: one minute)" + start_time = time.time() + while True: + modem.send('AT+CGATT?') + r = modem.wait() + if r.ret != True: + print "ERROR: failed checking attachment status of modem" + quit(1) + if "+CGATT: 1" in r.data: + break + if not "CGATT: 0" in r.data: + print "ERROR: bad data when checking attachment status of modem" + quit(1) + time.sleep(0.1) + if time.time() > start_time + 60: + print "ERROR: modem not connected after one minute, close modem" + modem.send('AT+CFUN=0') + r = modem.wait() + if r.ret != True: + print "ERROR: closing modem failed" + quit(1) + + print "INFO: modem is connected" + +except BaseException, e: + print "ERROR: " + str(e) + quit(1) + +quit(0) diff --git a/cmake_targets/autotests/v2/actions/stop_3276.py b/cmake_targets/autotests/v2/actions/stop_3276.py new file mode 100644 index 0000000000..3eb7e889c6 --- /dev/null +++ b/cmake_targets/autotests/v2/actions/stop_3276.py @@ -0,0 +1,29 @@ +import time + +from modem import quit, Modem + +try: + modem = Modem("/dev/ttyUSB0") + + #test that modem is there + print "INFO: check modem's presence" + modem.send('AT') + r = modem.wait() + if r.ret != True and "NO CARRIER" not in r.data: + print "ERROR: no modem?" + quit(1) + if "NO CARRIER" in r.data: + print "WARNING: 'NO CARRIER' detected, not sure if handled correctly" + + #deactivate the modem + print "INFO: deactivate the modem" + modem.send('AT+CFUN=0') + if modem.wait().ret != True: + print "ERROR: failed asking modem for deactivation" + quit(1) + +except BaseException, e: + print "ERROR: " + str(e) + quit(1) + +quit(0) diff --git a/cmake_targets/autotests/v2/actions/wvdial.3276.conf b/cmake_targets/autotests/v2/actions/wvdial.3276.conf new file mode 100644 index 0000000000..81fedc8df2 --- /dev/null +++ b/cmake_targets/autotests/v2/actions/wvdial.3276.conf @@ -0,0 +1,27 @@ +[Dialer Defaults] +Modem = /dev/ttyUSB0 +ISDN = off +Modem Type = Analog Modem +Baud = 9600 +Init1 = ATZ +Init2 = AT&F &D2 &C1 +Init3 = AT+CGDCONT=1,"IP","oai.ipv4" +Phone = *99# +Phone1 = +Phone2 = +Phone3 = +Phone4 = +Ask Password = off +Password = '' +Username = ImaginLab +Auto Reconnect = off +Abort on Busy = off +Carrier Check = on +Check Def Route = on +Abort on No Dialtone = on +Stupid Mode = on +Idle Seconds = 0 +Auto DNS = on +;Minimize = off +;Dock = off +;Do NOT edit this file by hand! diff --git a/cmake_targets/autotests/v2/alu_test.py b/cmake_targets/autotests/v2/alu_test.py index 7992ce7f3c..8ba6ab857a 100644 --- a/cmake_targets/autotests/v2/alu_test.py +++ b/cmake_targets/autotests/v2/alu_test.py @@ -102,7 +102,7 @@ class alu_test: # compile_enb ########################################################################## def compile_enb(self, build_arguments): - log("INFO: ALU test: compile softmodem") + log("INFO: ALU test: compile softmodem on " + self.enb_machine) envcomp = list(self.env) envcomp.append('BUILD_ARGUMENTS="' + build_arguments + '"') #we don't care about BUILD_OUTPUT but required (TODO: change that) @@ -163,24 +163,24 @@ class alu_test: #os._exit(1) ########################################################################## - # start_bandrich_ue + # start_ue ########################################################################## - def start_bandrich_ue(self): - log("INFO: ALU test: start bandrich UE") - self.task_ue = Task("actions/start_bandrich.bash", - "start_bandrich", + def start_ue(self, ue): + log("INFO: ALU test: start " + ue + " UE") + self.task_ue = Task("actions/start_" + ue + ".bash", + "start_" + ue, self.ue_machine, self.oai_user, self.oai_password, self.env, - self.logdir + "/start_bandrich." + self.ue_machine, + self.logdir + "/start_" + ue + "." + self.ue_machine, event=self.event) self.task_ue.waitlog("local IP address", event=self.event) self.event.wait() #at this point one task has died or we have the line in the log if self.task_ue.waitlog_state != WAITLOG_SUCCESS: - log("ERROR: ALU test: bandrich UE did not connect") + log("ERROR: ALU test: " + ue + " UE did not connect") raise TestFailed() self.event.clear() @@ -191,21 +191,21 @@ class alu_test: log("ERROR: ALU test: eNB, HSS or UE task died") raise TestFailed() - #get bandrich UE IP + #get UE IP l = open(self.task_ue.logfile, "r").read() - self.bandrich_ue_ip = re.search("local IP address (.*)\n", l) \ - .groups()[0] - log("INFO: ALU test: bandrich UE IP address: " + self.bandrich_ue_ip) + self.ue_ip = re.search("local IP address (.*)\n", l) \ + .groups()[0] + log("INFO: ALU test: " + ue + " UE IP address: " + self.ue_ip) ########################################################################## - # stop_bandrich_ue + # stop_ue ########################################################################## - def stop_bandrich_ue(self): - log("INFO: ALU test: stop bandrich UE") + def stop_ue(self, ue): + log("INFO: ALU test: stop " + ue + " UE") self.task_ue.sendnow("%c" % 3) ret = self.task_ue.wait() if ret != 0: - log("ERROR: ALU test: task bandrich UE failed") + log("ERROR: ALU test: task " + ue + " UE failed") #not sure if we have to quit here or not #os._exit(1) @@ -286,47 +286,47 @@ class alu_test: ########################################################################## # dl_tcp ########################################################################## - def dl_tcp(self): - self._do_traffic("bandrich downlink TCP", - "server_tcp", self.ue_machine, self.bandrich_ue_ip, + def dl_tcp(self, ue): + self._do_traffic(ue + " downlink TCP", + "server_tcp", self.ue_machine, self.ue_ip, "client_tcp", self.epc_machine, "Server listening on TCP port 5001", - "bandrich_downlink_tcp_server", - "bandrich_downlink_tcp_client") + ue + "_downlink_tcp_server", + ue + "_downlink_tcp_client") ########################################################################## # ul_tcp ########################################################################## - def ul_tcp(self): - self._do_traffic("bandrich uplink TCP", + def ul_tcp(self, ue): + self._do_traffic(ue + " uplink TCP", "server_tcp", self.epc_machine, "192.172.0.1", "client_tcp", self.ue_machine, "Server listening on TCP port 5001", - "bandrich_uplink_tcp_server", - "bandrich_uplink_tcp_client") + ue + "_uplink_tcp_server", + ue + "_uplink_tcp_client") ########################################################################## # dl_udp ########################################################################## - def dl_udp(self, bandwidth): - self._do_traffic("bandrich downlink UDP", - "server_udp", self.ue_machine, self.bandrich_ue_ip, + def dl_udp(self, ue, bandwidth): + self._do_traffic(ue + " downlink UDP", + "server_udp", self.ue_machine, self.ue_ip, "client_udp", self.epc_machine, "Server listening on UDP port 5001", - "bandrich_downlink_udp_server", - "bandrich_downlink_udp_client", + ue + "_downlink_udp_server", + ue + "_downlink_udp_client", udp_bandwidth=bandwidth) ########################################################################## # ul_udp ########################################################################## - def ul_udp(self, bandwidth): - self._do_traffic("bandrich uplink UDP", + def ul_udp(self, ue, bandwidth): + self._do_traffic(ue + " uplink UDP", "server_udp", self.epc_machine, "192.172.0.1", "client_udp", self.ue_machine, "Server listening on UDP port 5001", - "bandrich_uplink_udp_server", - "bandrich_uplink_udp_client", + ue + "_uplink_udp_server", + ue + "_uplink_udp_client", udp_bandwidth=bandwidth) ############################################################################## @@ -337,19 +337,33 @@ def run_b210_alu(tests, openair_dir, oai_user, oai_password, env): if not do_tests(tests['b210']['alu']): return - #compile eNB + #compile eNB (two cases: one for FDD and one for TDD) - alu = alu_test(epc='amerique', enb='hutch', ue='stevens', - openair=openair_dir, - user=oai_user, password=oai_password, - log_subdir='enb_tests/b210_alu/compile_enb', - env=env) + if do_tests(tests['b210']['alu']['fdd']): + alu = alu_test(epc='amerique', enb='hutch', ue='stevens', + openair=openair_dir, + user=oai_user, password=oai_password, + log_subdir='enb_tests/b210_alu/compile_enb_fdd', + env=env) - try: - alu.compile_enb("--eNB -w USRP -x -c --disable-cpu-affinity") - except BaseException, e: - log("ERROR: ALU test failed: eNB compilation failed: " + str(e)) - return + try: + alu.compile_enb("--eNB -w USRP -x -c --disable-cpu-affinity") + except BaseException, e: + log("ERROR: ALU test failed: eNB compilation failed: " + str(e)) + return + + if do_tests(tests['b210']['alu']['tdd']): + alu = alu_test(epc='amerique', enb='calisson', ue='mozart', + openair=openair_dir, + user=oai_user, password=oai_password, + log_subdir='enb_tests/b210_alu/compile_enb_tdd', + env=env) + + try: + alu.compile_enb("--eNB -w USRP -x -c --disable-cpu-affinity") + except BaseException, e: + log("ERROR: ALU test failed: eNB compilation failed: " + str(e)) + return #run tests @@ -361,29 +375,38 @@ def run_b210_alu(tests, openair_dir, oai_user, oai_password, env): "10" : "15M", "20" : "15M" } - for bw in ('5', '10', '20'): - if do_tests(tests['b210']['alu'][bw]): - log("INFO: ALU test: run tests for bandwidth " + bw + " MHz") - ctest = tests['b210']['alu'][bw] - alu = alu_test(epc='amerique', enb='hutch', ue='stevens', - openair=openair_dir, - user=oai_user, password=oai_password, - log_subdir='enb_tests/b210_alu/' + bw, - env=env) - try: - alu.start_epc() - alu.start_enb("enb.band7.tm1.usrpb210." + bw + "MHz.conf") - if do_tests(ctest['bandrich']): - alu.start_bandrich_ue() - if do_tests(ctest['bandrich']['tcp']['dl']): alu.dl_tcp() - if do_tests(ctest['bandrich']['tcp']['ul']): alu.ul_tcp() - if do_tests(ctest['bandrich']['udp']['dl']): - alu.dl_udp(udp_dl_bandwidth[bw]) - if do_tests(ctest['bandrich']['udp']['ul']): - alu.ul_udp(udp_ul_bandwidth[bw]) - alu.stop_bandrich_ue() - alu.stop_enb() - alu.stop_epc() - except BaseException, e: - log("ERROR: ALU test failed: " + str(e)) - alu.finish() + ue_machine = { "fdd" : "stevens", + "tdd" : "mozart" } + + enb_machine = { "fdd" : "hutch", + "tdd" : "calisson" } + + band = { "fdd" : "7", + "tdd" : "38" } + + for mode in ('fdd', 'tdd'): + for bw in ('5', '10', '20'): + if do_tests(tests['b210']['alu'][mode][bw]): + log("INFO: ALU test: run tests for bandwidth " + bw + " MHz") + ctest = tests['b210']['alu'][mode][bw] + alu = alu_test(epc='amerique', enb=enb_machine[mode], ue=ue_machine[mode], + openair=openair_dir, + user=oai_user, password=oai_password, + log_subdir='enb_tests/b210_alu/' + mode + "/" + bw, + env=env) + try: + alu.start_epc() + alu.start_enb("enb.band" + band[mode] + ".tm1.usrpb210." + mode + "." + bw + "MHz.conf") + for ue in ('bandrich', '3276'): + if ue in ctest and do_tests(ctest[ue]): + alu.start_ue(ue) + if do_tests(ctest[ue]['tcp']['dl']): alu.dl_tcp(ue) + if do_tests(ctest[ue]['tcp']['ul']): alu.ul_tcp(ue) + if do_tests(ctest[ue]['udp']['dl']): alu.dl_udp(ue, udp_dl_bandwidth[bw]) + if do_tests(ctest[ue]['udp']['ul']): alu.ul_udp(ue, udp_ul_bandwidth[bw]) + alu.stop_ue(ue) + alu.stop_enb() + alu.stop_epc() + except BaseException, e: + log("ERROR: ALU test failed: " + str(e)) + alu.finish() diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf new file mode 100644 index 0000000000..c25b954e1a --- /dev/null +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf @@ -0,0 +1,175 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2580000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -24; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf new file mode 100644 index 0000000000..0773f9c267 --- /dev/null +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf @@ -0,0 +1,175 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2580000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -24; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf new file mode 100644 index 0000000000..024be3b775 --- /dev/null +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf @@ -0,0 +1,175 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2580000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -24; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -90; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.82/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth6"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.82/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf similarity index 100% rename from cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.10MHz.conf rename to cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf similarity index 100% rename from cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.20MHz.conf rename to cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf similarity index 100% rename from cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.5MHz.conf rename to cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf diff --git a/cmake_targets/autotests/v2/main.py b/cmake_targets/autotests/v2/main.py index 6cf3b97c36..14e5442720 100644 --- a/cmake_targets/autotests/v2/main.py +++ b/cmake_targets/autotests/v2/main.py @@ -283,27 +283,41 @@ machine_list.wait_all_free() tests = { 'b210' : { 'alu' : { - '5' : { - 'bandrich' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}, - 'sony' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}, - '10' : { - 'bandrich' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}, - 'sony' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}, - '20' : { - 'bandrich' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}, - 'sony' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}}, + 'fdd' : { + '5' : { + 'bandrich' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}, + 'sony' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}}, + '10' : { + 'bandrich' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}, + 'sony' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}}, + '20' : { + 'bandrich' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}, + 'sony' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}}}, + 'tdd' : { + '5' : { + '3276' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}}, + '10' : { + '3276' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}}, + '20' : { + '3276' : { + 'tcp' : { 'ul': False, 'dl' : False }, + 'udp' : { 'ul': False, 'dl' : False }}}}}, 'openair-cn' : {} }, 'x310' : { @@ -321,24 +335,24 @@ for test in todo_tests: todo_tests_ids.append(test.get('id')) for test in todo_tests_ids: - if test=='015500':tests['b210']['alu'][ '5']['bandrich']['udp']['ul']=True - if test=='015501':tests['b210']['alu']['10']['bandrich']['udp']['ul']=True - if test=='015502':tests['b210']['alu']['20']['bandrich']['udp']['ul']=True - if test=='015503':tests['b210']['alu'][ '5']['bandrich']['udp']['dl']=True - if test=='015504':tests['b210']['alu']['10']['bandrich']['udp']['dl']=True - if test=='015505':tests['b210']['alu']['20']['bandrich']['udp']['dl']=True + if test=='015500':tests['b210']['alu']['fdd'][ '5']['bandrich']['udp']['ul']=True + if test=='015501':tests['b210']['alu']['fdd']['10']['bandrich']['udp']['ul']=True + if test=='015502':tests['b210']['alu']['fdd']['20']['bandrich']['udp']['ul']=True + if test=='015503':tests['b210']['alu']['fdd'][ '5']['bandrich']['udp']['dl']=True + if test=='015504':tests['b210']['alu']['fdd']['10']['bandrich']['udp']['dl']=True + if test=='015505':tests['b210']['alu']['fdd']['20']['bandrich']['udp']['dl']=True if test=='015506':log('WARNING: skip test ' + test) #TODO if test=='015507':log('WARNING: skip test ' + test) #TODO if test=='015508':log('WARNING: skip test ' + test) #TODO if test=='015509':log('WARNING: skip test ' + test) #TODO if test=='015510':log('WARNING: skip test ' + test) #TODO if test=='015511':log('WARNING: skip test ' + test) #TODO - if test=='015512':tests['b210']['alu'][ '5']['bandrich']['tcp']['ul']=True - if test=='015513':tests['b210']['alu']['10']['bandrich']['tcp']['ul']=True - if test=='015514':tests['b210']['alu']['20']['bandrich']['tcp']['ul']=True - if test=='015515':tests['b210']['alu'][ '5']['bandrich']['tcp']['dl']=True - if test=='015516':tests['b210']['alu']['10']['bandrich']['tcp']['dl']=True - if test=='015517':tests['b210']['alu']['20']['bandrich']['tcp']['dl']=True + if test=='015512':tests['b210']['alu']['fdd'][ '5']['bandrich']['tcp']['ul']=True + if test=='015513':tests['b210']['alu']['fdd']['10']['bandrich']['tcp']['ul']=True + if test=='015514':tests['b210']['alu']['fdd']['20']['bandrich']['tcp']['ul']=True + if test=='015515':tests['b210']['alu']['fdd'][ '5']['bandrich']['tcp']['dl']=True + if test=='015516':tests['b210']['alu']['fdd']['10']['bandrich']['tcp']['dl']=True + if test=='015517':tests['b210']['alu']['fdd']['20']['bandrich']['tcp']['dl']=True if test=='015518':log('WARNING: skip test ' + test) #TODO if test=='015519':log('WARNING: skip test ' + test) #TODO if test=='015520':log('WARNING: skip test ' + test) #TODO @@ -441,6 +455,31 @@ for test in todo_tests_ids: if test=='018504':log('WARNING: skip test ' + test) #TODO if test=='018505':log('WARNING: skip test ' + test) #TODO + if test=='018600':tests['b210']['alu']['tdd'][ '5']['3276']['udp']['ul']=True + if test=='018601':tests['b210']['alu']['tdd']['10']['3276']['udp']['ul']=True + if test=='018602':tests['b210']['alu']['tdd']['20']['3276']['udp']['ul']=True + if test=='018603':tests['b210']['alu']['tdd'][ '5']['3276']['udp']['dl']=True + if test=='018604':tests['b210']['alu']['tdd']['10']['3276']['udp']['dl']=True + if test=='018605':tests['b210']['alu']['tdd']['20']['3276']['udp']['dl']=True + if test=='018606':log('WARNING: skip test ' + test) #TODO + if test=='018607':log('WARNING: skip test ' + test) #TODO + if test=='018608':log('WARNING: skip test ' + test) #TODO + if test=='018609':log('WARNING: skip test ' + test) #TODO + if test=='018610':log('WARNING: skip test ' + test) #TODO + if test=='018611':log('WARNING: skip test ' + test) #TODO + if test=='018612':tests['b210']['alu']['tdd'][ '5']['3276']['tcp']['ul']=True + if test=='018613':tests['b210']['alu']['tdd']['10']['3276']['tcp']['ul']=True + if test=='018614':tests['b210']['alu']['tdd']['20']['3276']['tcp']['ul']=True + if test=='018615':tests['b210']['alu']['tdd'][ '5']['3276']['tcp']['dl']=True + if test=='018616':tests['b210']['alu']['tdd']['10']['3276']['tcp']['dl']=True + if test=='018617':tests['b210']['alu']['tdd']['20']['3276']['tcp']['dl']=True + if test=='018618':log('WARNING: skip test ' + test) #TODO + if test=='018619':log('WARNING: skip test ' + test) #TODO + if test=='018620':log('WARNING: skip test ' + test) #TODO + if test=='018621':log('WARNING: skip test ' + test) #TODO + if test=='018622':log('WARNING: skip test ' + test) #TODO + if test=='018623':log('WARNING: skip test ' + test) #TODO + if test=='025500':log('WARNING: skip test ' + test) #TODO if test=='025501':log('WARNING: skip test ' + test) #TODO if test=='025502':log('WARNING: skip test ' + test) #TODO From 947e50f33d6a9e78ae6d525e5f002e5c7df121e2 Mon Sep 17 00:00:00 2001 From: hbilel Date: Mon, 13 Mar 2017 09:49:56 +0100 Subject: [PATCH 380/571] integration fix optional compilation of avx2 --- cmake_targets/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0bf63cfb1a..3687b08a1a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -130,6 +130,9 @@ else (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") file(STRINGS "/proc/cpuinfo" CPUINFO REGEX flags LIMIT_COUNT 1) if (CPUINFO MATCHES "avx2") set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2") + set(COMPILATION_AVX2 "True") + else() + set(COMPILATION_AVX2 "False") endif() if (CPUINFO MATCHES "sse4_1") set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1") @@ -1034,7 +1037,6 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_modulation.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation.c - ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/power_control.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_decoding.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -1117,6 +1119,11 @@ set(PHY_SRC if (${SMBV}) set(PHY_SRC "${PHY_SRC} ${OPENAIR1_DIR}/PHY/TOOLS/smbv.c") endif (${SMBV}) + +if (${COMPILATION_AVX2} STREQUAL "True") + set(PHY_SRC ${PHY_SRC} ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.c) +endif () + add_library(PHY ${PHY_SRC}) #Layer 2 library From a194009e00a59d3d60c44421015da846a57e6633 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Mar 2017 10:06:26 +0100 Subject: [PATCH 381/571] integration fix: put dlsch_demod_shift into dlsch_demodulation --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 7 ++++++- targets/RT/USER/lte-softmodem.c | 7 ++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 9ed40ce162..a842a8a9dc 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -42,7 +42,12 @@ #define NOCYGWIN_STATIC #endif -extern int16_t dlsch_demod_shift; +/* dynamic shift for LLR computation for TM3/4 + * set as command line argument, see lte-softmodem.c + * default value: 0 + */ +int16_t dlsch_demod_shift = 0; + //#define DEBUG_HARQ //#undef LOG_D diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 5761577259..65f578fd25 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -151,8 +151,6 @@ uint8_t usim_test = 0; uint8_t nb_antenna_tx = 1; uint8_t nb_antenna_rx = 1; -int16_t dlsch_demod_shift = 0; - char ref[128] = "internal"; char channels[128] = "0"; @@ -323,6 +321,7 @@ void help (void) { printf(" --ue-txgain set UE TX gain\n"); printf(" --ue-nb-ant-rx set UE number of rx antennas "); printf(" --ue-scan_carrier set UE to scan around carrier\n"); + printf(" --dlsch-demod-shift dynamic shift for LLR compuation for TM3/4 (default 0)\n"); printf(" --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n"); printf(" --mmapped-dma sets flag for improved EXMIMO UE performance\n"); printf(" --external-clock tells hardware to use an external clock reference\n"); @@ -804,9 +803,11 @@ static void get_options (int argc, char **argv) { case LONG_OPTION_THREADEVENSUBFRAME: threads.even=atoi(optarg); break; - case LONG_OPTION_DEMOD_SHIFT: + case LONG_OPTION_DEMOD_SHIFT: { + extern int16_t dlsch_demod_shift; dlsch_demod_shift = atof(optarg); break; + } #if T_TRACER case LONG_OPTION_T_PORT: { extern int T_port; From b82b7781eed6a021bc546018b5cbe816e04ed1d4 Mon Sep 17 00:00:00 2001 From: hbilel Date: Mon, 13 Mar 2017 10:13:23 +0100 Subject: [PATCH 382/571] integration fix clear tx-buffer of ue in case of empty subframe for all processing including oaisim --- openair1/SCHED/phy_procedures_lte_ue.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 96082340b9..386dd8b52c 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1045,8 +1045,8 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; int ulsch_start; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int overflow=0; +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) int k,l; int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16))); #endif @@ -1074,7 +1074,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance; #endif //else EXMIMO -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) +//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) if (empty_subframe) { //#if 1 @@ -1082,14 +1082,14 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt for (aa=0; aanb_antennas_tx; aa++) { if (overflow > 0) - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow)); - memset(&ue->common_vars.txdata[aa][0],0,4*overflow); - } - else - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti); - } + { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow)); + memset(&ue->common_vars.txdata[aa][0],0,4*overflow); + } + else + { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti); + } } /*#else overflow = ulsch_start - 9*frame_parms->samples_per_tti; @@ -1107,7 +1107,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt #endif*/ return; } -#endif +//#endif if ((frame_tx%100) == 0) LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n", From cec9cb7662aa2184876042c6ed5aa2a599ad29a1 Mon Sep 17 00:00:00 2001 From: hbilel Date: Mon, 13 Mar 2017 12:05:47 +0100 Subject: [PATCH 383/571] fix compilation error for dlsim --- openair1/SIMULATION/LTE_PHY/dlsim.c | 56 ++-- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 346 ++++++++++++------------ openair1/SIMULATION/LTE_PHY/dlsim_tm7.c | 132 ++++----- 3 files changed, 267 insertions(+), 267 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index af39d92a6b..ddc108a7c8 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2098,14 +2098,14 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[0][i]) { + if (!UE->dlsch[subframe&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[0][i]->rnti = n_rnti; + UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; } UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); @@ -2254,7 +2254,7 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_rate_matching_stats); reset_meas(&eNB->dlsch_turbo_encoding_stats); - reset_meas(&UE->phy_proc_rx); // total UE rx + reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx reset_meas(&UE->ofdm_demod_stats); reset_meas(&UE->dlsch_channel_estimation_stats); reset_meas(&UE->dlsch_freq_offset_estimation_stats); @@ -2488,7 +2488,7 @@ int main(int argc, char **argv) if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); phy_procedures_UE_RX(UE,proc,0,0,normal_txrx,no_relay,NULL); - if (UE->dlsch[0][0]->active == 0) { + if (UE->dlsch[subframe&0x1][0][0]->active == 0) { //printf("DCI not received\n"); /* write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); @@ -2543,7 +2543,7 @@ int main(int argc, char **argv) //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); @@ -2561,13 +2561,13 @@ int main(int argc, char **argv) if (UE->dlsch_errors[0] == 0) { - avg_iter += UE->dlsch[eNB_id][0]->last_iteration_cnt; + avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt; iter_trials++; if (n_frames==1) printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; @@ -2575,25 +2575,25 @@ int main(int argc, char **argv) else { errs[round]++; - avg_iter += UE->dlsch[eNB_id][0]->last_iteration_cnt-1; + avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt-1; iter_trials++; if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); - for (s=0; sdlsch[0][0]->harq_processes[0]->C; s++) { - if (sdlsch[0][0]->harq_processes[0]->Cminus) - Kr = UE->dlsch[0][0]->harq_processes[0]->Kminus; + for (s=0; sdlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) { + if (sdlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[0][0]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0; idlsch[0][0]->harq_processes[0]->c[s][i],UE->dlsch[0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -2644,13 +2644,13 @@ int main(int argc, char **argv) } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); //write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); //write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); //write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - //write_output("dlsch_w.m","w",UE->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + //write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); //pdcch_vars write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); @@ -2664,7 +2664,7 @@ int main(int argc, char **argv) // printf("round %d errors %d/%d\n",round,errs[round],trials); round++; - // UE->dlsch[0][0]->harq_processes[0]->round++; + // UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++; } if (xforms==1) { @@ -2705,7 +2705,7 @@ int main(int argc, char **argv) double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx = (double)UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0; double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; @@ -2854,7 +2854,7 @@ int main(int argc, char **argv) rate*effective_rate, 100*effective_rate, rate, - rate*get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs), + rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -2894,10 +2894,10 @@ int main(int argc, char **argv) eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials); printf("\n\nUE RX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_rx = sqrt((double)UE->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_rx.trials - pow((double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000.0, - UE->phy_proc_rx.trials*2/3); + std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2)); + printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0, + UE->phy_proc_rx[subframe&0x1].trials*2/3); printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, @@ -2931,7 +2931,7 @@ int main(int argc, char **argv) printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[0][0]->harq_processes[0]->Cminus ? UE->dlsch[0][0]->harq_processes[0]->Kminus : UE->dlsch[0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -3109,7 +3109,7 @@ int main(int argc, char **argv) eNB->dlsch_modulation_stats.trials, eNB->dlsch_scrambling_stats.trials, eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx.trials, + UE->phy_proc_rx[subframe&0x1].trials, UE->ofdm_demod_stats.trials, UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, @@ -3122,7 +3122,7 @@ int main(int argc, char **argv) get_time_meas_us(&eNB->dlsch_modulation_stats), get_time_meas_us(&eNB->dlsch_scrambling_stats), get_time_meas_us(&eNB->dlsch_encoding_stats), - get_time_meas_us(&UE->phy_proc_rx), + get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]), nsymb*get_time_meas_us(&UE->ofdm_demod_stats), get_time_meas_us(&UE->dlsch_rx_pdcch_stats), 3*get_time_meas_us(&UE->dlsch_llr_stats), @@ -3162,7 +3162,7 @@ int main(int argc, char **argv) eNB->dlsch_modulation_stats.trials, eNB->dlsch_scrambling_stats.trials, eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx.trials, + UE->phy_proc_rx[subframe&0x1].trials, UE->ofdm_demod_stats.trials, UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, @@ -3220,7 +3220,7 @@ int main(int argc, char **argv) printf("eNB %d\n",i); free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[0][i]); + free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index c3f975006d..b45bfdf324 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -980,15 +980,15 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[0][i]) { + if (!UE->dlsch[subframe&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[0][i]->rnti = n_rnti; + UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; } // structure for SIC at UE @@ -2081,7 +2081,7 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_rate_matching_stats); reset_meas(&eNB->dlsch_turbo_encoding_stats); - reset_meas(&UE->phy_proc_rx); // total UE rx + reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx reset_meas(&UE->ofdm_demod_stats); reset_meas(&UE->dlsch_channel_estimation_stats); reset_meas(&UE->dlsch_freq_offset_estimation_stats); @@ -2135,8 +2135,8 @@ int main(int argc, char **argv) eNB2UE[0]->first_run = 1; - ret[0] = UE->dlsch[0][0]->max_turbo_iterations+1; - ret[1] = UE->dlsch[0][0]->max_turbo_iterations+1; + ret[0] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; + ret[1] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; resend_cw0_cw1=1; resend_cw1=0; @@ -2144,10 +2144,10 @@ int main(int argc, char **argv) TB1_active=1; while (((transmission_mode == 3 || transmission_mode == 4) && - ((round < num_rounds) && ((ret[0] > UE->dlsch[0][0]->max_turbo_iterations) || - (ret[1] > UE->dlsch[0][0]->max_turbo_iterations)))) || + ((round < num_rounds) && ((ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) || + (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) || ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && - (ret[0] > UE->dlsch[0][0]->max_turbo_iterations)))) { + (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) { #ifdef DEBUG_HARQ printf("\n [DLSIM] On top round is %d\n", round); #endif @@ -2158,10 +2158,10 @@ int main(int argc, char **argv) //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); - /*if (ret[0] > UE->dlsch[0][0]->max_turbo_iterations) { + /*if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) { round_trials[0][round]++; round_trials[1][round]++; - } else if ((ret[1] > UE->dlsch[0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[0][0]->max_turbo_iterations)) + } else if ((ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) round_trials[1][round]++;*/ @@ -2624,7 +2624,7 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - UE->dlsch[0][1]->pmi_alloc, + UE->dlsch[subframe&0x1][0][1]->pmi_alloc, transmission_mode>=7?transmission_mode:0 ); break; @@ -2852,7 +2852,7 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - UE->dlsch[0][1]->pmi_alloc, + UE->dlsch[subframe&0x1][0][1]->pmi_alloc, transmission_mode>=7?transmission_mode:0 ); break; @@ -2983,7 +2983,7 @@ int main(int argc, char **argv) // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); - UE->dlsch[0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); if (n_users>1) eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); /* @@ -3007,7 +3007,7 @@ int main(int argc, char **argv) printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); } else if (updated_csi == 0){ @@ -3020,7 +3020,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); } else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ @@ -3031,7 +3031,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); } } else if (updated_csi == 1){ @@ -3050,11 +3050,11 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I quantize from ENodeB 2\n"); #endif - UE->dlsch[0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); #ifdef DEBUG_HARQ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif - UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); } else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ #ifdef DEBUG_HARQ @@ -3070,11 +3070,11 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I quantize from ENodeB 2\n"); #endif - UE->dlsch[0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); #ifdef DEBUG_HARQ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif - UE->dlsch[0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); } } @@ -3363,7 +3363,7 @@ int main(int argc, char **argv) pilot3 = 9; } - start_meas(&UE->phy_proc_rx); + start_meas(&UE->phy_proc_rx[subframe&0x1]); // Inner receiver scheduling for 3 slots for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) { for (l=0;ldlsch[0][0]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; } if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) { - UE->dlsch[0][1]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1; } if ((dci_alloc_rx[i].rnti == n_rnti) && @@ -3537,7 +3537,7 @@ int main(int argc, char **argv) dci_alloc_rx[i].dci_pdu, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3547,30 +3547,30 @@ int main(int argc, char **argv) UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0)==0)) { dump_dci(&UE->frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword[0]= get_G(&eNB->frame_parms, - UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->nb_rb, - UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs), - UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->Nl, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[0]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); if (transmission_mode == 3 || transmission_mode == 4) { coded_bits_per_codeword[1]= get_G(&eNB->frame_parms, - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->nb_rb, - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs), - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->Nl, + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[1]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); } /* - rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs)][UE->dlsch[0][0]->nb_rb-1]/(coded_bits_per_codeword); - rate*=get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs); + rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs); */ - printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->TBS); + printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); dlsch_active = 1; // what does it indicates??? } else { @@ -3594,8 +3594,8 @@ int main(int argc, char **argv) UE->pdcch_vars[0]->crnti = n_rnti; UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; if (round == 0) { - UE->dlsch[0][0]->harq_processes[0]->first_tx=1; - UE->dlsch[0][1]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1; } switch (transmission_mode) { @@ -3606,7 +3606,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format1 : format1A, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3617,14 +3617,14 @@ int main(int argc, char **argv) break; case 3: - //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx); + //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); generate_ue_dlsch_params_from_dci(0, subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2A : format1A, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3632,7 +3632,7 @@ int main(int argc, char **argv) P_RNTI, transmission_mode<7?0:transmission_mode, UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0); - //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx); + //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); break; case 4: generate_ue_dlsch_params_from_dci(0, @@ -3640,7 +3640,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A,//format1A only for a codeblock - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3657,7 +3657,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu2_1E[0], C_RNTI, format1E_2A_M10PRB, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3673,13 +3673,13 @@ int main(int argc, char **argv) if (dlsch_active == 1) { if (TB0_active==1) - cur_harq_pid =UE->dlsch[0][0]->current_harq_pid; + cur_harq_pid =UE->dlsch[subframe&0x1][0][0]->current_harq_pid; else - cur_harq_pid =UE->dlsch[0][1]->current_harq_pid; + cur_harq_pid =UE->dlsch[subframe&0x1][0][1]->current_harq_pid; if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix /* if (transmission_mode == 5) { - if ((UE->dlsch[eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && + if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && (openair_daq_vars.use_ia_receiver ==1)) { rx_type = rx_IC_single_stream; } else { @@ -3701,7 +3701,7 @@ int main(int argc, char **argv) (m==UE->pdcch_vars[0]->num_pdcch_symbols)?1:0, rx_type, i_mod, - UE->dlsch[0][0]->current_harq_pid)==-1){ + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1){ dlsch_active = 0; break; } @@ -3788,7 +3788,7 @@ int main(int argc, char **argv) break; } - UE->dlsch[0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe&0x1][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[TB] = get_G(&eNB->frame_parms, eNB->dlsch[0][TB]->harq_processes[0]->nb_rb, eNB->dlsch[0][TB]->harq_processes[0]->rb_alloc, @@ -3798,12 +3798,12 @@ int main(int argc, char **argv) 0,subframe, transmission_mode>=7?transmission_mode:0); - UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; - UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs); + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs); if (n_frames==2) { printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB], - UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->TBS); + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]); @@ -3812,7 +3812,7 @@ int main(int argc, char **argv) sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB); - write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); + write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); sprintf(fname,"dlsch_cw%d_e.m", TB); sprintf(vname,"dlschcw%d_e", TB); write_output(fname, vname,eNB->dlsch[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4); @@ -3820,7 +3820,7 @@ int main(int argc, char **argv) printf("trials=%d\n", trials); for (i=0;idlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword][i]<0)) { + if (eNB->dlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } @@ -3842,22 +3842,22 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, 0, - UE->dlsch[0][TB], + UE->dlsch[subframe&0x1][0][TB], coded_bits_per_codeword[TB], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword], TB, subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); start_meas(&UE->dlsch_decoding_stats); ret[TB] = dlsch_decoding(UE, - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword], &UE->frame_parms, - UE->dlsch[0][TB], - UE->dlsch[0][TB]->harq_processes[UE->dlsch[0][TB]->current_harq_pid], + UE->dlsch[subframe&0x1][0][TB], + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid], 0, subframe, - UE->dlsch[0][TB]->current_harq_pid, + UE->dlsch[subframe&0x1][0][TB]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats); #ifdef DEBUG_HARQ @@ -3865,11 +3865,11 @@ int main(int argc, char **argv) #endif //printf("retr cw 0 = %d\n", ret[0]); - //printf("current round = %d\n", UE->dlsch[0][cw_non_sic]->harq_processes[UE->dlsch[0][cw_non_sic]->current_harq_pid]->round); + //printf("current round = %d\n", UE->dlsch[subframe&0x1][0][cw_non_sic]->harq_processes[UE->dlsch[subframe&0x1][0][cw_non_sic]->current_harq_pid]->round); - if (ret[TB] <= UE->dlsch[0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 + if (ret[TB] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 #ifdef DEBUG_HARQ printf("[DLSIM] TB%d is decoded\n", TB); #endif @@ -3880,33 +3880,33 @@ int main(int argc, char **argv) if (n_frames==2) { printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[0][TB]->harq_processes[0]->C;s++) { - if (sdlsch[0][TB]->harq_processes[0]->Cminus) - Kr = UE->dlsch[0][TB]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[0][TB]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][TB]->harq_processes[0]->c[s][i], - UE->dlsch[0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); } #endif } - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[eNB_id][TB]->harq_processes[UE->dlsch[eNB_id][TB]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][TB]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][TB]->current_harq_pid]->TBS; // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) - if (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* - //for (round = 0 ; round < UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->round ; round++) { + //for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { // we assume here that the second stream has a lower MCS and is thus more likely to be decoded // re-encoding of second stream - dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = LARGE_CDD; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; @@ -3920,14 +3920,14 @@ int main(int argc, char **argv) dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - UE->dlsch[eNB_id]->active = UE->dlsch[eNB_id][0]->active; - UE->dlsch[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti; - UE->dlsch[eNB_id]->current_harq_pid = UE->dlsch[eNB_id][0]->current_harq_pid; + UE->dlsch[subframe&0x1][eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; + UE->dlsch[subframe&0x1][eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; + UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; - dlsch_encoding(UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b, + dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, - UE->dlsch[eNB_id], + UE->dlsch[subframe&0x1][eNB_id], 0,subframe, &UE->dlsch_rate_matching_stats, &UE->dlsch_turbo_encoding_stats, @@ -3935,10 +3935,10 @@ int main(int argc, char **argv) ); coded_bits_per_codeword = get_G(&UE->frame_parms, - UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->nb_rb, - UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->rb_alloc, - get_Qm(UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->mcs), - UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id]->current_harq_pid]->Nl, + UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->Nl, num_pdcch_symbols, 0,subframe); @@ -3946,7 +3946,7 @@ int main(int argc, char **argv) //scrambling dlsch_scrambling(&UE->frame_parms, 0, - UE->dlsch[eNB_id], + UE->dlsch[subframe&0x1][eNB_id], coded_bits_per_codeword, 0, subframe<<1); @@ -3958,7 +3958,7 @@ int main(int argc, char **argv) subframe, &UE->frame_parms, num_pdcch_symbols, - &UE->dlsch[0][0], + &UE->dlsch[subframe&0x1][0][0], NULL); // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding // precoding is contained in effective channel estimate @@ -3998,8 +3998,8 @@ int main(int argc, char **argv) } - if ((UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && + if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && (rx_type==rx_SIC_dual_stream)) { #ifdef DEBUG_HARQ printf("[DLSIM] Starting SIC procedure\n"); @@ -4018,10 +4018,10 @@ int main(int argc, char **argv) #endif //printf("I enter round_sic loop \n"); //printf("round_sic= %d\n", round_sic); - dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq->mimo_mode = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode; + dlsch0_eNB_harq->mimo_mode = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; @@ -4033,28 +4033,28 @@ int main(int argc, char **argv) dlsch0_eNB_harq->status = dlsch0_ue_harq->status; if (round_sic == 0){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 0; - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=0; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 0; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=0; } else if (round_sic == 1){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 1; - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=1; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 1; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=1; } else if (round_sic == 2){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 2; - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=2; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 2; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=2; } else{ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[eNB_id][1]->current_harq_pid]->rvidx = 3; - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->rvidx=3; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 3; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=3; } - UE->dlsch_eNB[eNB_id]->active = UE->dlsch[eNB_id][0]->active; - UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti; - UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[eNB_id][0]->current_harq_pid; + UE->dlsch_eNB[eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; + UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; + UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; dlsch_encoding_SIC(UE, - input_buffer0[0], //UE->dlsch[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,, + input_buffer0[0], //UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,, num_pdcch_symbols, UE->dlsch_eNB[eNB_id], 0, @@ -4089,8 +4089,8 @@ int main(int argc, char **argv) coded_bits_per_codeword[0]); // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); - // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1); - // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); switch (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){ @@ -4100,58 +4100,58 @@ int main(int argc, char **argv) case 2: dlsch_qpsk_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - UE->dlsch[eNB_id][0]); + UE->dlsch[subframe&0x1][eNB_id][0]); break; case 4: dlsch_16qam_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs), - UE->dlsch[eNB_id][0]); + UE->dlsch[subframe&0x1][eNB_id][0]); break; case 6: dlsch_64qam_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - UE->dlsch[eNB_id][TB]); + UE->dlsch[subframe&0x1][eNB_id][TB]); break; } //}// rouns sic #ifdef DEBUG_HARQ - printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword); + printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword); #endif // write_output("rxdata_llr1.m","llr1", UE->pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); // replace cw_sic with TB+1 - UE->dlsch[0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe&0x1][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[1]= get_G(&eNB->frame_parms, eNB->dlsch[0][1]->harq_processes[0]->nb_rb, eNB->dlsch[0][1]->harq_processes[0]->rb_alloc, @@ -4162,12 +4162,12 @@ int main(int argc, char **argv) subframe, transmission_mode>=7?transmission_mode:0); - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs); + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs); if (n_frames==2) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1], - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->TBS); + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]); @@ -4181,7 +4181,7 @@ int main(int argc, char **argv) uncoded_ber=0; printf("trials=%d\n", trials); for (i=0;idlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword][i]<0)) { + if (eNB->dlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } @@ -4201,9 +4201,9 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, 0, - UE->dlsch[0][1], + UE->dlsch[subframe&0x1][0][1], coded_bits_per_codeword[1], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], 1, subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); @@ -4211,13 +4211,13 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_decoding_stats); ret[1] = dlsch_decoding(UE, - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], &UE->frame_parms, - UE->dlsch[0][1], - UE->dlsch[0][1]->harq_processes[UE->dlsch[0][1]->current_harq_pid], + UE->dlsch[subframe&0x1][0][1], + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid], 0, subframe, - UE->dlsch[0][1]->current_harq_pid, + UE->dlsch[subframe&0x1][0][1]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats); @@ -4227,7 +4227,7 @@ int main(int argc, char **argv) //printf("ret TB 1 = %d round %d \n", ret[1], round); - if (ret[1] <=UE->dlsch[0][0]->max_turbo_iterations ) { + if (ret[1] <=UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { decoded_in_sic[round]++; round_sic = round+1; // to exit round_sic #ifdef DEBUG_HARQ @@ -4241,19 +4241,19 @@ int main(int argc, char **argv) printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[0][1]->harq_processes[0]->C;s++) { - if (sdlsch[0][1]->harq_processes[0]->Cminus) - Kr = UE->dlsch[0][1]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[0][1]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][1]->harq_processes[0]->c[s][i], - UE->dlsch[0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); } #endif } @@ -4261,7 +4261,7 @@ int main(int argc, char **argv) } //round_sic - if (ret[1] > UE->dlsch[0][0]->max_turbo_iterations ){ + if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ){ errs[1][round]++; #ifdef DEBUG_HARQ printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]); @@ -4276,23 +4276,23 @@ int main(int argc, char **argv) //if ((n_frames==1) || (SNR>=30)) { printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[0][1]->harq_processes[0]->C;s++) { - if (sdlsch[0][1]->harq_processes[0]->Cminus) - Kr = UE->dlsch[0][1]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[0][1]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][1]->harq_processes[0]->c[s][i], - UE->dlsch[0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); } #endif } //n_frames==1 // exit(0); - } //if (ret > UE->dlsch[0][1]->max_turbo_iterations ) + } //if (ret > UE->dlsch[subframe&0x1][0][1]->max_turbo_iterations ) }//if SIC } else { @@ -4307,8 +4307,8 @@ int main(int argc, char **argv) iter_trials[0]++; }*/ - if ((UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) { errs[1][round]++; #ifdef DEBUG_HARQ @@ -4327,18 +4327,18 @@ int main(int argc, char **argv) //if ((n_frames==1) || (SNR>=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[0][TB]->harq_processes[0]->C;s++) { - if (sdlsch[0][TB]->harq_processes[0]->Cminus) - Kr = UE->dlsch[0][TB]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[0][TB]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[0][TB]->harq_processes[0]->c[s][i], - UE->dlsch[0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); } #endif } @@ -4347,7 +4347,7 @@ int main(int argc, char **argv) TB++; // to terminate the loop over TB } - stop_meas(&UE->phy_proc_rx); + stop_meas(&UE->phy_proc_rx[subframe&0x1]); if (n_frames==1) { @@ -4410,12 +4410,12 @@ int main(int argc, char **argv) UE->frame_parms.ofdm_symbol_size*nsymb,1,1); } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); /* write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("dlsch_eNB_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - write_output("dlsch_UE_w.m","w",UE->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + write_output("dlsch_UE_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); */ //pdcch_vars @@ -4439,15 +4439,15 @@ int main(int argc, char **argv) printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]); #endif - if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[0][0]->max_turbo_iterations)){ + if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)){ //printf("flag 1 \n"); round++; } if (transmission_mode == 3 || transmission_mode == 4 ) { - if (ret[0] > UE->dlsch[0][0]->max_turbo_iterations && - ret[1] > UE->dlsch[0][0]->max_turbo_iterations){ + if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && + ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ resend_both[round]++; round++; resend_cw0_cw1=1; //resend both cws @@ -4455,8 +4455,8 @@ int main(int argc, char **argv) TB0_active=1; TB1_active=1; } - else if (ret[1] > UE->dlsch[0][0]->max_turbo_iterations && - ret[0] <= UE->dlsch[0][0]->max_turbo_iterations){ + else if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && + ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ resend_one[round]++; resend_cw0_cw1=0; TB0_active=0; @@ -4476,8 +4476,8 @@ int main(int argc, char **argv) #endif round++; } - else if (ret[0] > UE->dlsch[0][0]->max_turbo_iterations && - ret[1] <= UE->dlsch[0][0]->max_turbo_iterations){ + else if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && + ret[1] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ resend_one[round]++; resend_cw0_cw1=0; TB0_active=1; @@ -4531,7 +4531,7 @@ int main(int argc, char **argv) double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx = (double)UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0; double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; @@ -4796,7 +4796,7 @@ int main(int argc, char **argv) rate[0]*effective_rate, 100*effective_rate, rate[0], - rate[0]*get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs), + rate[0]*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+ 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) @@ -4864,10 +4864,10 @@ int main(int argc, char **argv) eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials); printf("\n\nUE RX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_rx = sqrt((double)UE->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_rx.trials - pow((double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000.0, - UE->phy_proc_rx.trials*2/3); + std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2)); + printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0, + UE->phy_proc_rx[subframe&0x1].trials*2/3); printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, @@ -4901,7 +4901,7 @@ int main(int argc, char **argv) printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[0][0]->harq_processes[0]->Cminus ? UE->dlsch[0][0]->harq_processes[0]->Kminus : UE->dlsch[0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -5189,7 +5189,7 @@ int main(int argc, char **argv) eNB->dlsch_modulation_stats.trials, eNB->dlsch_scrambling_stats.trials, eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx.trials, + UE->phy_proc_rx[subframe&0x1].trials, UE->ofdm_demod_stats.trials, UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, @@ -5202,7 +5202,7 @@ int main(int argc, char **argv) get_time_meas_us(&eNB->dlsch_modulation_stats), get_time_meas_us(&eNB->dlsch_scrambling_stats), get_time_meas_us(&eNB->dlsch_encoding_stats), - get_time_meas_us(&UE->phy_proc_rx), + get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]), nsymb*get_time_meas_us(&UE->ofdm_demod_stats), get_time_meas_us(&UE->dlsch_rx_pdcch_stats), 3*get_time_meas_us(&UE->dlsch_llr_stats), @@ -5326,7 +5326,7 @@ int main(int argc, char **argv) free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[0][i]); + free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 195f27f72e..6c306d6d46 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -953,14 +953,14 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[0][i]) { + if (!UE->dlsch[subframe&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[0][i]->rnti = n_rnti; + UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; } // structure for SIC at UE @@ -2069,7 +2069,7 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_rate_matching_stats); reset_meas(&eNB->dlsch_turbo_encoding_stats); - reset_meas(&UE->phy_proc_rx); // total UE rx + reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx reset_meas(&UE->ofdm_demod_stats); reset_meas(&UE->dlsch_channel_estimation_stats); reset_meas(&UE->dlsch_freq_offset_estimation_stats); @@ -2112,9 +2112,9 @@ int main(int argc, char **argv) //if (trials%100==0) eNB2UE[0]->first_run = 1; - ret = UE->dlsch[0][0]->max_turbo_iterations+1; + ret = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; - while ((round < num_rounds) && (ret > UE->dlsch[0][0]->max_turbo_iterations)) { + while ((round < num_rounds) && (ret > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) { //printf("Trial %d, round %d\n",trials,round); round_trials[round]++; @@ -2601,7 +2601,7 @@ PMI_FEEDBACK: // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); - UE->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); if (n_users>1) eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); @@ -3059,7 +3059,7 @@ PMI_FEEDBACK: } - start_meas(&UE->phy_proc_rx); + start_meas(&UE->phy_proc_rx[subframe&0x1]); // Inner receiver scheduling for 3 slots @@ -3227,7 +3227,7 @@ PMI_FEEDBACK: for (i=0; idlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->first_tx=1; + if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->first_tx=1; if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, @@ -3235,7 +3235,7 @@ PMI_FEEDBACK: dci_alloc_rx[i].dci_pdu, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3244,23 +3244,23 @@ PMI_FEEDBACK: transmission_mode<7?0:transmission_mode))) { //dump_dci(&UE->frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword = get_G(&eNB->frame_parms, - UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->nb_rb, - UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs), - UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->Nl, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[0]->num_pdcch_symbols, 0, subframe, (transmission_mode<7?0:transmission_mode)); /*if (transmission_mode==7 && common_flag==0) - UE->dlsch[0][0]->harq_processes[0]->mimo_mode = TM7; */ + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7; */ /* - rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs)][UE->dlsch[0][0]->nb_rb-1]/(coded_bits_per_codeword); - rate*=get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs); + rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs); */ printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword, - UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->TBS); + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); dlsch_active = 1; } else { @@ -3288,7 +3288,7 @@ PMI_FEEDBACK: UE->pdcch_vars[0]->crnti = n_rnti; UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; - if (round == 0) UE->dlsch[0][0]->harq_processes[0]->first_tx=1; + if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; switch (transmission_mode) { case 1: @@ -3299,7 +3299,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format1 : format1A, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3307,24 +3307,24 @@ PMI_FEEDBACK: P_RNTI, transmission_mode<7?0:transmission_mode); /*if(transmission_mode==7 && common_flag==0) - UE->dlsch[0][0]->harq_processes[0]->mimo_mode = TM7;*/ + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7;*/ break; case 3: - // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx); + // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); generate_ue_dlsch_params_from_dci(0, subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2A : format1A, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, 0, P_RNTI, 0); - // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[0][0]->harq_processes[0]->round,UE->dlsch[0][0]->harq_processes[0]->first_tx); + // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); break; case 4: @@ -3333,7 +3333,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3349,7 +3349,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu2_1E[0], C_RNTI, format1E_2A_M10PRB, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3381,7 +3381,7 @@ PMI_FEEDBACK: if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix) if ((transmission_mode == 5) && - (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->dl_power_off==0) && + (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->dl_power_off==0) && (UE->use_ia_receiver ==1)) { dual_stream_UE = 1; } else { @@ -3404,7 +3404,7 @@ PMI_FEEDBACK: (m==UE->pdcch_vars[0]->num_pdcch_symbols)?1:0, dual_stream_UE, i_mod, - UE->dlsch[0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { dlsch_active = 0; break; } @@ -3430,7 +3430,7 @@ PMI_FEEDBACK: 0, dual_stream_UE, i_mod, - UE->dlsch[0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { dlsch_active=0; break; } @@ -3456,7 +3456,7 @@ PMI_FEEDBACK: 0, dual_stream_UE, i_mod, - UE->dlsch[0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { dlsch_active=0; break; } @@ -3534,7 +3534,7 @@ PMI_FEEDBACK: } for (int cw=Kmimo-1; cw>=0; cw--) { - UE->dlsch[0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe&0x1][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword = get_G(&eNB->frame_parms, eNB->dlsch[0][cw]->harq_processes[0]->nb_rb, eNB->dlsch[0][cw]->harq_processes[0]->rb_alloc, @@ -3545,7 +3545,7 @@ PMI_FEEDBACK: subframe, (transmission_mode<7?0:transmission_mode)); - UE->dlsch[0][cw]->harq_processes[UE->dlsch[0][cw]->current_harq_pid]->G = coded_bits_per_codeword; + UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid]->G = coded_bits_per_codeword; @@ -3569,7 +3569,7 @@ PMI_FEEDBACK: start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, 0, - UE->dlsch[0][cw], + UE->dlsch[subframe&0x1][0][cw], coded_bits_per_codeword, UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw], 0, @@ -3580,15 +3580,15 @@ PMI_FEEDBACK: ret = dlsch_decoding(UE, UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw], &UE->frame_parms, - UE->dlsch[0][cw], - UE->dlsch[0][cw]->harq_processes[UE->dlsch[0][cw]->current_harq_pid], + UE->dlsch[subframe&0x1][0][cw], + UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid], subframe, - UE->dlsch[0][cw]->current_harq_pid, + UE->dlsch[subframe&0x1][0][cw]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats); if (cw==1) { - if (ret <= UE->dlsch[0][cw]->max_turbo_iterations) { + if (ret <= UE->dlsch[subframe&0x1][0][cw]->max_turbo_iterations) { } else { errs2[round]++; } @@ -3596,10 +3596,10 @@ PMI_FEEDBACK: } - stop_meas(&UE->phy_proc_rx); + stop_meas(&UE->phy_proc_rx[subframe&0x1]); - if (ret <= UE->dlsch[0][0]->max_turbo_iterations) { + if (ret <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) { avg_iter += ret; iter_trials++; @@ -3607,15 +3607,15 @@ PMI_FEEDBACK: if (n_frames==1) printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; - if (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* - for (round = 0 ; round < UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->round ; round++) { + for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { // re-encoding of first stream - dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = LARGE_CDD; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; @@ -3627,13 +3627,13 @@ PMI_FEEDBACK: dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - UE->dlsch[eNB_id]->active = UE->dlsch[eNB_id][0]->active; - UE->dlsch[eNB_id]->rnti = UE->dlsch[eNB_id][0]->rnti; + UE->dlsch[subframe&0x1][eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; + UE->dlsch[subframe&0x1][eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; - dlsch_encoding(UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b, + dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, - UE->dlsch[0], + UE->dlsch[subframe&0x1][0], 0,subframe, &UE->dlsch_rate_matching_stats, &UE->dlsch_turbo_encoding_stats, @@ -3660,18 +3660,18 @@ PMI_FEEDBACK: //if ((n_frames==1) || (SNR>=30)) printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); - for (s=0; sdlsch[0][0]->harq_processes[0]->C; s++) { - if (sdlsch[0][0]->harq_processes[0]->Cminus) - Kr = UE->dlsch[0][0]->harq_processes[0]->Kminus; + for (s=0; sdlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) { + if (sdlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[0][0]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0; idlsch[0][0]->harq_processes[0]->c[s][i],UE->dlsch[0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -3726,7 +3726,7 @@ PMI_FEEDBACK: write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - write_output("dlsch_w.m","w",UE->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); */ if (round == 3) exit(-1); @@ -3735,7 +3735,7 @@ PMI_FEEDBACK: // printf("round %d errors %d/%d\n",round,errs[round],trials); round++; - // UE->dlsch[0][0]->harq_processes[0]->round++; + // UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++; } if (xforms==1) { @@ -3775,7 +3775,7 @@ PMI_FEEDBACK: double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx = (double)UE->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; + double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0; double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; @@ -3925,7 +3925,7 @@ PMI_FEEDBACK: rate*effective_rate, 100*effective_rate, rate, - rate*get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs), + rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -3964,10 +3964,10 @@ PMI_FEEDBACK: eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials); printf("\n\nUE RX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_rx = sqrt((double)UE->phy_proc_rx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_rx.trials - pow((double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx.diff/UE->phy_proc_rx.trials/cpu_freq_GHz/1000.0, - UE->phy_proc_rx.trials*2/3); + std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2)); + printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0, + UE->phy_proc_rx[subframe&0x1].trials*2/3); printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, @@ -4001,7 +4001,7 @@ PMI_FEEDBACK: printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[0][0]->harq_processes[0]->Cminus ? UE->dlsch[0][0]->harq_processes[0]->Kminus : UE->dlsch[0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -4179,7 +4179,7 @@ PMI_FEEDBACK: eNB->dlsch_modulation_stats.trials, eNB->dlsch_scrambling_stats.trials, eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx.trials, + UE->phy_proc_rx[subframe&0x1].trials, UE->ofdm_demod_stats.trials, UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, @@ -4192,7 +4192,7 @@ PMI_FEEDBACK: get_time_meas_us(&eNB->dlsch_modulation_stats), get_time_meas_us(&eNB->dlsch_scrambling_stats), get_time_meas_us(&eNB->dlsch_encoding_stats), - get_time_meas_us(&UE->phy_proc_rx), + get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]), nsymb*get_time_meas_us(&UE->ofdm_demod_stats), get_time_meas_us(&UE->dlsch_rx_pdcch_stats), 3*get_time_meas_us(&UE->dlsch_llr_stats), @@ -4232,7 +4232,7 @@ PMI_FEEDBACK: eNB->dlsch_modulation_stats.trials, eNB->dlsch_scrambling_stats.trials, eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx.trials, + UE->phy_proc_rx[subframe&0x1].trials, UE->ofdm_demod_stats.trials, UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, @@ -4290,7 +4290,7 @@ PMI_FEEDBACK: printf("eNB %d\n",i); free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[0][i]); + free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); } From 0e78513b5a32bd55a441bcb06fd0cb4f07d6f897 Mon Sep 17 00:00:00 2001 From: fnabet Date: Mon, 13 Mar 2017 12:27:09 +0100 Subject: [PATCH 384/571] RLC AM Tx Segment : missing data_ptr setting --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 314bdc56c1..c4a5ca9ce3 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -314,9 +314,9 @@ mem_block_t* rlc_am_retransmit_get_am_segment( retx_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; retx_so_stop = pdu_mngt->hole_so_stop[pdu_mngt->retx_hole_index]; - AssertFatal (retx_so_start <= retx_so_stop, - "RLC AM Tx PDU Segment Data SO Error: retx_so_start=%d retx_so_stop=%d sn=%d LcId=%d!\n", - retx_so_start,retx_so_stop,sn,rlc_pP->channel_id); + AssertFatal ((retx_so_start <= retx_so_stop) && (retx_so_stop - retx_so_start + 1 < pdu_mngt->payload_size), + "RLC AM Tx PDU Segment Data SO Error: retx_so_start=%d retx_so_stop=%d OriginalPDUDataLength=%d sn=%d LcId=%d!\n", + retx_so_start,retx_so_stop,pdu_mngt->payload_size,sn,rlc_pP->channel_id); /* Init FI to the same value as original PDU */ fi_start = (!(RLC_AM_PDU_GET_FI_START(*(pdu_mngt->first_byte)))); @@ -333,12 +333,10 @@ mem_block_t* rlc_am_retransmit_get_am_segment( *payload_sizeP = retx_so_stop - retx_so_start + 1; - AssertFatal (retx_so_stop <= pdu_mngt->payload_size - 1, - "RLC AM Tx PDU Segment Data Error noLI: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d sn=%d LcId=%d !\n", - retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,sn,rlc_pP->channel_id); - mem_pdu_segment_p = get_free_mem_block((*payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + sizeof(struct mac_tb_req)), __func__); - pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; + pdu_segment_header_p = (uint8_t *)&mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; + ((struct mac_tb_req*)(mem_pdu_segment_p->data))->data_ptr = pdu_segment_header_p; + ((struct mac_tb_req*)(mem_pdu_segment_p->data))->tb_size = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + *payload_sizeP; /* clear all PDU segment */ memset(pdu_segment_header_p, 0, *payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE); @@ -545,7 +543,9 @@ mem_block_t* rlc_am_retransmit_get_am_segment( AssertFatal (header_segment_length + *payload_sizeP <= pdu_mngt->header_and_payload_size + 2, "RLC AM PDU Segment Error: Hdr=%d Data=%d Original Hdr+Data =%d sn=%d LcId=%d !\n", header_segment_length,*payload_sizeP,pdu_mngt->header_and_payload_size,sn,rlc_pP->channel_id); mem_pdu_segment_p = get_free_mem_block((*payload_sizeP + header_segment_length + sizeof(struct mac_tb_req)), __func__); - pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; + pdu_segment_header_p = (uint8_t *)&mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; + ((struct mac_tb_req*)(mem_pdu_segment_p->data))->data_ptr = pdu_segment_header_p; + ((struct mac_tb_req*)(mem_pdu_segment_p->data))->tb_size = header_segment_length + *payload_sizeP; /* clear all PDU segment */ memset(pdu_segment_header_p, 0, *payload_sizeP + header_segment_length); @@ -581,9 +581,6 @@ mem_block_t* rlc_am_retransmit_get_am_segment( pdu_mngt->nack_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; } - /* Set Fixed part of AM PDU Segment Header */ - pdu_segment_header_p = &mem_pdu_segment_p->data[sizeof(struct mac_tb_req)]; - /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ RLC_AM_PDU_SET_D_C(*pdu_segment_header_p); RLC_AM_PDU_SET_RF(*pdu_segment_header_p); @@ -645,7 +642,12 @@ mem_block_t* rlc_am_retransmit_get_am_segment( index ++; } } - + } + else + { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RE-SEGMENT] OUT OF MEMORY PDU SN %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + sn); } return mem_pdu_segment_p; From a500b2b29348ca3cbe9645e69bdf3f5c88941010 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 13 Mar 2017 15:43:43 +0100 Subject: [PATCH 385/571] integration fix: fix compilation of ulsim We use the odd/even dlsch corresponding to the configured subframe. It may not be the right thing to do. --- openair1/SIMULATION/LTE_PHY/ulsim.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 55c6b8387e..470cfc3f87 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -681,20 +681,20 @@ int main(int argc, char **argv) // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms); - UE->dlsch[0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&1][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); if (!eNB->dlsch[0][i]) { printf("Can't get eNB dlsch structures\n"); exit(-1); } - if (!UE->dlsch[0][i]) { + if (!UE->dlsch[subframe&1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } eNB->dlsch[0][i]->rnti = 14; - UE->dlsch[0][i]->rnti = 14; + UE->dlsch[subframe&1][0][i]->rnti = 14; } @@ -735,7 +735,7 @@ int main(int argc, char **argv) init_ul_hopping(&eNB->frame_parms); - UE->dlsch[0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; + UE->dlsch[subframe&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; From bd4898222fa0820cf5041517f6fc4375e513737d Mon Sep 17 00:00:00 2001 From: hbilel Date: Mon, 13 Mar 2017 15:50:10 +0100 Subject: [PATCH 386/571] pdcch dual buffer --- openair1/PHY/INIT/lte_init.c | 69 ++++-- openair1/PHY/LTE_TRANSPORT/dci.c | 70 +++--- openair1/PHY/LTE_TRANSPORT/dci.h | 6 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 19 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 4 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 9 +- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 11 +- openair1/PHY/LTE_TRANSPORT/phich.c | 10 +- openair1/PHY/LTE_TRANSPORT/print_stats.c | 2 +- openair1/PHY/LTE_TRANSPORT/proto.h | 6 +- openair1/PHY/LTE_TRANSPORT/pucch.c | 2 +- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 10 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 2 +- openair1/PHY/TOOLS/lte_phy_scope.c | 10 +- openair1/PHY/TOOLS/lte_phy_scope_tm4.c | 8 +- openair1/PHY/defs.h | 2 +- openair1/SCHED/phy_procedures_lte_ue.c | 217 ++++++++++-------- .../SIMULATION/ETH_TRANSPORT/emu_transport.c | 3 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 18 +- openair1/SIMULATION/LTE_PHY/pdcchsim.c | 14 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 2 +- openair3/NAS/TOOLS/network.h | 2 +- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 8 +- openair3/NAS/UE/ESM/esm_ebr_context.c | 2 +- targets/RT/USER/lte-softmodem.c | 10 +- targets/SIMU/USER/channel_sim.c | 2 +- targets/SIMU/USER/init_lte.c | 34 +-- targets/SIMU/USER/oaisim_functions.c | 2 +- 28 files changed, 324 insertions(+), 230 deletions(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index de83506bb3..d2a814c175 100755 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -614,8 +614,12 @@ void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobility // RNTI - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); + + LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); } if(ho_failed) { @@ -835,7 +839,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, if (physicalConfigDedicated->antennaInfo) { phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); - LOG_D(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); + LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { case AntennaInfoDedicated__transmissionMode_tm1: phy_vars_ue->transmission_mode[eNB_id] = 1; @@ -856,7 +860,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->transmission_mode[eNB_id] = 6; break; case AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[eNB_id]->crnti); + lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); phy_vars_ue->transmission_mode[eNB_id] = 7; break; default: @@ -952,6 +956,14 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, LOG_I(PHY,"Disabling SIB MIB decoding \n"); phy_vars_ue->decode_SIB = 0; phy_vars_ue->decode_MIB = 0; + //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) + phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; + else + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + + LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); } @@ -1075,7 +1087,8 @@ int phy_init_lte_ue(PHY_VARS_UE *ue, LTE_UE_PDSCH** const pdsch_vars_ra = ue->pdsch_vars_ra; LTE_UE_PDSCH** const pdsch_vars_mch = ue->pdsch_vars_MCH; LTE_UE_PBCH** const pbch_vars = ue->pbch_vars; - LTE_UE_PDCCH** const pdcch_vars = ue->pdcch_vars; + LTE_UE_PDCCH** const pdcch_vars_th0 = ue->pdcch_vars[0]; + LTE_UE_PDCCH** const pdcch_vars_th1 = ue->pdcch_vars[1]; LTE_UE_PRACH** const prach_vars = ue->prach_vars; int i,j,k,l; @@ -1157,7 +1170,8 @@ int phy_init_lte_ue(PHY_VARS_UE *ue, pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); pdsch_vars_ra[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); pdsch_vars_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); - pdcch_vars[eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH)); + pdcch_vars_th0[eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH)); + pdcch_vars_th1[eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH)); prach_vars[eNB_id] = (LTE_UE_PRACH *)malloc16_clear(sizeof(LTE_UE_PRACH)); pbch_vars[eNB_id] = (LTE_UE_PBCH *)malloc16_clear(sizeof(LTE_UE_PBCH)); @@ -1233,29 +1247,46 @@ int phy_init_lte_ue(PHY_VARS_UE *ue, phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE - pdcch_vars[eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - pdcch_vars[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - pdcch_vars[eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - pdcch_vars[eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); + pdcch_vars_th0[eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + pdcch_vars_th0[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + pdcch_vars_th0[eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + pdcch_vars_th0[eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); - pdcch_vars[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdcch_vars[eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdcch_vars[eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - pdcch_vars[eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdcch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdcch_vars_th0[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdcch_vars_th0[eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdcch_vars_th0[eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + pdcch_vars_th0[eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdcch_vars_th0[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + + pdcch_vars_th1[eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + pdcch_vars_th1[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + pdcch_vars_th1[eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + pdcch_vars_th1[eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); + + pdcch_vars_th1[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdcch_vars_th1[eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdcch_vars_th1[eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); + pdcch_vars_th1[eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdcch_vars_th1[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); for (i=0; inb_antennas_rx; i++) { //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); - pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); + pdcch_vars_th0[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); + pdcch_vars_th1[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++) int idx = (j<<1)+i; // size_t num = 7*2*fp->N_RB_DL*12; size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB - pdcch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdcch_vars[eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdcch_vars[eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdcch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdcch_vars_th0[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdcch_vars_th0[eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdcch_vars_th0[eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdcch_vars_th0[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + + pdcch_vars_th1[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdcch_vars_th1[eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdcch_vars_th1[eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdcch_vars_th1[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); } } diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index af25e33ff7..df4146adec 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -1682,9 +1682,7 @@ void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, int32_t avgP[4]; -int32_t rx_pdcch(LTE_UE_COMMON *common_vars, - LTE_UE_PDCCH **pdcch_vars, - LTE_DL_FRAME_PARMS *frame_parms, +int32_t rx_pdcch(PHY_VARS_UE *ue, uint32_t frame, uint8_t subframe, uint8_t eNB_id, @@ -1693,6 +1691,10 @@ int32_t rx_pdcch(LTE_UE_COMMON *common_vars, uint8_t is_secondary_ue) { + LTE_UE_COMMON *common_vars = &ue->common_vars; + LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[subframe & 0x1]; + uint8_t log2_maxh,aatx,aarx; #ifdef MU_RECEIVER uint8_t eNB_id_i=eNB_id+1;//add 1 to eNB_id to separate from wanted signal, chosen as the B/F'd pilots from the SeNB are shifted by 1 @@ -1701,7 +1703,7 @@ int32_t rx_pdcch(LTE_UE_COMMON *common_vars, uint8_t n_pdcch_symbols = 3; //pdcch_vars[eNB_id]->num_pdcch_symbols; uint8_t mi = get_mi(frame_parms,subframe); - // printf("In rx_pdcch, subframe %d, eNB_id %d\n",subframe,eNB_id); + //printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d \n",subframe,eNB_id,pdcch_vars); for (s=0; s3) n_pdcch_symbols=1; #ifdef DEBUG_DCI_DECODING - printf("[PDCCH] subframe %d n_pdcch_symbols from PCFICH =%d\n",subframe,n_pdcch_symbols); printf("demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config); #endif @@ -2503,7 +2505,7 @@ void dci_decoding(uint8_t DCI_LENGTH, } -static uint8_t dci_decoded_output[(MAX_DCI_SIZE_BITS+64)/8]; +static uint8_t dci_decoded_output[2][(MAX_DCI_SIZE_BITS+64)/8]; uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi) { @@ -2795,21 +2797,23 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, #ifdef DEBUG_DCI_DECODING if (do_common == 1) - LOG_I(PHY,"[DCI search - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); + LOG_I(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", + pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); else - LOG_I(PHY,"[DCI search - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); + LOG_I(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", + pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); #endif dci_decoding(sizeof_bits, L, &pdcch_vars[eNB_id]->e_rx[CCEind*72], - dci_decoded_output); + &dci_decoded_output[subframe&0x1][0]); /* for (i=0;i<3+(sizeof_bits>>3);i++) printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]); */ - crc = (crc16(dci_decoded_output,sizeof_bits)>>16) ^ extract_crc(dci_decoded_output,sizeof_bits); + crc = (crc16(&dci_decoded_output[subframe&0x1][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[subframe&0x1][0],sizeof_bits); #ifdef DEBUG_DCI_DECODING printf("crc =>%x\n",crc); #endif @@ -2823,27 +2827,31 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, dci_alloc[*dci_cnt].L = L; dci_alloc[*dci_cnt].firstCCE = CCEind; + //printf("DCI FOUND !!! crc =>%x, sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes); if (sizeof_bytes<=4) { - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[0]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[1]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[2]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[3]; + dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[subframe&0x1][0]; + dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe&0x1][1]; + dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe&0x1][2]; + dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe&0x1][3]; #ifdef DEBUG_DCI_DECODING - printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3]); + printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[subframe&0x1][0], + dci_decoded_output[subframe&0x1][1], + dci_decoded_output[subframe&0x1][2], + dci_decoded_output[subframe&0x1][3]); #endif } else { - dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[0]; - dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[1]; - dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[2]; - dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[3]; - dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[4]; - dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[5]; - dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[6]; - dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[7]; + dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[subframe&0x1][0]; + dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[subframe&0x1][1]; + dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[subframe&0x1][2]; + dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[subframe&0x1][3]; + dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[subframe&0x1][4]; + dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe&0x1][5]; + dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe&0x1][6]; + dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe&0x1][7]; #ifdef DEBUG_DCI_DECODING printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", - dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3], - dci_decoded_output[4],dci_decoded_output[5],dci_decoded_output[6],dci_decoded_output[7]); + dci_decoded_output[subframe&0x1][0],dci_decoded_output[subframe&0x1][1],dci_decoded_output[subframe&0x1][2],dci_decoded_output[subframe&0x1][3], + dci_decoded_output[subframe&0x1][4],dci_decoded_output[subframe&0x1][5],dci_decoded_output[subframe&0x1][6],dci_decoded_output[subframe&0x1][7]); #endif } @@ -2860,7 +2868,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, *dci_cnt = *dci_cnt+1; } else if (crc==pdcch_vars[eNB_id]->crnti) { - if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[0]&0x80)==0)) {// check if pdu is format 0 or 1A + if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[subframe&0x1][0]&0x80)==0)) {// check if pdu is format 0 or 1A if (*format0_found == 0) { dci_alloc[*dci_cnt].format = format0; *format0_found = 1; @@ -2882,7 +2890,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, } } - LOG_D(PHY,"DCI decoding CRNTI [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2); + LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2); // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); @@ -2928,7 +2936,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, uint8_t dci_cnt=0,old_dci_cnt=0; uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0; - LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars; + LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[subframe & 0x1]; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; uint8_t mi = get_mi(&ue->frame_parms,subframe); uint16_t ra_rnti=99; @@ -3518,7 +3526,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, } else if (tmode == 3) { - LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1\n"); + LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); // Now check UE_SPEC format 2A_2A search spaces at aggregation 1 old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, @@ -3554,7 +3562,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); // Now check UE_SPEC format 2 search spaces at aggregation 2 - LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 2\n"); + LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 2 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, @@ -3623,7 +3631,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, //#ifdef ALL_AGGREGATION // Now check UE_SPEC format 2_2A search spaces at aggregation 8 - LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 8 \n"); + LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 8 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h index c250e7c10a..2987f026e0 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.h +++ b/openair1/PHY/LTE_TRANSPORT/dci.h @@ -1897,9 +1897,9 @@ struct DCI2A_10MHz_4A_TDD { #define sizeof_DCI2A_10MHz_4A_TDD_t 41 typedef struct DCI2A_10MHz_4A_TDD DCI2A_10MHz_4A_TDD_t; -/// DCI Format Type 2A (10 MHz, FDD, 2 Antenna Ports, 36 bits) +/// DCI Format Type 2A (10 MHz, FDD, 2 Antenna Ports, 40 bits) struct DCI2A_10MHz_2A_FDD { - uint64_t padding:28; + uint64_t padding:24; /// Redundancy version 2 uint64_t rv2:2; /// New Data Indicator 2 @@ -1923,7 +1923,7 @@ struct DCI2A_10MHz_2A_FDD { /// Resource Allocation Header uint64_t rah:1; } __attribute__ ((__packed__)); -#define sizeof_DCI2A_10MHz_2A_FDD_t 36 +#define sizeof_DCI2A_10MHz_2A_FDD_t 41 typedef struct DCI2A_10MHz_2A_FDD DCI2A_10MHz_2A_FDD_t; /// DCI Format Type 2A (10 MHz, FDD, 4 Antenna Ports, 38 bits) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index c4e379b45a..dff1181197 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5720,9 +5720,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, pdlsch1->active = 0; } -#ifdef DEBUG_HARQ +//#ifdef DEBUG_HARQ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); -#endif +//#endif // compute resource allocation if (TB0_active == 1){ @@ -5882,9 +5882,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, dlsch1_harq->Qm = (mcs2-28)<<1; } -#ifdef DEBUG_HARQ +//#ifdef DEBUG_HARQ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); -#endif +//#endif #ifdef DEBUG_HARQ if (dlsch0 != NULL && dlsch1 != NULL) @@ -6156,7 +6156,7 @@ int generate_ue_dlsch_params_from_dci(int frame, case format2A: { // extract dci infomation - //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe); + LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe); extract_dci2A_info(frame_parms->N_RB_DL, frame_type, frame_parms->nb_antenna_ports_eNB, @@ -6376,7 +6376,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } - #ifdef DEBUG_DCI +#ifdef DEBUG_DCI if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe); @@ -6384,7 +6384,7 @@ int generate_ue_dlsch_params_from_dci(int frame, printf("PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb); printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid); - printf("PDSCH dlsch0 UE: tpc %d\n",TPC); + //printf("PDSCH dlsch0 UE: tpc %d\n",TPC); printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); printf("PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); printf("PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); @@ -6393,8 +6393,7 @@ int generate_ue_dlsch_params_from_dci(int frame, printf("PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); } - - #endif +#endif #if T_TRACER if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) @@ -8077,7 +8076,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; - #ifdef DEBUG_DCI +#ifdef DEBUG_DCI printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe); printf("Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index d683decc9f..a8c9fab621 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -927,7 +927,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, case PDSCH: // TB0 dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]; harq_pid = dlsch_ue->current_harq_pid; - ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]); + ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[subframe & 0x1][(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]); DevAssert( ue_id != (uint32_t)-1 ); dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[ue_id][0]; @@ -973,7 +973,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, case PDSCH1: { // TB1 dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]; harq_pid = dlsch_ue->current_harq_pid; - int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] ); + int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[subframe & 0x1][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] ); DevAssert( UE_id != -1 ); dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch[UE_id][1]; // reset HARQ diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index a842a8a9dc..5fb11d2db6 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -56,9 +56,7 @@ int16_t dlsch_demod_shift = 0; //#define DEBUG_PHY 1 //#define DEBUG_DLSCH_DEMOD 1 -int avg[4]; -int avg_0[2]; -int avg_1[2]; + // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; @@ -110,6 +108,9 @@ int rx_pdsch(PHY_VARS_UE *ue, PHY_MEASUREMENTS *measurements = &ue->measurements; LTE_UE_DLSCH_t **dlsch; + int avg[4]; + int avg_0[2]; + int avg_1[2]; unsigned char aatx,aarx; @@ -143,7 +144,7 @@ int rx_pdsch(PHY_VARS_UE *ue, break; case PDSCH: - pdsch_vars = &ue->pdsch_vars[subframe&0x1][eNB_id]; + pdsch_vars = ue->pdsch_vars[subframe&0x1]; dlsch = ue->dlsch[subframe&0x1][eNB_id]; LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame,subframe,symbol,harq_pid, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index b08836762c..48b777fcde 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -8847,6 +8847,15 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, memcpy(ch_mag_i_256i, ch_mag_i, len*4); memcpy(rho_256i, rho, len*4); +#if 1 + qam64_qam16_avx2((short *)rxF_256i, + (short *)rxF_i_256i, + (short *)ch_mag_256i, + (short *)ch_mag_i_256i, + (short *)llr16, + (short *) rho_256i, + len); +#else qam64_qam64_avx2((int32_t *)rxF_256i, (int32_t *)rxF_i_256i, (int32_t *)ch_mag_256i, @@ -8854,7 +8863,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, (int16_t *)llr16, (int32_t *) rho_256i, len); - +#endif free16(rxF_256i, sizeof(rxF_256i)); free16(rxF_i_256i, sizeof(rxF_i_256i)); free16(ch_mag_256i, sizeof(ch_mag_256i)); diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index df789cd174..bb8c1f119d 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1067,7 +1067,7 @@ void rx_phich(PHY_VARS_UE *ue, LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars; + LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[subframe & 0x1][eNB_id]; // uint8_t HI; uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,proc->frame_rx,subframe); @@ -1368,7 +1368,7 @@ void rx_phich(PHY_VARS_UE *ue, if (HI16>0) { //NACK if (ue->ulsch_Msg3_active[eNB_id] == 1) { - LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received NAK (%d) nseq %d, ngroup %d\n", + LOG_I(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received NAK (%d) nseq %d, ngroup %d\n", ue->Mod_id,harq_pid, proc->frame_rx, subframe, @@ -1389,7 +1389,7 @@ void rx_phich(PHY_VARS_UE *ue, } } else { //#ifdef DEBUG_PHICH - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n", + LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n", ue->Mod_id,harq_pid, proc->frame_rx%1024, subframe, @@ -1436,7 +1436,7 @@ void rx_phich(PHY_VARS_UE *ue, } else { //ACK if (ue->ulsch_Msg3_active[eNB_id] == 1) { - LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", + LOG_I(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", ue->Mod_id,harq_pid, proc->frame_rx, subframe, @@ -1444,7 +1444,7 @@ void rx_phich(PHY_VARS_UE *ue, nseq_PHICH,ngroup_PHICH); } else { //#ifdef PHICH_DEBUG - LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", + LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", ue->Mod_id,harq_pid, proc->frame_rx%1024, subframe, HI16, diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c index c3e40e1e72..0bebff8c35 100644 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c @@ -59,7 +59,7 @@ int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length return 0; if ((mode == normal_txrx) || (mode == no_L2_connect)) { - len += sprintf(&buffer[len], "[UE_PROC] UE %d, RNTI %x\n",ue->Mod_id, ue->pdcch_vars[0]->crnti); + len += sprintf(&buffer[len], "[UE_PROC] UE %d, RNTI %x\n",ue->Mod_id, ue->pdcch_vars[0][0]->crnti); len += sprintf(&buffer[len],"[UE PROC] RSRP[0] %.2f dBm/RE, RSSI %.2f dBm, RSRQ[0] %.2f dB, N0 %d dBm/RE (NF %.1f dB)\n", 10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB, 10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB, diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index fe7991e343..be317712da 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1308,9 +1308,7 @@ int32_t rx_pdsch(PHY_VARS_UE *phy_vars_ue, uint8_t i_mod, uint8_t harq_pid); -int32_t rx_pdcch(LTE_UE_COMMON *lte_ue_common_vars, - LTE_UE_PDCCH **lte_ue_pdcch_vars, - LTE_DL_FRAME_PARMS *frame_parms, +int32_t rx_pdcch(PHY_VARS_UE *ue, uint32_t frame, uint8_t subframe, uint8_t eNB_id, @@ -1781,6 +1779,7 @@ uint32_t ulsch_encoding(uint8_t *a, PHY_VARS_UE *phy_vars_ue, uint8_t harq_pid, uint8_t eNB_id, + uint8_t subframe_rx, uint8_t tmode, uint8_t control_only_flag, uint8_t Nbundled); @@ -1796,6 +1795,7 @@ uint32_t ulsch_encoding(uint8_t *a, int32_t ulsch_encoding_emul(uint8_t *ulsch_buffer, PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, + uint8_t subframe_rx, uint8_t harq_pid, uint8_t control_only_flag); diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 563f83bb7f..1efad912af 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -1315,7 +1315,7 @@ int32_t rx_pucch_emul(PHY_VARS_eNB *eNB, rnti = eNB->ulsch[UE_index]->rnti; for (UE_id=0; UE_idpdcch_vars[0]->crnti) + if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe & 0x1][0]->crnti) break; } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index dbb7a16ac9..e64b959e68 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -202,6 +202,7 @@ uint32_t ulsch_encoding(uint8_t *a, PHY_VARS_UE *ue, uint8_t harq_pid, uint8_t eNB_id, + uint8_t subframe_rx, uint8_t tmode, uint8_t control_only_flag, uint8_t Nbundled) @@ -261,10 +262,10 @@ uint32_t ulsch_encoding(uint8_t *a, // fill CQI/PMI information if (ulsch->O>0) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_IN); - rnti = ue->pdcch_vars[eNB_id]->crnti; + rnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti; fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff); - LOG_D(PHY,"UE CQI\n"); + LOG_I(PHY,"ULSCH Encoding rnti %x \n", rnti); print_CQI(ulsch->o,ulsch->uci_format,0,ue->frame_parms.N_RB_DL); // save PUSCH pmi for later (transmission modes 4,5,6) @@ -961,6 +962,7 @@ uint32_t ulsch_encoding(uint8_t *a, int ulsch_encoding_emul(uint8_t *ulsch_buffer, PHY_VARS_UE *ue, uint8_t eNB_id, + uint8_t subframe_rx, uint8_t harq_pid, uint8_t control_only_flag) { @@ -969,7 +971,7 @@ int ulsch_encoding_emul(uint8_t *ulsch_buffer, LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id]; PHY_MEASUREMENTS *meas = &ue->measurements; uint8_t tmode = ue->transmission_mode[eNB_id]; - uint16_t rnti=ue->pdcch_vars[eNB_id]->crnti; + uint16_t rnti=ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti; LOG_D(PHY,"EMUL UE ulsch_encoding for eNB %d,mod_id %d, harq_pid %d rnti %x, ACK(%d,%d) \n", eNB_id,ue->Mod_id, harq_pid, rnti,ulsch->o_ACK[0],ulsch->o_ACK[1]); @@ -1003,7 +1005,7 @@ int ulsch_encoding_emul(uint8_t *ulsch_buffer, //UE_transport_info_TB_index[ue->Mod_id]+=ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; // navid: currently more than one eNB is not supported in the code UE_transport_info[ue->Mod_id][ue->CC_id].num_eNB = 1; - UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[0]->crnti; + UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[subframe_rx & 0x1][0]->crnti; UE_transport_info[ue->Mod_id][ue->CC_id].eNB_id[0] = eNB_id; UE_transport_info[ue->Mod_id][ue->CC_id].harq_pid[0] = harq_pid; UE_transport_info[ue->Mod_id][ue->CC_id].tbs[0] = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3 ; diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index bb2a5b3e22..a26f3a876b 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -2002,7 +2002,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, #endif for (UE_id=0; UE_idpdcch_vars[0]->crnti) + if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe & 0x1][0]->crnti) break; } diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 7a53346453..325e9f8215 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -525,8 +525,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } } - if (phy_vars_ue->pdcch_vars[eNB_id]!=NULL) { - num_pdcch_symbols = phy_vars_ue->pdcch_vars[eNB_id]->num_pdcch_symbols; + if (phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]!=NULL) { + num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols; } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); @@ -563,8 +563,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id]; pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; - pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[eNB_id]->llr; - pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[eNB_id]->rxdataF_comp[0]; + pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->llr; + pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0]; pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 0 // pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0 pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0]; @@ -768,4 +768,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } free(chest_t_abs); -} \ No newline at end of file +} diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index 6807f1f6f4..92a0d9f218 100755 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -467,8 +467,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, return; mcs1 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs; } - if (phy_vars_ue->pdcch_vars[eNB_id]!=NULL) { - num_pdcch_symbols = phy_vars_ue->pdcch_vars[eNB_id]->num_pdcch_symbols; + if (phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]!=NULL) { + num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols; } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { @@ -519,8 +519,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id]; pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; - pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[eNB_id]->llr; - pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[eNB_id]->rxdataF_comp[0]; + pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->llr; + pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0]; pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 0 pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[1]; // stream 1 pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0]; diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 5c1b1158ba..921d2be1fc 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -713,7 +713,7 @@ typedef struct { LTE_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; - LTE_UE_PDCCH *pdcch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; + LTE_UE_PDCCH *pdcch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; LTE_UE_DLSCH_t *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads LTE_UE_ULSCH_t *ulsch[NUMBER_OF_CONNECTED_eNB_MAX]; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 386dd8b52c..2bd4590fe0 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -95,7 +95,7 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm, ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols, proc->frame_rx, subframe, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); @@ -126,7 +126,7 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, 2, 1, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols, proc->frame_rx, subframe, 0); @@ -137,7 +137,7 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs, ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols, coded_bits_per_codeword); write_output("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1); @@ -231,7 +231,7 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even, 2, 1, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols, proc->frame_rx, subframe, 0); @@ -240,7 +240,7 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs, ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols, coded_bits_per_codeword); write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1); @@ -310,8 +310,10 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) // if contention resolution fails, go back to PRACH PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH; - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_index]->crnti_is_temporary = 0; - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_index]->crnti = 0; + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0; + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti = 0; + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0; + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti = 0; LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id); //mac_xface->macphy_exit(""); } @@ -323,7 +325,8 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id); - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[eNB_index]->crnti_is_temporary = 0; + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0; + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0; PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0; PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH; @@ -379,7 +382,7 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) int subframe=proc->subframe_tx; LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n", - ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,proc->frame_tx,subframe, + ue->Mod_id,ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti,proc->frame_tx,subframe, ue->scheduling_request_config[eNB_id].sr_ConfigIndex); if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 4) { // 5 ms SR period @@ -632,7 +635,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id CC_id, frame_tx, eNB_id, - ue->pdcch_vars[eNB_id]->crnti, + ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti, subframe_tx); // subframe used for meas gap if (SR_payload > 0) @@ -819,10 +822,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, if (frame_parms->frame_type == FDD ) { // FDD sf = (subframe<4)? subframe+6 : subframe-4; - LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[eNB_id]->nCCE[sf]); + LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[proc->subframe_rx&0x1][eNB_id]->nCCE[sf]); if (SR == 0) - return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[eNB_id]->nCCE[sf]); + return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[sf]); else return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); } else { @@ -885,7 +888,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, last_dl); // i=0 - nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[last_dl]; + nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[last_dl]; n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; harq_ack0 = b[0]; @@ -927,10 +930,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, // This is the offset for a particular subframe (2,3,4) => (0,2,4) last_dl = (subframe-2)<<1; // i=0 - nCCE0 = ue->pdcch_vars[eNB_id]->nCCE[5+last_dl]; + nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[5+last_dl]; n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; // i=1 - nCCE1 = ue->pdcch_vars[eNB_id]->nCCE[(6+last_dl)%10]; + nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(6+last_dl)%10]; n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; // set ACK/NAK to values if not DTX @@ -1425,7 +1428,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } if (isBad) { - LOG_D(PHY,"Skip PUSCH generation!\n"); + LOG_I(PHY,"Skip PUSCH generation!\n"); ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; } } @@ -1435,7 +1438,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB // deactivate service request // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); + LOG_I(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1)) { LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); @@ -1489,10 +1492,10 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } -#ifdef DEBUG_PHY_PROC - LOG_D(PHY, - "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", - Mod_id,harq_pid,frame_tx,subframe_tx, +//#ifdef DEBUG_PHY_PROC + LOG_I(PHY, + "[UE %d][PUSCH %d] AbsSubframe %d.%d %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", + Mod_id,harq_pid,frame_tx,subframe_tx,proc->subframe_rx, first_rb,nb_rb, ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs, @@ -1506,7 +1509,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, ue->ulsch[eNB_id]->bundling); -#endif +//#endif @@ -1536,6 +1539,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue, harq_pid, eNB_id, + proc->subframe_rx, ue->transmission_mode[eNB_id],0,0)!=0) { LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n"); mac_xface->macphy_exit("Error in ulsch_coding"); @@ -1548,7 +1552,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB #ifdef PHY_ABSTRACTION else { - ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,harq_pid,0); + ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,proc->subframe_rx,harq_pid,0); } #endif @@ -1608,6 +1612,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue, harq_pid, eNB_id, + proc->subframe_rx, ue->transmission_mode[eNB_id],0, Nbundled)!=0) { LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n"); @@ -1619,7 +1624,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB #ifdef PHY_ABSTRACTION else { - ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0); + ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0); } #endif @@ -1890,7 +1895,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin CC_id, frame_tx, eNB_id, - ue->pdcch_vars[eNB_id]->crnti, + ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti, subframe_tx); // subframe used for meas gap } else { @@ -2107,7 +2112,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin 0, // B2 not needed tx_amp, subframe_tx, - ue->pdcch_vars[eNB_id]->crnti); + ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti); } break; @@ -2217,6 +2222,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui ue, harq_pid, eNB_id, + proc->subframe_rx, ue->transmission_mode[eNB_id],0, 0)!=0) { // Nbundled, to be updated!!!! LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n"); @@ -2226,7 +2232,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui #ifdef PHY_ABSTRACTION else { - ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0); + ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->subframe_rx,harq_pid,0); } #endif @@ -2502,10 +2508,15 @@ void restart_phy(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t ab ue->pbch_vars[eNB_id]->pdu_errors_conseq=0; ue->pbch_vars[eNB_id]->pdu_errors=0; - ue->pdcch_vars[eNB_id]->dci_errors = 0; - ue->pdcch_vars[eNB_id]->dci_missed = 0; - ue->pdcch_vars[eNB_id]->dci_false = 0; - ue->pdcch_vars[eNB_id]->dci_received = 0; + ue->pdcch_vars[0][eNB_id]->dci_errors = 0; + ue->pdcch_vars[0][eNB_id]->dci_missed = 0; + ue->pdcch_vars[0][eNB_id]->dci_false = 0; + ue->pdcch_vars[0][eNB_id]->dci_received = 0; + + ue->pdcch_vars[1][eNB_id]->dci_errors = 0; + ue->pdcch_vars[1][eNB_id]->dci_missed = 0; + ue->pdcch_vars[1][eNB_id]->dci_false = 0; + ue->pdcch_vars[1][eNB_id]->dci_received = 0; ue->dlsch_errors[eNB_id] = 0; ue->dlsch_errors_last[eNB_id] = 0; @@ -2753,9 +2764,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint if (abstraction_flag == 0) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN); - rx_pdcch(&ue->common_vars, - ue->pdcch_vars, - &ue->frame_parms, + rx_pdcch(ue, proc->frame_rx, subframe_rx, eNB_id, @@ -2801,14 +2810,14 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint } LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n"); - dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars, + dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars[subframe_rx&1], PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[subframe_rx&1], PHY_vars_eNB_g[i][CC_id]->num_common_dci[subframe_rx&1], PHY_vars_eNB_g[i][CC_id]->dci_alloc[subframe_rx&1], dci_alloc_rx, eNB_id); // printf("DCI: dci_cnt %d\n",dci_cnt); - UE_id = (uint32_t)find_ue((int16_t)ue->pdcch_vars[eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]); + UE_id = (uint32_t)find_ue((int16_t)ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]); if (UE_id>=0) { // printf("Checking PHICH for UE %d (eNB %d)\n",UE_id,i); @@ -2831,9 +2840,14 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #endif - LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt); + LOG_I(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n", + ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]], + dci_cnt, + dci_alloc_rx[0].rnti, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, + dci_alloc_rx[0].format ); - ue->pdcch_vars[eNB_id]->dci_received += dci_cnt; + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->dci_received += dci_cnt; #ifdef EMOS //emos_dump_UE.dci_cnt[subframe_rx] = dci_cnt; @@ -2844,7 +2858,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint if ((ue->UE_mode[eNB_id]>PRACH) && - (dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) && + (dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti) && (dci_alloc_rx[i].format != format0)) { @@ -2852,8 +2866,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint ue->Mod_id,dci_alloc_rx[i].rnti, frame_rx%1024,subframe_rx, dci_alloc_rx[i].format, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, - ue->pdcch_vars[eNB_id]->nCCE[subframe_rx], + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->nCCE[subframe_rx], get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0))); @@ -2865,7 +2879,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (generate_ue_dlsch_params_from_dci(frame_rx, subframe_rx, (void *)&dci_alloc_rx[i].dci_pdu, - ue->pdcch_vars[eNB_id]->crnti, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, dci_alloc_rx[i].format, ue->dlsch[subframe_rx&0x1][eNB_id], &ue->frame_parms, @@ -2874,7 +2888,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint 0, P_RNTI, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], - ue->pdcch_vars[eNB_id]->crnti_is_temporary? ue->pdcch_vars[eNB_id]->crnti: 0)==0)) { + ue->pdcch_vars[0&0x1][eNB_id]->crnti_is_temporary? ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti: 0)==0)) { // update TPC for PUCCH if((dci_alloc_rx[i].format == format1) || @@ -2898,7 +2912,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint // we received a CRNTI, so we're in PUSCH if (ue->UE_mode[eNB_id] != PUSCH) { #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[eNB_id]->crnti); + LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti); #endif //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); ue->UE_mode[eNB_id] = PUSCH; @@ -3006,7 +3020,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]); #endif } - } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) && + } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti) && (dci_alloc_rx[i].format == format0)) { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n", @@ -3018,7 +3032,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint if ((ue->UE_mode[eNB_id] > PRACH) && (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu, - ue->pdcch_vars[eNB_id]->crnti, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, subframe_rx, format0, ue, @@ -3089,7 +3103,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint else { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti, - ue->pdcch_vars[eNB_id]->crnti, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, ue->ulsch[eNB_id]->cba_rnti[0], dci_alloc_rx[i].format); // dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); @@ -3345,7 +3359,7 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo frame_rx, ue->prach_resources[eNB_id]->ra_RNTI, dlsch0->harq_processes[0]->b, - &ue->pdcch_vars[eNB_id]->crnti, + &ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, ue->prach_resources[eNB_id]->ra_PreambleIndex); @@ -3355,11 +3369,11 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo ue->Mod_id, frame_rx, subframe_rx, - ue->pdcch_vars[eNB_id]->crnti, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, timing_advance); // remember this c-rnti is still a tc-rnti - ue->pdcch_vars[eNB_id]->crnti_is_temporary = 1; + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti_is_temporary = 1; //timing_advance = 0; process_timing_advance_rar(ue,proc,timing_advance); @@ -3491,7 +3505,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[harq_pid]->rb_alloc_even, dlsch0->harq_processes[harq_pid]->Qm, dlsch0->harq_processes[harq_pid]->Nl, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, frame_rx, subframe_rx, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); @@ -3504,13 +3518,17 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, 0, subframe_rx<<1); stop_meas(&ue->dlsch_unscrambling_stats); - - //LOG_I(PHY,"start turbo decode for CW 0 --> nb_rb %d \n", dlsch0->harq_processes[harq_pid]->nb_rb); - //LOG_I(PHY,"start turbo decode for CW 0 --> rb_alloc_even %x \n", dlsch0->harq_processes[harq_pid]->rb_alloc_even); - //LOG_I(PHY,"start turbo decode for CW 0 --> Qm %d \n", dlsch0->harq_processes[harq_pid]->Qm); - //LOG_I(PHY,"start turbo decode for CW 0 --> Nl %d \n", dlsch0->harq_processes[harq_pid]->Nl); - //LOG_I(PHY,"start turbo decode for CW 0 --> G %d \n", dlsch0->harq_processes[harq_pid]->G); - //LOG_I(PHY,"start turbo decode for CW 0 --> Kmimo %d \n", dlsch0->Kmimo); + +#if 0 + LOG_I(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, subframe_rx, harq_pid); + LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); + LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even); + LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); + LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); + LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); + LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo); + LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols); +#endif start_meas(&ue->dlsch_decoding_stats); ret = dlsch_decoding(ue, @@ -3525,10 +3543,10 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); stop_meas(&ue->dlsch_decoding_stats); - //printf(" --> Unscrambling for CW0 %5.3f\n", - // (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - //printf(" --> Turbo Decoding for CW0 %5.3f\n", - // (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + printf(" --> Unscrambling for CW0 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + printf(" --> Turbo Decoding for CW0 %5.3f\n", + (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); if(is_cw1_active) { @@ -3538,7 +3556,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch1->harq_processes[harq_pid]->rb_alloc_even, dlsch1->harq_processes[harq_pid]->Qm, dlsch1->harq_processes[harq_pid]->Nl, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, frame_rx, subframe_rx, ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); @@ -3553,13 +3571,15 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, subframe_rx<<1); stop_meas(&ue->dlsch_unscrambling_stats); - //LOG_I(PHY,"start turbo decode for CW 1 --> nb_rb %d \n", dlsch1->harq_processes[harq_pid]->nb_rb); - //LOG_I(PHY,"start turbo decode for CW 1 --> rb_alloc_even %x \n", dlsch1->harq_processes[harq_pid]->rb_alloc_even); - //LOG_I(PHY,"start turbo decode for CW 1 --> Qm %d \n", dlsch1->harq_processes[harq_pid]->Qm); - //LOG_I(PHY,"start turbo decode for CW 1 --> Nl %d \n", dlsch1->harq_processes[harq_pid]->Nl); - //LOG_I(PHY,"start turbo decode for CW 1 --> G %d \n", dlsch1->harq_processes[harq_pid]->G); - //LOG_I(PHY,"start turbo decode for CW 1 --> Kmimo %d \n", dlsch1->Kmimo); - +#if 0 + LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); + LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even); + LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm); + LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); + LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); + LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo); + LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols); +#endif start_meas(&ue->dlsch_decoding_stats); ret1 = dlsch_decoding(ue, pdsch_vars->llr[1], @@ -3573,11 +3593,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch1->harq_processes[harq_pid]->TBS>256?1:0); stop_meas(&ue->dlsch_decoding_stats); - //printf(" --> Unscrambling for CW1 %5.3f\n", - // (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - //printf(" --> Turbo Decoding for CW1 %5.3f\n", - // (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + printf(" --> Unscrambling for CW1 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + printf(" --> Turbo Decoding for CW1 %5.3f\n", + (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); } + + LOG_I(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ \n", frame_rx, subframe_rx); } else { @@ -3596,7 +3618,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(dlsch0->rnti != 0xffff) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3608,7 +3630,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, } else { if(dlsch0->rnti != 0xffff) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3677,7 +3699,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(is_cw1_active) { if (ret1 == (1+dlsch0->max_turbo_iterations)) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3685,7 +3707,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[harq_pid]->TBS); } else { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", + LOG_I(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3765,6 +3787,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->frame_parms.samples_per_tti * 4)); // start timers + + LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); start_meas(&ue->phy_proc_rx[subframe_rx&0x1]); start_meas(&ue->generic_stat); @@ -3818,6 +3842,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ l=1; } + + LOG_I(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_I(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); for (; l<=l2; l++) { if (abstraction_flag == 0) { start_meas(&ue->ofdm_demod_stats); @@ -3841,12 +3868,13 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); return(-1); } - LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[eNB_id]->num_pdcch_symbols); + LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols); } } // for l=1..l2 ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); + LOG_I(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); // If this is PMCH, call procedures and return if (pmch_flag == 1) { ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag); @@ -3862,8 +3890,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) stop_meas(&ue->generic_stat); - //printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_I(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); start_meas(&ue->generic_stat); // do procedures for C-RNTI if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { @@ -3874,11 +3903,13 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin PDSCH, ue->dlsch[subframe_rx&0x1][eNB_id][0], NULL, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, ue->frame_parms.symbols_per_tti>>1, abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } + + LOG_I(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); @@ -3888,7 +3919,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin SI_PDSCH, ue->dlsch_SI[eNB_id], NULL, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, ue->frame_parms.symbols_per_tti>>1, abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); @@ -3903,7 +3934,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin P_PDSCH, ue->dlsch_p[eNB_id], NULL, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, ue->frame_parms.symbols_per_tti>>1, abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); @@ -3918,12 +3949,15 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin RA_PDSCH, ue->dlsch_ra[eNB_id], NULL, - ue->pdcch_vars[eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, ue->frame_parms.symbols_per_tti>>1, abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } + LOG_I(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_I(PHY," ------ --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) { // do front-end processing for second slot, and first symbol of next subframe for (l=1; lframe_parms.symbols_per_tti>>1; l++) { if (abstraction_flag == 0) { @@ -3957,15 +3991,16 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } // not an S-subframe stop_meas(&ue->generic_stat); - //printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); - // run pbch procedures if subframe is 0 + LOG_I(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) { ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); } // do procedures for C-RNTI + LOG_I(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); start_meas(&ue->pdsch_procedures_stat); @@ -3979,7 +4014,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->frame_parms.symbols_per_tti-1, abstraction_flag); stop_meas(&ue->pdsch_procedures_stat); + LOG_I(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_I(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); start_meas(&ue->dlsch_procedures_stat); ue_dlsch_procedures(ue, proc, @@ -3991,15 +4028,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin mode, abstraction_flag); stop_meas(&ue->dlsch_procedures_stat); - //printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0)); - //printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } start_meas(&ue->generic_stat); - // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { ue_pdsch_procedures(ue, @@ -4105,8 +4141,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]); - //printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0)); + printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0)); + LOG_I(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); return (0); } diff --git a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c index 6d3d4cabb3..76b72e321f 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/emu_transport.c @@ -488,7 +488,8 @@ void fill_phy_ue_vars(unsigned int ue_id, uint8_t CC_id,unsigned int last_slot) rnti = UE_transport_info[ue_id][CC_id].rnti[n_enb]; enb_id = UE_transport_info[ue_id][CC_id].eNB_id[n_enb]; - PHY_vars_UE_g[ue_id][CC_id]->pdcch_vars[enb_id]->crnti=rnti; + PHY_vars_UE_g[ue_id][CC_id]->pdcch_vars[0][enb_id]->crnti=rnti; + PHY_vars_UE_g[ue_id][CC_id]->pdcch_vars[1][enb_id]->crnti=rnti; harq_pid = UE_transport_info[ue_id][CC_id].harq_pid[n_enb]; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index ddc108a7c8..ac26a9259c 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1991,7 +1991,7 @@ int main(int argc, char **argv) } */ - UE->pdcch_vars[0]->crnti = n_rnti; + UE->pdcch_vars[0][0]->crnti = n_rnti; // Fill in UL_alloc UL_alloc_pdu.type = 0; @@ -2548,11 +2548,11 @@ int main(int argc, char **argv) write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); //pdcch_vars - write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4); + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); } @@ -2652,11 +2652,11 @@ int main(int argc, char **argv) //write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); //write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); //pdcch_vars - write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4); + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); if (round == 3) exit(-1); } diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index 1ba79bdb0a..ebc178a55e 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -1085,11 +1085,11 @@ int main(int argc, char **argv) // write_output("H00.m","h00",&(UE->common_vars.dl_ch_estimates[0][0][0]),((frame_parms->Ncp==0)?7:6)*(eNB->frame_parms.ofdm_symbol_size),1,1); // do PDCCH procedures here - UE->pdcch_vars[0]->crnti = n_rnti; + UE->pdcch_vars[0][0]->crnti = n_rnti; // printf("Doing RX : num_pdcch_symbols at TX %d\n",num_pdcch_symbols); rx_pdcch(&UE->common_vars, - UE->pdcch_vars, + UE->pdcch_vars[0], &UE->frame_parms, trial, subframe, @@ -1118,7 +1118,7 @@ int main(int argc, char **argv) dl_rx=0; if (n_frames==1) { - numCCE = get_nCCE(UE->pdcch_vars[0]->num_pdcch_symbols, &UE->frame_parms, get_mi(&UE->frame_parms,subframe)); + numCCE = get_nCCE(UE->pdcch_vars[0][0]->num_pdcch_symbols, &UE->frame_parms, get_mi(&UE->frame_parms,subframe)); for (i = 0; i < dci_cnt; i++) printf("dci %d: rnti 0x%x, format %d, L %d, nCCE %d/%d dci_length %d\n",i, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, @@ -1167,7 +1167,7 @@ int main(int argc, char **argv) // exit(-1); } - if (UE->pdcch_vars[0]->num_pdcch_symbols != num_pdcch_symbols) + if (UE->pdcch_vars[0][0]->num_pdcch_symbols != num_pdcch_symbols) n_errors_cfi++; /* @@ -1224,9 +1224,9 @@ int main(int argc, char **argv) if (n_tx==2) write_output("H10.m","h10",&(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2][0]),((frame_parms->Ncp==0)?7:6)*(eNB->frame_parms.ofdm_symbol_size),1,1); - write_output("pdcch_rxF_ext0.m","pdcch_rxF_ext0",UE->pdcch_vars[eNb_id]->rxdataF_ext[0],3*12*UE->frame_parms.N_RB_DL,1,1); - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNb_id]->rxdataF_comp[0],4*12*UE->frame_parms.N_RB_DL,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNb_id]->llr,2400,1,4); + write_output("pdcch_rxF_ext0.m","pdcch_rxF_ext0",UE->pdcch_vars[0][eNb_id]->rxdataF_ext[0],3*12*UE->frame_parms.N_RB_DL,1,1); + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNb_id]->rxdataF_comp[0],4*12*UE->frame_parms.N_RB_DL,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNb_id]->llr,2400,1,4); } lte_sync_time_free(); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 55c6b8387e..a2f9f1a484 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -630,7 +630,7 @@ int main(int argc, char **argv) fl_show_form (form_enb->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); } - UE->pdcch_vars[0]->crnti = 14; + UE->pdcch_vars[0][0]->crnti = 14; UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7; diff --git a/openair3/NAS/TOOLS/network.h b/openair3/NAS/TOOLS/network.h index 0d60359c57..d7044c8e51 100644 --- a/openair3/NAS/TOOLS/network.h +++ b/openair3/NAS/TOOLS/network.h @@ -61,7 +61,7 @@ Description Defines a list of PLMN network operators #define VDF5 11 -#define SELECTED_PLMN OAI_LTEBOX //SFR1 +#define SELECTED_PLMN TEST1 //SFR1 #define TEST_PLMN {0,0,0x0f,1,1,0} // 00101 #define SFR_PLMN_1 {0,2,0x0f,8,0,1} // 20810 diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index 84ec59a36b..05db6be4d1 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -86,14 +86,14 @@ UE0: }; SIM: { - MSIN="0100001111"; - USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; + MSIN="000001234"; + USIM_API_K="000102030405060708090A0B0C0D0E0F"; OPC="C42449363BBAD02B66D16BC975D77CC1"; - MSISDN="33611123456"; + MSISDN="000000000000";//"33611123456"; }; # Home PLMN Selector with Access Technology - HPLMN= "20893"; + HPLMN= "00101"; # User controlled PLMN Selector with Access Technology UCPLMN_LIST = (); diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index bfa4a04cc8..31f215e359 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -286,7 +286,7 @@ int esm_ebr_context_create( LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); - if (system(command_line)) ; /* TODO: what to do? */ + //if (system(command_line)) ; /* TODO: what to do? */ break; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 65f578fd25..9c4f6d07da 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1579,9 +1579,15 @@ int main( int argc, char **argv ) { UE[CC_id]->X_u); if (UE[CC_id]->mac_enabled == 1) - UE[CC_id]->pdcch_vars[0]->crnti = 0x1234; + { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234; + } else - UE[CC_id]->pdcch_vars[0]->crnti = 0x1235; + { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235; + } UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index aff1f789ee..3913de6016 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -145,7 +145,7 @@ void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_N // find out which eNB the UE is attached to for (eNB_id=0; eNB_idpdcch_vars[0]->crnti,PHY_vars_eNB_g[eNB_id][CC_id])>=0) { + if (find_ue(PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0][0]->crnti,PHY_vars_eNB_g[eNB_id][CC_id])>=0) { // UE with UE_id is connected to eNb with eNB_id att_eNB_id=eNB_id; LOG_D(OCM,"A: UE attached to eNB (UE%d->eNB%d)\n",UE_id,eNB_id); diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c index a99ccf2c09..3baf8fdad6 100644 --- a/targets/SIMU/USER/init_lte.c +++ b/targets/SIMU/USER/init_lte.c @@ -161,9 +161,9 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms, memcpy(&(PHY_vars_UE->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS)); phy_init_lte_ue(PHY_vars_UE,1,abstraction_flag); - for (int l=0; l<2; l++) { - for (i=0; idlsch[l][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); if (!PHY_vars_UE->dlsch[l][i][j]) { @@ -172,21 +172,21 @@ PHY_VARS_UE* init_lte_UE(LTE_DL_FRAME_PARMS *frame_parms, } else LOG_D(PHY,"dlsch[%d][%d] => %p\n",UE_id,i,PHY_vars_UE->dlsch[l][i][j]); } - - - - PHY_vars_UE->ulsch[i] = new_ue_ulsch(frame_parms->N_RB_UL, abstraction_flag); - - if (!PHY_vars_UE->ulsch[i]) { - LOG_E(PHY,"Can't get ue ulsch structures\n"); - exit(-1); - } - - PHY_vars_UE->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); - PHY_vars_UE->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); - - PHY_vars_UE->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2; } + + + + PHY_vars_UE->ulsch[i] = new_ue_ulsch(frame_parms->N_RB_UL, abstraction_flag); + + if (!PHY_vars_UE->ulsch[i]) { + LOG_E(PHY,"Can't get ue ulsch structures\n"); + exit(-1); + } + + PHY_vars_UE->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); + PHY_vars_UE->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,frame_parms->N_RB_DL, abstraction_flag); + + PHY_vars_UE->transmission_mode[i] = frame_parms->nb_antenna_ports_eNB==1 ? 1 : 2; } PHY_vars_UE->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index c47dc10caf..c00bb50401 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1428,7 +1428,7 @@ void init_openair1(void) else PHY_vars_UE_g[UE_id][CC_id]->mac_enabled=1; - PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0]->crnti = 0x1235 + UE_id; + PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[0][0]->crnti = 0x1235 + UE_id; PHY_vars_UE_g[UE_id][CC_id]->current_dlsch_cqi[0] = 10; LOG_I(EMU, "UE %d mode is initialized to %d\n", UE_id, PHY_vars_UE_g[UE_id][CC_id]->UE_mode[0] ); From 3a43c08ae306201e1a0ef2fff421c0f3942a9c8a Mon Sep 17 00:00:00 2001 From: fnabet Date: Mon, 13 Mar 2017 15:54:27 +0100 Subject: [PATCH 387/571] RLC AM fix RX Segment --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index cc84ef9ab5..310c66a44c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -176,7 +176,7 @@ mem_block_t * create_new_segment_from_pdu( if (new_segment_p != NULL) { pdu_new_segment_info_p = &((rlc_am_rx_pdu_management_t*)(new_segment_p->data))->pdu_info; rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (new_segment_p->data); - uint8_t *pdu_segment_header_p = &(new_segment_p->data[sizeof (mac_rlc_max_rx_header_size_t)]); + uint8_t *pdu_segment_header_p = (uint8_t *)&(new_segment_p->data[sizeof (mac_rlc_max_rx_header_size_t)]); pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO; //to be updated after if SN = vrR From dabf833c107a0bb5349bed522a59b9f9bc1dd2dd Mon Sep 17 00:00:00 2001 From: gabrielC Date: Mon, 13 Mar 2017 19:41:24 +0100 Subject: [PATCH 388/571] RLC AM Rx Segment and Tx Status Report fixes --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 13 +++++---- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 29 ++++++++++++++----- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 17 ++++++----- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index df8682f726..f7f4de1718 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -88,17 +88,18 @@ rlc_am_get_status_pdu_buffer_occupancy( if (pdu_info_cursor_p->so) { nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size; - /* Go to next segment */ - cursor_p = cursor_p->next; - if (cursor_p != NULL) - { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - } } else { waited_so = pdu_info_cursor_p->payload_size; } + /* Go to next segment */ + cursor_p = cursor_p->next; + if (cursor_p != NULL) + { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + /* Fill following gaps if any */ while (!segment_loop_end) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 310c66a44c..bb1d172451 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -464,8 +464,8 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( // remove duplicate at the begining, only valid if the segment is to be inserted after a PDU segment of the same SN if (previous_cursor_p != NULL) { pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; - if (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) { - so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - pdu_rx_info_p->so); + if ((pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) && (so_start_segment < pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size)) { + so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - so_start_segment); } } @@ -512,9 +512,16 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( else { if (previous_cursor_p != NULL) { + pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d NOT EMPTY] PDU SEGMENT INSERTED AFTER PDU SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, + pdu_info_previous_cursor_p->sn); list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); } else { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d NOT EMPTY] PDU SEGMENT INSERTED BEFORE PDU SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, + pdu_rx_info_p->sn); list2_insert_before_element(tb_pP, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer); } @@ -1330,10 +1337,19 @@ rlc_am_rx_list_reassemble_rlc_sdus( else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING) { rlc_am_rx_pdu_management_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLED; - cursor_p = list2_remove_head(&rlc_pP->receiver_buffer); rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,FALSE); rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; - cursor_p = list2_get_head(&rlc_pP->receiver_buffer); + cursor_p = cursor_p->next; + + if (cursor_p == NULL) { + return; + } + + rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); + } + else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED) { + rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; + cursor_p = cursor_p->next; if (cursor_p == NULL) { return; @@ -1354,9 +1370,8 @@ rlc_am_rx_list_reassemble_rlc_sdus( return; } - } while ((rlc_am_rx_pdu_management_p->pdu_info.sn == ((rlc_am_rx_old_pdu_management->pdu_info.sn + 1) & RLC_AM_SN_MASK)) - || ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && ( - (rlc_am_rx_pdu_management_p->all_segments_received > 0) || (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING)))); + } while (((rlc_am_rx_pdu_management_p->pdu_info.sn == ((rlc_am_rx_old_pdu_management->pdu_info.sn + 1) & RLC_AM_SN_MASK)) && (rlc_am_rx_old_pdu_management->all_segments_received > 0)) + || ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && (rlc_am_rx_pdu_management_p->segment_reassembled != RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO))); } //----------------------------------------------------------------------------- mem_block_t * diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 6d4fd0a2b7..dfa62f0351 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -620,17 +620,18 @@ rlc_am_send_status_pdu( pdu_info_cursor_p->so - 1); #endif waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size; - /* Go to next segment */ - cursor_p = cursor_p->next; - if (cursor_p != NULL) - { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - } } else { waited_so = pdu_info_cursor_p->payload_size; } + /* Go to next segment */ + cursor_p = cursor_p->next; + if (cursor_p != NULL) + { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + /* Find the first discontinuity and then fill SOStart/SOEnd */ while (!segment_loop_end) { if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) { @@ -644,7 +645,7 @@ rlc_am_send_status_pdu( if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; - control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so; + control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so - 1; control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; /* Set E1 for next NACK_SN. The last one will be cleared */ control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; @@ -732,7 +733,7 @@ rlc_am_send_status_pdu( } // End main while NACK_SN /* Clear E1 of last nack_sn entry */ - AssertFatal (control_pdu_info.num_nack, "RLC AM Tx Status PDU Data Error no NACK_SN LcId=%d\n",rlc_pP->channel_id); + AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN LcId=%d\n",rlc_pP->channel_id); control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0; /* Set ACK_SN unless it was set before */ From cf9727c4be5f69815357758a315a6af2839db08f Mon Sep 17 00:00:00 2001 From: GabrielCouturier Date: Mon, 13 Mar 2017 19:44:52 +0100 Subject: [PATCH 389/571] RLC AM fix bad assert for resegmentation --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index c4a5ca9ce3..d61dd8b6ab 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -314,7 +314,14 @@ mem_block_t* rlc_am_retransmit_get_am_segment( retx_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; retx_so_stop = pdu_mngt->hole_so_stop[pdu_mngt->retx_hole_index]; - AssertFatal ((retx_so_start <= retx_so_stop) && (retx_so_stop - retx_so_start + 1 < pdu_mngt->payload_size), + /* + if (!(retx_so_start <= retx_so_stop) && (retx_so_stop - retx_so_start + 1 <= pdu_mngt->payload_size)) + { + AssertFatal(0); + } + */ + + AssertFatal ((retx_so_start <= retx_so_stop) && (retx_so_stop - retx_so_start + 1 <= pdu_mngt->payload_size), "RLC AM Tx PDU Segment Data SO Error: retx_so_start=%d retx_so_stop=%d OriginalPDUDataLength=%d sn=%d LcId=%d!\n", retx_so_start,retx_so_stop,pdu_mngt->payload_size,sn,rlc_pP->channel_id); From c1da605f6d56e5193b2639ff56678efb745c5f71 Mon Sep 17 00:00:00 2001 From: fnabet Date: Tue, 14 Mar 2017 10:10:36 +0100 Subject: [PATCH 390/571] RLC AM code cleaning --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 7 ----- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 26 +++++++++---------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index d61dd8b6ab..27aa0b6ddf 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -314,13 +314,6 @@ mem_block_t* rlc_am_retransmit_get_am_segment( retx_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; retx_so_stop = pdu_mngt->hole_so_stop[pdu_mngt->retx_hole_index]; - /* - if (!(retx_so_start <= retx_so_stop) && (retx_so_stop - retx_so_start + 1 <= pdu_mngt->payload_size)) - { - AssertFatal(0); - } - */ - AssertFatal ((retx_so_start <= retx_so_stop) && (retx_so_stop - retx_so_start + 1 <= pdu_mngt->payload_size), "RLC AM Tx PDU Segment Data SO Error: retx_so_start=%d retx_so_stop=%d OriginalPDUDataLength=%d sn=%d LcId=%d!\n", retx_so_start,retx_so_stop,pdu_mngt->payload_size,sn,rlc_pP->channel_id); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index bb1d172451..fd84cd5e35 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -284,10 +284,9 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( rlc_am_pdu_info_t* pdu_rx_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; rlc_am_pdu_info_t* pdu_info_cursor_p = NULL; rlc_am_pdu_info_t* pdu_info_previous_cursor_p = NULL; - mem_block_t* cursor_p = NULL; + mem_block_t* cursor_p = rlc_pP->receiver_buffer.head; mem_block_t* previous_cursor_p = NULL; mem_block_t* next_cursor_p = NULL; - cursor_p = rlc_pP->receiver_buffer.head; boolean_t prev_segment_found = FALSE; boolean_t next_segment_found = FALSE; uint16_t so_start = 0; @@ -298,8 +297,9 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( /*****************************************************/ // 1) Find previous cursor to the PDU to insert /*****************************************************/ - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - while (cursor_p != NULL) { + AssertFatal(cursor_p != NULL,"AM Rx PDU Error, received buffer empty LcID=%d\n",rlc_pP->channel_id); + + do { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; // Stop if Cursor SN >= Received SN @@ -310,7 +310,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( previous_cursor_p = cursor_p; pdu_info_previous_cursor_p = pdu_info_cursor_p; cursor_p = cursor_p->next; - } + } while (cursor_p != NULL); /*****************************************************/ // 2) Store the received Segment @@ -536,9 +536,8 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( { rlc_am_pdu_info_t* pdu_rx_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; rlc_am_pdu_info_t* pdu_info_cursor_p = NULL; - mem_block_t* cursor_p = NULL; + mem_block_t* cursor_p = rlc_pP->receiver_buffer.head; mem_block_t* previous_cursor_p = NULL; - cursor_p = rlc_pP->receiver_buffer.head; rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; // it is assumed this pdu is in rx window @@ -546,9 +545,9 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( /*****************************************************/ // 1) Find previous cursor to the PDU to insert /*****************************************************/ - previous_cursor_p = cursor_p; - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - while (cursor_p != NULL) { + AssertFatal(cursor_p != NULL,"AM Rx PDU Error, received buffer empty LcID=%d\n",rlc_pP->channel_id); + + do { pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; // Stop if Cursor SN >= Received SN @@ -558,16 +557,15 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( previous_cursor_p = cursor_p; cursor_p = cursor_p->next; - } + } while (cursor_p != NULL); /*****************************************************/ // 2) Insert PDU by removing byte duplicate if required /*****************************************************/ - // First case : cursor_p is NULL, it means the SN is received for the first time + // First case : cursor_p is NULL or SN are different, it means the SN is received for the first time // Insert PDU after previous_cursor_p if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { - rlc_usn_t sn_prev = ((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info.sn; - if (RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(pdu_rx_info_p->sn,rlc_pP->vr_r)) { + if (previous_cursor_p != NULL) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SN=%d] PDU INSERTED AFTER PDU SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, ((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info.sn); From 28a50c15e9b9356ee5773e619e266551099c6fbd Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 14 Mar 2017 15:35:21 +0100 Subject: [PATCH 391/571] Remove some print and correct rnti for the pdcch_vars odd/even subframe --- openair1/PHY/LTE_TRANSPORT/dci.c | 2 +- openair1/PHY/LTE_TRANSPORT/phich.c | 8 +-- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 2 +- openair1/SCHED/phy_procedures_lte_ue.c | 77 ++++++++++++----------- 4 files changed, 46 insertions(+), 43 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index df4146adec..21c4c8aba8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -2890,7 +2890,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, } } - LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2); + LOG_D(PHY,"DCI decoding CRNTI [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2); // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index bb8c1f119d..d363d4dcf6 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1368,7 +1368,7 @@ void rx_phich(PHY_VARS_UE *ue, if (HI16>0) { //NACK if (ue->ulsch_Msg3_active[eNB_id] == 1) { - LOG_I(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received NAK (%d) nseq %d, ngroup %d\n", + LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received NAK (%d) nseq %d, ngroup %d\n", ue->Mod_id,harq_pid, proc->frame_rx, subframe, @@ -1389,7 +1389,7 @@ void rx_phich(PHY_VARS_UE *ue, } } else { //#ifdef DEBUG_PHICH - LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n", + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n", ue->Mod_id,harq_pid, proc->frame_rx%1024, subframe, @@ -1436,7 +1436,7 @@ void rx_phich(PHY_VARS_UE *ue, } else { //ACK if (ue->ulsch_Msg3_active[eNB_id] == 1) { - LOG_I(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", + LOG_D(PHY,"[UE %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", ue->Mod_id,harq_pid, proc->frame_rx, subframe, @@ -1444,7 +1444,7 @@ void rx_phich(PHY_VARS_UE *ue, nseq_PHICH,ngroup_PHICH); } else { //#ifdef PHICH_DEBUG - LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", + LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n", ue->Mod_id,harq_pid, proc->frame_rx%1024, subframe, HI16, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index e64b959e68..bd49fdacb0 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -265,7 +265,7 @@ uint32_t ulsch_encoding(uint8_t *a, rnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti; fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff); - LOG_I(PHY,"ULSCH Encoding rnti %x \n", rnti); + LOG_D(PHY,"ULSCH Encoding rnti %x \n", rnti); print_CQI(ulsch->o,ulsch->uci_format,0,ue->frame_parms.N_RB_DL); // save PUSCH pmi for later (transmission modes 4,5,6) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 2bd4590fe0..4e5e6cb7b1 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1438,7 +1438,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB // deactivate service request // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - LOG_I(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); + LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1)) { LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); @@ -1492,8 +1492,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } -//#ifdef DEBUG_PHY_PROC - LOG_I(PHY, +#ifdef DEBUG_PHY_PROC + LOG_D(PHY, "[UE %d][PUSCH %d] AbsSubframe %d.%d %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", Mod_id,harq_pid,frame_tx,subframe_tx,proc->subframe_rx, first_rb,nb_rb, @@ -1509,7 +1509,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, ue->ulsch[eNB_id]->bundling); -//#endif +#endif @@ -2840,7 +2840,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #endif - LOG_I(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n", + LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n", ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]], dci_cnt, dci_alloc_rx[0].rnti, @@ -3361,16 +3361,18 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo dlsch0->harq_processes[0]->b, &ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, ue->prach_resources[eNB_id]->ra_PreambleIndex); + + ue->pdcch_vars[(subframe_rx+1) & 0x1][eNB_id]->crnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti; if (timing_advance!=0xffff) { - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n", - ue->Mod_id, - frame_rx, - subframe_rx, - ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, - timing_advance); + LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n", + ue->Mod_id, + frame_rx, + subframe_rx, + ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, + timing_advance); // remember this c-rnti is still a tc-rnti ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti_is_temporary = 1; @@ -3543,9 +3545,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); stop_meas(&ue->dlsch_decoding_stats); - printf(" --> Unscrambling for CW0 %5.3f\n", + LOG_D(PHY," --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - printf(" --> Turbo Decoding for CW0 %5.3f\n", + LOG_D(PHY," --> Turbo Decoding for CW0 %5.3f\n", (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); if(is_cw1_active) @@ -3593,13 +3595,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, dlsch1->harq_processes[harq_pid]->TBS>256?1:0); stop_meas(&ue->dlsch_decoding_stats); - printf(" --> Unscrambling for CW1 %5.3f\n", + LOG_D(PHY," --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - printf(" --> Turbo Decoding for CW1 %5.3f\n", + LOG_D(PHY," --> Turbo Decoding for CW1 %5.3f\n", (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); } - LOG_I(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ \n", frame_rx, subframe_rx); + LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ \n", frame_rx, subframe_rx); } else { @@ -3618,7 +3620,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(dlsch0->rnti != 0xffff) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3630,7 +3632,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, } else { if(dlsch0->rnti != 0xffff) { - LOG_I(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, @@ -3788,7 +3790,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // start timers - LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); start_meas(&ue->phy_proc_rx[subframe_rx&0x1]); start_meas(&ue->generic_stat); @@ -3843,8 +3845,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin l=1; } - LOG_I(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_I(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); for (; l<=l2; l++) { if (abstraction_flag == 0) { start_meas(&ue->ofdm_demod_stats); @@ -3874,7 +3876,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } // for l=1..l2 ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); - LOG_I(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); // If this is PMCH, call procedures and return if (pmch_flag == 1) { ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag); @@ -3890,9 +3892,9 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) stop_meas(&ue->generic_stat); - printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_D(PHY,"[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_I(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); start_meas(&ue->generic_stat); // do procedures for C-RNTI if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { @@ -3909,7 +3911,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } - LOG_I(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); @@ -3955,8 +3957,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } - LOG_I(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_I(PHY," ------ --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) { // do front-end processing for second slot, and first symbol of next subframe for (l=1; lframe_parms.symbols_per_tti>>1; l++) { @@ -3991,16 +3993,17 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } // not an S-subframe stop_meas(&ue->generic_stat); - printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); - LOG_I(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY,"[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) { ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); } // do procedures for C-RNTI - LOG_I(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); start_meas(&ue->pdsch_procedures_stat); @@ -4014,9 +4017,10 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->frame_parms.symbols_per_tti-1, abstraction_flag); stop_meas(&ue->pdsch_procedures_stat); - LOG_I(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_I(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + start_meas(&ue->dlsch_procedures_stat); ue_dlsch_procedures(ue, proc, @@ -4028,8 +4032,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin mode, abstraction_flag); stop_meas(&ue->dlsch_procedures_stat); - printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0)); - printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); + LOG_D(PHY,"[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0)); + LOG_D(PHY,"[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); @@ -4141,9 +4145,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); stop_meas(&ue->phy_proc_rx[subframe_rx&0x1]); - printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0)); - - LOG_I(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + LOG_D(PHY,"------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0)); + LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); return (0); } From 1e193853eb007a2378d401269a8777e29bbdc669 Mon Sep 17 00:00:00 2001 From: Calisson Date: Tue, 14 Mar 2017 17:13:14 +0100 Subject: [PATCH 392/571] WIP: adding srs channel estimation to eNB. estimation results yet to be checked. --- .../lte_ul_channel_estimation.c | 36 +++++++------ openair1/PHY/LTE_TRANSPORT/proto.h | 8 +-- openair1/PHY/LTE_TRANSPORT/srs_modulation.c | 50 +++++++----------- openair1/PHY/TOOLS/lte_phy_scope.c | 13 +++-- openair1/SCHED/phy_procedures_lte_eNb.c | 52 ++++++++++++------- openair1/SCHED/phy_procedures_lte_ue.c | 8 ++- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 2 +- .../CONF/enb.band7.tm1.usrpb210.conf | 2 +- 8 files changed, 92 insertions(+), 79 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 4fef74dd1c..22ed10ebb7 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -667,28 +667,28 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB, } extern uint16_t transmission_offset_tdd[16]; -#define DEBUG_SRS +//#define DEBUG_SRS int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, LTE_eNB_COMMON *common_vars, LTE_eNB_SRS *srs_vars, SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated, - unsigned char sub_frame_number, + unsigned char subframe, unsigned char eNB_id) { - int T_SFC,aa; + int aa; int N_symb,symbol; - uint8_t nb_antennas_rx = frame_parms->nb_antenna_ports_eNB; + uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; #ifdef DEBUG_SRS char fname[40], vname[40]; #endif - uint8_t Ssrs = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; + //uint8_t Ssrs = frame_parms->soundingrs_ul_config_common.srs_SubframeConfig; + //uint8_t T_SFC = (Ssrs<=7 ? 5 : 10); N_symb = 2*7-frame_parms->Ncp; - symbol = (sub_frame_number+1)*N_symb-1; //SRS is always in last symbol of subframe - T_SFC = (Ssrs<=7 ? 5 : 10); + symbol = N_symb-1; //SRS is always in last symbol of subframe /* msg("SRS channel estimation eNB %d, subframs %d, %d %d %d %d %d\n",eNB_id,sub_frame_number, @@ -699,19 +699,21 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, SRS_parms->Ssrs); */ - if ((1<<(sub_frame_number%T_SFC))&transmission_offset_tdd[Ssrs]) { + //if ((1<<(sub_frame_number%T_SFC))&transmission_offset_tdd[Ssrs]) { - if (generate_srs_rx(frame_parms, - soundingrs_ul_config_dedicated, - srs_vars->srs)==-1) { - msg("lte_srs_channel_estimation: Error in generate_srs_rx\n"); + if (generate_srs(frame_parms, + soundingrs_ul_config_dedicated, + &srs_vars->srs[eNB_id], + 0x7FFF, + subframe)==-1) { + LOG_E(PHY,"lte_srs_channel_estimation: Error in generate_srs_rx\n"); return(-1); } for (aa=0; aarxdataF[eNB_id][aa][2*frame_parms->ofdm_symbol_size*symbol], + &common_vars->rxdataF[eNB_id][aa][frame_parms->ofdm_symbol_size*symbol], srs_vars->srs, srs_vars->srs_ch_estimates[eNB_id][aa]); #endif @@ -719,14 +721,15 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, //write_output("eNB_rxF.m","rxF",&common_vars->rxdataF[0][aa][2*frame_parms->ofdm_symbol_size*symbol],2*(frame_parms->ofdm_symbol_size),2,1); //write_output("eNB_srs.m","srs_eNB",common_vars->srs,(frame_parms->ofdm_symbol_size),1,1); - mult_cpx_conj_vector((int16_t*) &common_vars->rxdataF[eNB_id][aa][2*frame_parms->ofdm_symbol_size*symbol], - (int16_t*) srs_vars->srs, + //memcpy(srs_vars->srs_ch_estimates[eNB_id][aa],&srs_vars->srs[eNB_id],frame_parms->ofdm_symbol_size*sizeof(int32_t)); + //memcpy(srs_vars->srs_ch_estimates[eNB_id][aa],&common_vars->rxdataF[eNB_id][aa][frame_parms->ofdm_symbol_size*symbol],frame_parms->ofdm_symbol_size*sizeof(int32_t)); + mult_cpx_conj_vector((int16_t*) &common_vars->rxdataF[eNB_id][aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t*) &srs_vars->srs[eNB_id], (int16_t*) srs_vars->srs_ch_estimates[eNB_id][aa], frame_parms->ofdm_symbol_size, 15, 0); - //msg("SRS channel estimation cmult out\n"); #ifdef USER_MODE #ifdef DEBUG_SRS sprintf(fname,"eNB_id%d_an%d_srs_ch_est.m",eNB_id,aa); @@ -735,7 +738,6 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, #endif #endif } - } /* else { diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 5fc8dea986..aaa0a28043 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1538,9 +1538,11 @@ uint8_t SE2I_TBS(float SE, @param soundingrs_ul_config_dedicated Dynamic configuration from RRC during Connection Establishment @param txdataF pointer to the frequency domain TX signal @returns 0 on success*/ -int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, - SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated, - int *txdataF); +int generate_srs(LTE_DL_FRAME_PARMS *frame_parms, + SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated, + int *txdataF, + int16_t amp, + uint32_t subframe); int32_t generate_srs_tx_emul(PHY_VARS_UE *phy_vars_ue, uint8_t subframe); diff --git a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c index 7e29d998a1..97dd1c5745 100644 --- a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c @@ -120,17 +120,15 @@ int compareints (const void * a, const void * b) return ( *(unsigned short*)a - *(unsigned short*)b ); } - -int32_t generate_srs_tx(PHY_VARS_UE *ue, - uint8_t eNB_id, - int16_t amp, - uint32_t subframe) +#define DEBUG_SRS +int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms, + SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated, + int32_t *txptr, + int16_t amp, + uint32_t subframe) { - LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id]; - int32_t **txdataF = ue->common_vars.txdataF; - uint16_t msrsb=0,Nb=0,nb,b,msrs0=0,k,Msc_RS,Msc_RS_idx,carrier_pos,symbol_offset; + uint16_t msrsb=0,Nb=0,nb,b,msrs0=0,k,Msc_RS,Msc_RS_idx,carrier_pos; uint16_t *Msc_idx_ptr; int32_t k0; //uint32_t subframe_offset; @@ -178,7 +176,7 @@ int32_t generate_srs_tx(PHY_VARS_UE *ue, } if (k0<0) { - msg("generate_srs: invalid parameter set msrs0=%d, msrsb=%d, Nb=%d => nb=%d, k0=%d\n",msrs0,msrsb,Nb,nb,k0); + LOG_E(PHY,"generate_srs: invalid parameter set msrs0=%d, msrsb=%d, Nb=%d => nb=%d, k0=%d\n",msrs0,msrsb,Nb,nb,k0); return(-1); } @@ -188,7 +186,7 @@ int32_t generate_srs_tx(PHY_VARS_UE *ue, if (Msc_idx_ptr) Msc_RS_idx = Msc_idx_ptr - dftsizes; else { - msg("generate_srs: index for Msc_RS=%d not found\n",Msc_RS); + LOG_E(PHY,"generate_srs: index for Msc_RS=%d not found\n",Msc_RS); return(-1); } @@ -199,29 +197,20 @@ int32_t generate_srs_tx(PHY_VARS_UE *ue, else if (Msc_RS==144) Msc_RS_idx = 9; else { - msg("generate_srs: index for Msc_RS=%d not implemented\n",Msc_RS); + LOG_E(PHY,"generate_srs: index for Msc_RS=%d not implemented\n",Msc_RS); return(-1); } #endif #ifdef DEBUG_SRS - msg("generate_srs_tx: Msc_RS = %d, Msc_RS_idx = %d\n",Msc_RS, Msc_RS_idx); + LOG_I(PHY,"generate_srs_tx: Msc_RS = %d, Msc_RS_idx = %d, k0 = %d\n",Msc_RS, Msc_RS_idx,k0); #endif carrier_pos = (frame_parms->first_carrier_offset + k0); if (carrier_pos>frame_parms->ofdm_symbol_size) { carrier_pos -= frame_parms->ofdm_symbol_size; } - uint16_t nsymb = (frame_parms->Ncp==0) ? 14:12; - symbol_offset = (int)frame_parms->ofdm_symbol_size*((subframe*nsymb)+(nsymb-1)); - - //msg("carrier_pos = %d\n",carrier_pos); - //subframe_offset = subframe*frame_parms->symbols_per_tti*frame_parms->ofdm_symbol_size; - //symbol_offset = subframe_offset+(frame_parms->symbols_per_tti-1)*frame_parms->ofdm_symbol_size; - - int32_t *txptr; - txptr = &txdataF[0][symbol_offset]; for (k=0; k> 15; @@ -245,6 +234,7 @@ int generate_srs_tx_emul(PHY_VARS_UE *phy_vars_ue,uint8_t subframe) return(0); } +#if 0 int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, SOUNDINGRS_UL_CONFIG_DEDICATED *soundingrs_ul_config_dedicated, int *txdataF) @@ -285,7 +275,7 @@ int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, } if (k0<0) { - msg("Invalid parameter set msrs0=%d, msrsb=%d, Nb=%d => nb=%d, k0=%d\n",msrs0,msrsb,Nb,nb,k0); + LOG_E(PHY,"Invalid parameter set msrs0=%d, msrsb=%d, Nb=%d => nb=%d, k0=%d\n",msrs0,msrsb,Nb,nb,k0); return(-1); } @@ -295,7 +285,7 @@ int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, if (Msc_idx_ptr) Msc_RS_idx = Msc_idx_ptr - dftsizes; else { - msg("generate_srs: index for Msc_RS=%d not found\n",Msc_RS); + LOG_E(PHY,"generate_srs: index for Msc_RS=%d not found\n",Msc_RS); return(-1); } @@ -306,23 +296,21 @@ int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, else if (Msc_RS==144) Msc_RS_idx = 9; else { - msg("generate_srs: index for Msc_RS=%d not implemented\n",Msc_RS); + LOG_E(PHY,"generate_srs: index for Msc_RS=%d not implemented\n",Msc_RS); return(-1); } #endif #ifdef DEBUG_SRS - msg("generate_srs_rx: Msc_RS = %d, Msc_RS_idx = %d, k0=%d\n",Msc_RS, Msc_RS_idx,k0); + LOG_I(PHY,"generate_srs_rx: Msc_RS = %d, Msc_RS_idx = %d, k0=%d\n",Msc_RS, Msc_RS_idx,k0); #endif carrier_pos = (frame_parms->first_carrier_offset + k0) % frame_parms->ofdm_symbol_size; for (k=0; k= frame_parms->ofdm_symbol_size) @@ -365,7 +353,7 @@ int generate_srs_rx(LTE_DL_FRAME_PARMS *frame_parms, // write_output("srs_rx.m","srsrx",txdataF,1024,2,1); return(0); } - +#endif #ifdef MAIN main() diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index ca08f87519..72035f9296 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -84,7 +84,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_xyplot_ybounds(fdui->rxsig_t,10,70); // Time-domain channel response - fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" ); + fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "SRS Frequency Response (samples, abs)" ); fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color @@ -196,7 +196,8 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, bit = malloc(coded_bits_per_codeword*sizeof(float)); rxsig_t = (int16_t**) phy_vars_enb->common_vars.rxdata[eNB_id]; - chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; + //chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; + chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates[eNB_id]; chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0]; @@ -232,8 +233,10 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, if (chest_t[0] !=NULL) { for (i=0; i<(frame_parms->ofdm_symbol_size); i++) { - i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size; - time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1)); + //i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size; + i2=i; + //time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1)); + time2[i] = (float)i; chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1])); if (chest_t_abs[0][i] > ymax) @@ -768,4 +771,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } free(chest_t_abs); -} \ No newline at end of file +} diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 2947ce2ce7..95fa3d4715 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2087,7 +2087,7 @@ void prach_procedures(PHY_VARS_eNB *eNB) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } -void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid) +void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq_pid,uint8_t do_srs) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0}; @@ -2099,10 +2099,6 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq PUCCH_FMT_t format; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - uint16_t srsPeriodicity; - uint16_t srsOffset; - uint16_t do_srs=0; - uint16_t is_srs_pos=0; if ((eNB->dlsch[UE_id][0]) && (eNB->dlsch[UE_id][0]->rnti>0) && @@ -2112,16 +2108,6 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq do_SR = is_SR_subframe(eNB,proc,UE_id); // do_SR = 0; - // check if there is SRS and we have to use shortened format - // TODO: check for exceptions in transmission of SRS together with ACK/NACK - is_srs_pos = is_srs_occasion_common(fp,pdcch_alloc2ul_frame(fp,frame,subframe),pdcch_alloc2ul_subframe(fp,subframe)); - if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup ) { - compute_srs_pos(fp->frame_type, eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex, &srsPeriodicity, &srsOffset); - if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) { - do_srs = 1; - } - } - // Now ACK/NAK // First check subframe_tx flag for earlier subframes @@ -2896,6 +2882,11 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const const int frame = proc->frame_rx; int offset = eNB->CC_id;//(proc == &eNB->proc.proc_rxtx[0]) ? 0 : 1; + uint16_t srsPeriodicity; + uint16_t srsOffset; + uint16_t do_srs=0; + uint16_t is_srs_pos=0; + T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0), @@ -2925,13 +2916,34 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->cba_last_reception[i]=0; } - // Do PUCCH processing first - for (i=0; isoundingrs_ul_config_dedicated[i].srsConfigDedicatedSetup ) { + compute_srs_pos(fp->frame_type, eNB->soundingrs_ul_config_dedicated[i].srs_ConfigIndex, &srsPeriodicity, &srsOffset); + if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) { + do_srs = 1; + } + } + + if (do_srs==1) { + if (lte_srs_channel_estimation(fp, + &eNB->common_vars, + &eNB->srs_vars[i], + &eNB->soundingrs_ul_config_dedicated[i], + subframe, + 0/*eNB_id*/)) { + LOG_E(PHY,"problem processing SRS\n"); + } + } + + // Do PUCCH processing + + pucch_procedures(eNB,proc,i,harq_pid, do_srs); + // check for Msg3 if (eNB->mac_enabled==1) { diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 381ea547e4..43113744a2 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1579,7 +1579,13 @@ void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8 nb_rb_srs, tx_amp); - generate_srs_tx(ue, eNB_id, tx_amp, subframe_tx); + uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12; + uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((subframe_tx*nsymb)+(nsymb-1)); + generate_srs(&ue->frame_parms, + &ue->soundingrs_ul_config_dedicated[eNB_id], + &ue->common_vars.txdataF[eNB_id][symbol_offset], + tx_amp, + subframe_tx); } } diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 67f93a960e..f6a5a0c9df 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -1593,7 +1593,7 @@ do_RRCConnectionSetup( SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=19; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=2; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift= SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index debed67f72..a9933a6444 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -137,7 +137,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "192.168.12.70"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; From bf71c6f01e0a6f926445d464f3cd13d0d60d4b2c Mon Sep 17 00:00:00 2001 From: fnabet Date: Wed, 15 Mar 2017 10:10:32 +0100 Subject: [PATCH 393/571] RLC AM Tx Segment: fix --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 27aa0b6ddf..b88d321494 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -430,7 +430,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( sdus_segment_size[0] = data_size - retx_so_start; /* Check if so end is in the first SDU portion */ - if (sdus_segment_size[0] > retx_so_stop - retx_so_start + 1) + if (sdus_segment_size[0] >= retx_so_stop - retx_so_start + 1) { sdus_segment_size[0] = retx_so_stop - retx_so_start + 1; *payload_sizeP = sdus_segment_size[0]; @@ -451,7 +451,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( { sdu_index ++; sdu_segment_index ++; - while (sdu_index < pdu_mngt->nb_sdus) + while ((sdu_index < pdu_mngt->nb_sdus) && (data_size < retx_so_stop + 1)) { if (sdu_index < pdu_mngt->nb_sdus - 1) { @@ -468,20 +468,19 @@ mem_block_t* rlc_am_retransmit_get_am_segment( data_size = pdu_mngt->payload_size; } - if (data_size >= retx_so_stop + 1) - { - sdus_segment_size[sdu_segment_index] = retx_so_stop - (data_size - sdu_size) + 1; - break; - } - sdus_segment_size[sdu_segment_index] = sdu_size; sdu_index ++; sdu_segment_index ++; } + if (data_size > retx_so_stop + 1) + { + sdus_segment_size[sdu_segment_index - 1] = retx_so_stop - (data_size - sdu_size) + 1; + } + /* Set number of LIs in the segment */ - num_LIs_pdu_segment = sdu_segment_index; + num_LIs_pdu_segment = sdu_segment_index - 1; AssertFatal (num_LIs_pdu_segment <= pdu_mngt->nb_sdus - 1, "RLC AM Tx PDU Segment Data Error: nbLISegment=%d nbLIPDU=%d sn=%d LcId=%d !\n", num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id); @@ -527,6 +526,8 @@ mem_block_t* rlc_am_retransmit_get_am_segment( data_size = 0; for (int i = 0; i < num_LIs_pdu_segment + 1; i++) { + AssertFatal (sdus_segment_size[i] > 0, "RLC AM Tx PDU Segment Data Error: EMpty LI index=%d numLISegment=%d numLIPDU=%d PDULength=%d SOStart=%d SOStop=%d sn=%d LcId=%d !\n", + i,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,pdu_mngt->payload_size,retx_so_start,retx_so_stop,sn,rlc_pP->channel_id); data_size += sdus_segment_size[i]; if ((retx_so_stop == data_size - 1) && (i < num_LIs_pdu_segment)) { @@ -534,7 +535,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( } } - AssertFatal (data_size == *payload_sizeP, "RLC AM PDU Segment Data Error: SduSum=%d Data=%d sn=%d LcId=%d !\n", + AssertFatal (data_size == *payload_sizeP, "RLC AM Tx PDU Segment Data Error: SduSum=%d Data=%d sn=%d LcId=%d !\n", data_size,*payload_sizeP,sn,rlc_pP->channel_id); From b4f8219170f03a1349bff0e678d78aacae3c55fd Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 15 Mar 2017 16:04:42 +0100 Subject: [PATCH 394/571] calibrations for 5/10/20 MHz LimeSDR --- targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 13 +++++++------ .../CONF/enb.band7.tm1.25PRB.lmssdr.conf | 8 ++++---- .../CONF/enb.band7.tm1.50PRB.lmssdr.conf | 6 +++--- targets/RT/USER/lte-enb.c | 2 +- targets/RT/USER/lte-softmodem.c | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index 64f87ca9d7..a98df19cf7 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -138,7 +138,7 @@ int trx_lms_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) ret = -1; } - LMS_SetNormalizedGain(lms_device, LMS_CH_TX, 0, .2);//openair0_cfg->tx_gain[0]); + LMS_SetGaindB(lms_device, LMS_CH_TX, 0, openair0_cfg->tx_gain[0]); LMS_SetGaindB(lms_device, LMS_CH_RX, 0, openair0_cfg->rx_gain[0]-openair0_cfg->rx_gain_offset[0]); return(ret); @@ -202,10 +202,11 @@ int trx_lms_start(openair0_device *device){ } printf("Set TX frequency %f MHz\n",device->openair0_cfg[0].tx_freq[0]/1e6); - //printf("Override antenna settings to: RX1_H, TXA_2"); - //LMS_SetAntenna(lms_device, LMS_CH_RX, 0, 1); - //LMS_SetAntenna(lms_device, LMS_CH_TX, 0, 2); - + /* + printf("Override antenna settings to: RX1_H, TXA_2"); + LMS_SetAntenna(lms_device, LMS_CH_RX, 0, 1); + LMS_SetAntenna(lms_device, LMS_CH_TX, 0, 2); + */ for (int i = 0; i< device->openair0_cfg->rx_num_channels; i++) @@ -354,7 +355,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg){ break; case 15360000: openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 70; + openair0_cfg[0].tx_sample_advance = 450; openair0_cfg[0].tx_bw = 15.36e6; openair0_cfg[0].rx_bw = 15.36e6; break; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf index 5aa544cd85..00f875ec4e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.lmssdr.conf @@ -17,7 +17,7 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "92"; + mobile_network_code = "93"; ////////// Physical parameters: @@ -39,7 +39,7 @@ eNBs = nb_antenna_ports = 1; nb_antennas_tx = 1; nb_antennas_rx = 1; - tx_gain = 20; + tx_gain = 7; rx_gain = 116; prach_root = 0; prach_config_index = 0; @@ -50,7 +50,7 @@ eNBs = pucch_nRB_CQI = 1; pucch_nCS_AN = 0; pucch_n1_AN = 32; - pdsch_referenceSignalPower = -30; + pdsch_referenceSignalPower = -34; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; @@ -136,7 +136,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.70"; + mme_ip_address = ( { ipv4 = "192.168.12.148"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf index d3ca6b9092..2d0e0f3702 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.lmssdr.conf @@ -17,7 +17,7 @@ eNBs = mobile_country_code = "208"; - mobile_network_code = "92"; + mobile_network_code = "93"; ////////// Physical parameters: @@ -50,7 +50,7 @@ eNBs = pucch_nRB_CQI = 1; pucch_nCS_AN = 0; pucch_n1_AN = 32; - pdsch_referenceSignalPower = -36; + pdsch_referenceSignalPower = -35; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; @@ -136,7 +136,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.70"; + mme_ip_address = ( { ipv4 = "192.168.12.148"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 6f31f7842d..21d34d40b1 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1560,7 +1560,7 @@ static void* eNB_thread_single( void* param ) { wait_sync("eNB_thread_single"); #if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - if (eNB->node_function < NGFI_RRU_IF5) + if ((eNB->node_function < NGFI_RRU_IF5) && (eNB->mac_enabled==1)) wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB); #endif diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 8303d88218..ecf7645808 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1726,7 +1726,7 @@ int main( int argc, char **argv ) { #if defined(ENABLE_ITTI) if ((UE_flag == 1)|| - (node_function[0] Date: Wed, 15 Mar 2017 16:54:01 +0100 Subject: [PATCH 395/571] RLC AM Fix on ReTx --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 3 + .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 57 ++++++++++--------- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 7 ++- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index f7f4de1718..c399fb8447 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -1236,6 +1236,8 @@ rlc_am_data_req ( l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.no_new_sdu_segmented_in_last_pdu = 0; //l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].li_index_for_discard = -1; l_rlc_p->next_sdu_index = (l_rlc_p->next_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; + if (l_rlc_p->channel_id <3) + { LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p), data_size, @@ -1244,6 +1246,7 @@ rlc_am_data_req ( l_rlc_p->next_sdu_index, conf, mui); + } } else { #if MESSAGE_CHART_GENERATOR mui = ((struct rlc_am_data_req*) (sdu_pP->data))->mui; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index b88d321494..4cef19253a 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -375,33 +375,33 @@ mem_block_t* rlc_am_retransmit_get_am_segment( li_bit_offset ^= 0x4; li_jump_offset ^= 0x3; data_size += sdu_size; + sdu_index = 1; /* Loop on all original LIs */ - while ((data_size < retx_so_start + 1) && (sdu_index + 1 < pdu_mngt->nb_sdus - 1)) + while ((data_size < retx_so_start + 1) && (sdu_index < pdu_mngt->nb_sdus)) { + if (sdu_index < pdu_mngt->nb_sdus - 1) + { + temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); + sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); + pdu_original_header_p += li_jump_offset; + li_bit_offset ^= 0x4; + li_jump_offset ^= 0x3; + data_size += sdu_size; + } + else + { + /* if retx_so_start is still not included then set data_size with full original PDU data size */ + /* Set fi_start to FALSE in this case */ + data_size = pdu_mngt->payload_size; + } sdu_index ++; - temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1)); - sdu_size = RLC_AM_PDU_GET_LI(temp_read,li_bit_offset); - pdu_original_header_p += li_jump_offset; - li_bit_offset ^= 0x4; - li_jump_offset ^= 0x3; - data_size += sdu_size; } - /* if retx_so_start is still not included then set data_size with full original PDU data size */ - /* Set fi_start to FALSE in this case */ - if ((data_size < retx_so_start + 1) && (sdu_index == pdu_mngt->nb_sdus - 1)) - { - data_size = pdu_mngt->payload_size; - fi_start = FALSE; - - } - else if (retx_so_start == data_size) + if (retx_so_start == data_size) { /* Set FI Start if retx_so_start = cumulated data size */ fi_start = TRUE; - /* jump to next SDU */ - sdu_index ++; /* there must be at least one SDU more */ AssertFatal (sdu_index < pdu_mngt->nb_sdus, "RLC AM Tx PDU Segment Error: sdu_index=%d nb_sdus=%d sn=%d LcId=%d !\n", sdu_index,pdu_mngt->nb_sdus,sn,rlc_pP->channel_id); @@ -419,6 +419,8 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* It was the last LI, then set data_size to full original PDU size */ data_size = pdu_mngt->payload_size; } + /* Go to next SDU */ + sdu_index ++; } else if (retx_so_start != 0) { @@ -449,7 +451,6 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* Now look for the end if it was not set previously */ if (*payload_sizeP == 0) { - sdu_index ++; sdu_segment_index ++; while ((sdu_index < pdu_mngt->nb_sdus) && (data_size < retx_so_stop + 1)) { @@ -489,16 +490,19 @@ mem_block_t* rlc_am_retransmit_get_am_segment( sdu_segment_index = 0; while ((sdu_segment_index < num_LIs_pdu_segment + 1) && (rlc_pP->nb_bytes_requested_by_mac > *payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index))) { + AssertFatal (sdus_segment_size[sdu_segment_index] > 0, "RLC AM Tx PDU Segment Data Error: EMpty LI index=%d numLISegment=%d numLIPDU=%d PDULength=%d SOStart=%d SOStop=%d sn=%d LcId=%d !\n", + sdu_segment_index,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,pdu_mngt->payload_size,retx_so_start,retx_so_stop,sn,rlc_pP->channel_id); + /* Add next sdu_segment_index to data part */ - if (RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index) + sdus_segment_size[sdu_segment_index] <= rlc_pP->nb_bytes_requested_by_mac) + if (RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index) + (*payload_sizeP) + sdus_segment_size[sdu_segment_index] <= rlc_pP->nb_bytes_requested_by_mac) { (*payload_sizeP) += sdus_segment_size[sdu_segment_index]; } else { /* bound to available TBS size */ - (*payload_sizeP) += (rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index)); - sdus_segment_size[sdu_segment_index] = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); + sdus_segment_size[sdu_segment_index] = rlc_pP->nb_bytes_requested_by_mac - RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index) - (*payload_sizeP); + (*payload_sizeP) += sdus_segment_size[sdu_segment_index]; } header_segment_length = RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index); sdu_segment_index ++; @@ -511,9 +515,9 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* update retx_so_stop */ retx_so_stop = retx_so_start + (*payload_sizeP) - 1; - AssertFatal (retx_so_stop <= pdu_mngt->payload_size - 1, - "RLC AM Tx PDU Segment Data Error: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d numLISegment=%d sn=%d LcId=%d !\n", - retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,num_LIs_pdu_segment,sn,rlc_pP->channel_id); + AssertFatal ((retx_so_stop <= pdu_mngt->payload_size - 1) && (retx_so_stop - retx_so_start + 1 < pdu_mngt->payload_size), + "RLC AM Tx PDU Segment Data Error: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d numLISegment=%d numLIPDU=%d sn=%d LcId=%d !\n", + retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id); /* init FI End to FALSE if retx_so_stop is not end of PDU */ if (retx_so_stop != pdu_mngt->payload_size - 1) @@ -526,8 +530,6 @@ mem_block_t* rlc_am_retransmit_get_am_segment( data_size = 0; for (int i = 0; i < num_LIs_pdu_segment + 1; i++) { - AssertFatal (sdus_segment_size[i] > 0, "RLC AM Tx PDU Segment Data Error: EMpty LI index=%d numLISegment=%d numLIPDU=%d PDULength=%d SOStart=%d SOStop=%d sn=%d LcId=%d !\n", - i,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,pdu_mngt->payload_size,retx_so_start,retx_so_stop,sn,rlc_pP->channel_id); data_size += sdus_segment_size[i]; if ((retx_so_stop == data_size - 1) && (i < num_LIs_pdu_segment)) { @@ -573,6 +575,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* Retx size is reset in the calling function */ pdu_mngt->num_holes = 0; pdu_mngt->retx_hole_index = 0; + pdu_mngt->nack_so_start = 0; } } else diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index dfa62f0351..50ed5dca56 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -384,8 +384,8 @@ rlc_am_receive_process_control_pdu( } else { - LOG_N(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN OUT OF WINDOW\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); + LOG_N(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN %d OUT OF WINDOW vtA=%d vtS=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,rlc_pP->vt_a,rlc_pP->vt_s); status = FALSE; } } else { @@ -416,6 +416,9 @@ rlc_am_receive_process_control_pdu( rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_data_cnf); } + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU ACK_SN=%d NewvtA=%d OldvtA=%d SnDataCnf=%d DataCnfSOStop=%d vtS=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,sn_data_cnf,data_cnf_so_stop,rlc_pP->vt_s); + /* Update vtA and vtMS */ rlc_pP->vt_a = vt_a_new; rlc_pP->vt_ms = (rlc_pP->vt_a + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; From 40fa3e076cd50b403f5034063890ac07b1053547 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Wed, 15 Mar 2017 16:58:54 +0100 Subject: [PATCH 396/571] RLC AM Rx fixes --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 12 +++++++++--- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c | 8 ++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index fd84cd5e35..c66b826fd6 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -490,7 +490,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( mem_block_t* trunc_segment = create_new_segment_from_pdu(tb_pP,so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1); if (trunc_segment != NULL) { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n", + LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1,pdu_rx_info_p->sn); if (previous_cursor_p != NULL) { @@ -610,7 +610,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU REPLACES STORED PDU SEGMENTS SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); - list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + if (previous_cursor_p != NULL) { + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + } + else { + list2_insert_before_element(tb_pP, cursor_next_p, &rlc_pP->receiver_buffer); + } + return pdu_status; } // End SN != vrR or SO != 0 else { @@ -636,7 +642,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( /* Insert PDU Segment */ list2_insert_after_element(trunc_pdu, previous_cursor_p, &rlc_pP->receiver_buffer); - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] CREATE PDU SEGMENT FROM PDU OFFSET =%d SN=%d\n", + LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] CREATE PDU SEGMENT FROM PDU OFFSET =%d SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),next_waited_so,pdu_rx_info_p->sn); /* clean previous stored segments in duplicate */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 50ed5dca56..0d01d0b1ce 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -736,8 +736,12 @@ rlc_am_send_status_pdu( } // End main while NACK_SN /* Clear E1 of last nack_sn entry */ - AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN LcId=%d\n",rlc_pP->channel_id); - control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0; + AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n", + rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id); + if (control_pdu_info.num_nack) { + control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0; + } + /* Set ACK_SN unless it was set before */ if (!status_report_completed){ From f5aa0135b13b1e9a9ad92ef2c56e29b180a00743 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 15 Mar 2017 17:17:54 +0100 Subject: [PATCH 397/571] hotfix: fix buffer size for phy-test mode 20MHz 768*8 is too small, in 20MHz, the phy-test mode (in default mode?) has a buffer of size 6378. Let's set the buffer size to the input's one plus 4 bytes (to accomodate for CRC, not sure about this). --- openair1/SCHED/phy_procedures_lte_eNb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index e9f1125a34..97c8fb0837 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -899,7 +899,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d int input_buffer_length = dlsch_harq->TBS/8; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; uint8_t *DLSCH_pdu=NULL; - uint8_t DLSCH_pdu_tmp[768*8]; + uint8_t DLSCH_pdu_tmp[input_buffer_length+4]; //[768*8]; uint8_t DLSCH_pdu_rar[256]; int i; From 65f49f9ffd517f9c89d72110c00416f85f9adb57 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 15 Mar 2017 17:43:18 +0100 Subject: [PATCH 398/571] bugfixes to previous commit and ulsim. now srs estimaton seems to work. at least in ulsim. --- cmake_targets/lte-simulators/CMakeLists.txt | 1 + openair1/PHY/LTE_TRANSPORT/srs_modulation.c | 2 +- openair1/SCHED/defs.h | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 6 ++-- openair1/SCHED/phy_procedures_lte_ue.c | 12 ++++---- openair1/SIMULATION/LTE_PHY/ulsim.c | 32 ++++++++++++++++----- 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index 5ed4d93d80..79ff0bfbd2 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -3,6 +3,7 @@ set(PACKAGE_NAME "unitary_tests_simulators") set(PHYSIM True) set(RF_BOARD None) set(XFORMS True) +set(ENABLE_ITTI False) set(DEBUG_PHY False) set(MU_RECIEVER False) diff --git a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c index 97dd1c5745..8381eca5e4 100644 --- a/openair1/PHY/LTE_TRANSPORT/srs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/srs_modulation.c @@ -204,7 +204,7 @@ int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms, #endif #ifdef DEBUG_SRS - LOG_I(PHY,"generate_srs_tx: Msc_RS = %d, Msc_RS_idx = %d, k0 = %d\n",Msc_RS, Msc_RS_idx,k0); + LOG_D(PHY,"generate_srs_tx: Msc_RS = %d, Msc_RS_idx = %d, k0 = %d\n",Msc_RS, Msc_RS_idx,k0); #endif carrier_pos = (frame_parms->first_carrier_offset + k0); diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index f283014af7..4aad186f76 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -379,7 +379,7 @@ void process_timing_advance_rar(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,ui unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb); -void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); +void phy_reset_ue( PHY_VARS_UE *ue ); /*! \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch. For diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 95fa3d4715..f4cc7f8c41 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2916,15 +2916,17 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const eNB->cba_last_reception[i]=0; } + is_srs_pos = is_srs_occasion_common(fp,frame,subframe); + for (i=0; isoundingrs_ul_config_dedicated[i].srsConfigDedicatedSetup ) { compute_srs_pos(fp->frame_type, eNB->soundingrs_ul_config_dedicated[i].srs_ConfigIndex, &srsPeriodicity, &srsOffset); - if ((((10*pdcch_alloc2ul_frame(fp,frame,subframe)+pdcch_alloc2ul_subframe(fp,subframe)) % srsPeriodicity) == srsOffset)) { + if (((10*frame+subframe) % srsPeriodicity) == srsOffset) { do_srs = 1; } } diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 43113744a2..ca9ee8df7c 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -259,14 +259,13 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s } -void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) +void phy_reset_ue(PHY_VARS_UE *ue) { // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later // for more flexibility uint8_t i,j,k,s; - PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; //[NUMBER_OF_CONNECTED_eNB_MAX][2]; for(i=0; icqi_PMI_ConfigIndex, // (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI)); - if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI) + if (cqirep->cqi_PMI_ConfigIndex==-1) + return(0); + else if (((10*frame + subframe) % cqirep->Npd) == cqirep->N_OFFSET_CQI) return(1); else return(0); @@ -428,8 +429,9 @@ uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) // ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame,subframe, // cqirep->ri_ConfigIndex, // (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<ri_ConfigIndex==-1) + return(0); + else if (((10*frame + subframe + cqirep->N_OFFSET_CQI - N_OFFSET_RI) % (cqirep->Npd<frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; UE->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; - UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7; + UE->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; + UE->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = srs_flag; + UE->soundingrs_ul_config_dedicated[eNB_id].duration = 1; + UE->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex = 2; UE->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = 0; UE->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = 0; UE->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = 0; + UE->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = 0; eNB->frame_parms.soundingrs_ul_config_common.enabled_flag = srs_flag; eNB->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig = 2; - eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 7; - - eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex = 1; + eNB->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig = 3; + eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup = srs_flag; + eNB->soundingrs_ul_config_dedicated[UE_id].duration = 1; + eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex = 2; eNB->soundingrs_ul_config_dedicated[UE_id].srs_Bandwidth = 0; eNB->soundingrs_ul_config_dedicated[UE_id].transmissionComb = 0; eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0; + eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 0; + eNB->cooperation_flag = cooperation_flag; - // eNB->eNB_UE_stats[0].SRS_parameters = UE->SRS_parameters; eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK; eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI; @@ -659,6 +668,11 @@ int main(int argc, char **argv) UE->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled = 1; + // disable periodic cqi/ri reporting + UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; + UE->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; + + printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8); UE2eNB = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, @@ -700,8 +714,8 @@ int main(int argc, char **argv) } - - + UE->dlsch_SI[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch_ra[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->measurements.rank[0] = 0; UE->transmission_mode[0] = 2; @@ -917,6 +931,10 @@ int main(int argc, char **argv) initialize(&time_vector_rx_dec); ndi=0; + + phy_reset_ue(UE); + UE->UE_mode[eNB_id]=PUSCH; + for (trials = 0; trialsframe++; From 01530385f1b8a2080af5cd9d9555d990c4bb0013 Mon Sep 17 00:00:00 2001 From: fnabet Date: Wed, 15 Mar 2017 18:56:53 +0100 Subject: [PATCH 399/571] RLC AM fix Tx Status Report --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 7 +++++-- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 5 +++-- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index c399fb8447..7d193bcd01 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -134,8 +134,11 @@ rlc_am_get_status_pdu_buffer_occupancy( } // end if segments else { - /* Go to next received PDU or PDU Segment */ - cursor_p = cursor_p->next; + /* Go to next received PDU or PDU segment with different SN */ + do + { + cursor_p = cursor_p->next; + } while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == sn_cursor)); } sn_prev = RLC_AM_NEXT_SN(sn_cursor); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index c66b826fd6..048466a1a9 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -638,7 +638,6 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( mem_block_t* trunc_pdu = create_new_segment_from_pdu(tb_pP,next_waited_so,pdu_rx_info_p->payload_size - next_waited_so); if (trunc_pdu != NULL) { - ((rlc_am_rx_pdu_management_t *) (trunc_pdu->data))->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; /* Insert PDU Segment */ list2_insert_after_element(trunc_pdu, previous_cursor_p, &rlc_pP->receiver_buffer); @@ -1317,7 +1316,9 @@ rlc_am_rx_list_reassemble_rlc_sdus( } /* Reset Management pointers */ - if (cursor_p != NULL) { + if ((cursor_p != NULL) && + ((((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == RLC_AM_NEXT_SN(sn)) || + (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING))) { rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); } else { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 0d01d0b1ce..3a00946160 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -723,8 +723,10 @@ rlc_am_send_status_pdu( } } // end while on all PDU segments of sn_cursor else { - /* Go to next received PDU or PDU segment if sn_cursor is fully received */ - cursor_p = cursor_p->next; + /* Go to next received PDU or PDU segment with different SN */ + do { + cursor_p = cursor_p->next; + } while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == sn_cursor)); } /* Increment sn_nack except if sn_nack = vrMS and if current SN was not fully received */ From fc6dec9edda0ed93997b7abd91b3491f2c4de962 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Mar 2017 11:13:32 +0100 Subject: [PATCH 400/571] fix dependancies in CMakeLists.txt for the T tracer On some hosts, compilations with the T tracer was failing. The error was: common/utils/T/T.h:15:19: fatal error: T_IDs.h: No such file or directory The problem was that in CMakeLists.txt some targets depend on the pre-generation of T_IDs.h but this dependancy relation was not set, so those targets could be generated before the T (it was the case with HASHTABLE). This commit fixes that. Basically, we take all the targets found in "add_executable" and "add_library" and make them depend on the T if the T is enabled. Almost all existing targets were added, even those that may not need it. The problem of this approach is that someone adding a new target using the T will not necessarily add a dependancy there. Another solution would be to generate T_IDs.h at "cmake" stage, not "make" stage and use an "if (NOT EXISTS T_IDs.h)" to generate the file. We lose the dependancy relation though. Things may be changed if maintenance cost is too high. --- cmake_targets/CMakeLists.txt | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 3687b08a1a..66a55f214f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2059,22 +2059,22 @@ endforeach(myExe) #ensure that the T header files are generated before targets depending on them if (${T_TRACER}) - add_dependencies(lte-softmodem generate_T) - add_dependencies(lte-softmodem-nos1 generate_T) - add_dependencies(rrh_gw generate_T) - add_dependencies(oaisim generate_T) - add_dependencies(oaisim_nos1 generate_T) - add_dependencies(dlsim generate_T) - add_dependencies(dlsim_tm4 generate_T) - add_dependencies(dlsim_tm7 generate_T) - add_dependencies(ulsim generate_T) - add_dependencies(pbchsim generate_T) - add_dependencies(scansim generate_T) - add_dependencies(mbmssim generate_T) - add_dependencies(pdcchsim generate_T) - add_dependencies(pucchsim generate_T) - add_dependencies(prachsim generate_T) - add_dependencies(syncsim generate_T) + foreach(i + #all "add_executable" definitions (except tests, rb_tool, updatefw) + lte-softmodem lte-softmodem-nos1 rrh_gw oaisim oaisim_nos1 + dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim + pdcchsim pucchsim prachsim syncsim + #all "add_library" definitions + ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB + oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif + oai_eth_transpro + FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA + SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL MIH CN_UTILS + GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB) + if (TARGET ${i}) + add_dependencies(${i} generate_T) + endif() + endforeach(i) endif (${T_TRACER}) ################################################## From 950c1c060e1890948e5ffb22383a358b4f31fcab Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 16 Mar 2017 11:45:07 +0100 Subject: [PATCH 401/571] Correction of dlsch channel calculation --- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 5fb11d2db6..efac41a6f0 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -3375,9 +3375,16 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - float one_over_nb_re = 0; - one_over_nb_re = 1/(nb_rb *12); - int16_t one_over_nb_re_q1_15 = (int16_t)(one_over_nb_re * (float)(1<<15) ); + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) + nre=8; + else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1)) + nre=10; + else + nre=12; + + double one_over_nb_re = 0.0; + one_over_nb_re = 1/((double)(nb_rb*nre)); + int16_t one_over_nb_re_q1_15 = (int16_t)(one_over_nb_re * (double)(1<<15) ); coeff128 = _mm_set_epi16(one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15, one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15); @@ -3399,7 +3406,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, dl_ch128+=2; } else { - avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); + avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15))); dl_ch128+=3; } /* @@ -3411,18 +3418,10 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, */ } - if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==0)) - nre=8; - else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->mode1_flag==1)) - nre=10; - else - nre=12; - avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] + ((int32_t*)&avg128D)[1] + ((int32_t*)&avg128D)[2] + ((int32_t*)&avg128D)[3]); - // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); } From 20b420bb84ee47f5c26fa4e106c15a83c91d621c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Mar 2017 14:44:38 +0100 Subject: [PATCH 402/571] fix compilation for ubuntu 16 This work was done by Laurent Thomas. --- cmake_targets/CMakeLists.txt | 9 +++- .../NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c | 9 +++- .../NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c | 8 ++++ openair2/NETWORK_DRIVER/LITE/device.c | 8 ++++ openair2/NETWORK_DRIVER/MESH/classifier.c | 4 +- openair2/NETWORK_DRIVER/MESH/common.c | 5 +-- openair2/NETWORK_DRIVER/MESH/device.c | 19 +++++--- openair2/NETWORK_DRIVER/MESH/ioctl.c | 2 +- openair2/NETWORK_DRIVER/MESH/local.h | 44 +++++++++---------- openair2/NETWORK_DRIVER/MESH/mesh.c | 6 ++- openair2/NETWORK_DRIVER/MESH/proto_extern.h | 11 +++-- openair2/NETWORK_DRIVER/UE_IP/common.c | 4 +- openair2/NETWORK_DRIVER/UE_IP/device.c | 8 ++++ 13 files changed, 87 insertions(+), 50 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 3687b08a1a..c2b9b82f52 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2099,11 +2099,16 @@ endforeach() # force castxml and clang compilation with gnu89 standard # we can't use cXX standard as pthread_rwlock_t is gnu standard list(APPEND itti_compiler_options "-std=gnu89") - set (ITTI_H ${ITTI_DIR}/intertask_interface_types.h) +if(EXISTS /usr/bin/gccxml) + set(xml_command gccxml ${itti_compiler_options} -fxml=${OPENAIR_BIN_DIR}/messages.xml ${ITTI_H}) +else() + set(xml_command castxml --castxml-gccxml ${itti_compiler_options} ${ITTI_H} -o ${OPENAIR_BIN_DIR}/messages.xml) +endif() + add_custom_command ( OUTPUT ${OPENAIR_BIN_DIR}/messages.xml - COMMAND gccxml ${itti_compiler_options} -fxml=${OPENAIR_BIN_DIR}/messages.xml ${ITTI_H} + COMMAND ${xml_command} DEPENDS ${S1AP_OAI_generated} ${RRC_FULL_DIR}/asn1_constants.h ) diff --git a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c index 7a8bd0f867..77b3c28165 100644 --- a/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c +++ b/openair2/NAS/DRIVER/CELLULAR/NASMT/nasmt_device.c @@ -233,9 +233,12 @@ int nasmt_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } // End debug information - netif_stop_queue(dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif #ifdef NAS_DEBUG_SEND_DETAIL printk("nasmt_hard_start_xmit: step 1\n"); #endif @@ -307,7 +310,11 @@ void nasmt_tx_timeout(struct net_device *dev) printk("nasmt_tx_timeout: begin\n"); //((struct nas_priv *)(dev->priv))->stats.tx_errors++; (gpriv->stats).tx_errors++; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif netif_wake_queue(dev); printk("nasmt_tx_timeout: transmit timed out %s\n",dev->name); } diff --git a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c index aaaa95754d..970600de21 100644 --- a/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c +++ b/openair2/NAS/DRIVER/CELLULAR/NASRG/nasrg_device.c @@ -226,7 +226,11 @@ int nasrg_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif #ifdef NAS_DEBUG_SEND_DETAIL printk("nasrg_hard_start_xmit: step 1\n"); #endif @@ -296,7 +300,11 @@ void nasrg_tx_timeout(struct net_device *dev) printk("nasrg_tx_timeout: begin\n"); // ((struct nas_priv *)(dev->priv))->stats.tx_errors++; (gpriv->stats).tx_errors++; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif netif_wake_queue(dev); printk("nasrg_tx_timeout: transmit timed out %s\n",dev->name); } diff --git a/openair2/NETWORK_DRIVER/LITE/device.c b/openair2/NETWORK_DRIVER/LITE/device.c index 9579ebf249..616af5e145 100644 --- a/openair2/NETWORK_DRIVER/LITE/device.c +++ b/openair2/NETWORK_DRIVER/LITE/device.c @@ -255,7 +255,11 @@ int oai_nw_drv_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif #ifdef OAI_DRV_DEBUG_DEVICE printk("[OAI_IP_DRV][%s] step 1\n", __FUNCTION__); #endif @@ -328,7 +332,11 @@ void oai_nw_drv_tx_timeout(struct net_device *dev) printk("[OAI_IP_DRV][%s] begin\n", __FUNCTION__); // (struct oai_nw_drv_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif netif_wake_queue(dev); printk("[OAI_IP_DRV][%s] transmit timed out %s\n", __FUNCTION__,dev->name); } diff --git a/openair2/NETWORK_DRIVER/MESH/classifier.c b/openair2/NETWORK_DRIVER/MESH/classifier.c index a982faac46..d477ba3ea9 100644 --- a/openair2/NETWORK_DRIVER/MESH/classifier.c +++ b/openair2/NETWORK_DRIVER/MESH/classifier.c @@ -790,7 +790,7 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) dscp, sprotocol, sp->classref, sfct, sp->rab_id); #endif - sp->fct(skb, cx, sp,inst); + sp->fct(skb, cx, sp,inst, NULL); } // if classifier entry match found @@ -808,7 +808,7 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) if (no_connection == 1) printk("NAS_CLASS_SEND: no corresponding connection, so the message is dropped\n"); -#endif NAS_DEBUG_CLASS +#endif /* NAS_DEBUG_CLASS */ // } // while loop over connections diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c index 0a4e3ddfed..6d10abd380 100644 --- a/openair2/NETWORK_DRIVER/MESH/common.c +++ b/openair2/NETWORK_DRIVER/MESH/common.c @@ -321,10 +321,9 @@ void nas_COMMON_receive(uint16_t dlen, //--------------------------------------------------------------------------- // Delete the data -void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp,int inst) +void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *sp,int inst,struct nas_priv *gpriv) { struct nas_priv *priv=netdev_priv(nasdev[inst]); - //--------------------------------------------------------------------------- ++priv->stats.tx_dropped; } @@ -332,7 +331,7 @@ void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct class //--------------------------------------------------------------------------- // Request the transfer of data (QoS SAP) -void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst) +void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst, struct nas_priv *gpriv) { //--------------------------------------------------------------------------- struct pdcp_data_req_header_s pdcph; diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index f28b41fc68..393fe9f9e0 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -124,11 +124,8 @@ void *nas_interrupt(void) int nas_open(struct net_device *dev) { //--------------------------------------------------------------------------- - struct nas_priv *priv=netdev_priv(dev); - printk("OPEN: begin\n"); // MOD_INC_USE_COUNT; - // Address has already been set at init #ifndef PDCP_USE_NETLINK @@ -250,7 +247,11 @@ int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif #ifdef DEBUG_DEVICE printk("HARD_START_XMIT: step 1\n"); #endif @@ -311,7 +312,11 @@ void nas_tx_timeout(struct net_device *dev) printk("TX_TIMEOUT: begin\n"); // (struct nas_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev); +#else dev->trans_start = jiffies; +#endif netif_wake_queue(dev); printk("TX_TIMEOUT: transmit timed out %s\n",dev->name); } @@ -406,8 +411,8 @@ void nas_init(struct net_device *dev) nas_TOOL_imei2iid(IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address) nas_TOOL_imei2iid(IMEI, (uint8_t *)priv->cx[0].iid6); #else - nas_TOOL_imei2iid(nas_IMEI, dev->dev_addr);// IMEI to device address (for stateless autoconfiguration address) - nas_TOOL_imei2iid(nas_IMEI, (uint8_t *)priv->cx[0].iid6); + nas_TOOL_imei2iid((uint8_t *)nas_IMEI, dev->dev_addr); // IMEI to device address (for stateless autoconfiguration address) + nas_TOOL_imei2iid((uint8_t *)nas_IMEI, (uint8_t *)priv->cx[0].iid6); #endif // this is more appropriate for user space soft realtime emulation #else @@ -478,8 +483,8 @@ int init_module (void) if (nasdev[inst]) { nas_mesh_init(inst); //memcpy(nasdev[inst]->dev_addr,&nas_IMEI[0],8); - nas_TOOL_imei2iid(nas_IMEI, nasdev[inst]->dev_addr);// IMEI to device address (for stateless autoconfiguration address) - nas_TOOL_imei2iid(nas_IMEI, (uint8_t *)priv->cx[0].iid6); + nas_TOOL_imei2iid((uint8_t *)nas_IMEI, nasdev[inst]->dev_addr);// IMEI to device address (for stateless autoconfiguration address) + nas_TOOL_imei2iid((uint8_t *)nas_IMEI, (uint8_t *)priv->cx[0].iid6); // TO HAVE DIFFERENT HW @ ((unsigned char*)nasdev[inst]->dev_addr)[7] = ((unsigned char*)nasdev[inst]->dev_addr)[7] + (unsigned char)inst + 1; printk("Setting HW addr for INST %d to : %X%X\n",inst,*((unsigned int *)&nasdev[inst]->dev_addr[0]),*((unsigned int *)&nasdev[inst]->dev_addr[4])); diff --git a/openair2/NETWORK_DRIVER/MESH/ioctl.c b/openair2/NETWORK_DRIVER/MESH/ioctl.c index 7d4bb10b1f..4045908d93 100644 --- a/openair2/NETWORK_DRIVER/MESH/ioctl.c +++ b/openair2/NETWORK_DRIVER/MESH/ioctl.c @@ -853,7 +853,7 @@ int nas_CTL_ioctl(struct net_device *dev, //--------------------------------------------------------------------------- void nas_CTL_send(struct sk_buff *skb, struct cx_entity *cx, - struct classifier_entity *gc) + struct classifier_entity *gc, int inst, struct nas_priv *gpriv) { //--------------------------------------------------------------------------- printk("NAS_CTL_SEND - void \n"); diff --git a/openair2/NETWORK_DRIVER/MESH/local.h b/openair2/NETWORK_DRIVER/MESH/local.h index 8db2b550b0..0e0a581cbc 100644 --- a/openair2/NETWORK_DRIVER/MESH/local.h +++ b/openair2/NETWORK_DRIVER/MESH/local.h @@ -98,6 +98,26 @@ struct cx_entity { int provider_id[MAX_MEASURE_NB]; }; +//#define NAS_RETRY_LIMIT_DEFAULT 5 + +struct nas_priv { + int irq; + struct timer_list timer; + spinlock_t lock; + struct net_device_stats stats; + uint8_t retry_limit; + uint32_t timer_establishment; + uint32_t timer_release; + struct cx_entity cx[NAS_CX_MAX]; + struct classifier_entity *rclassifier[NAS_DSCP_MAX]; // receive classifier + uint16_t nrclassifier; + int sap[NAS_SAPI_MAX]; + struct sock *nl_sk; + uint8_t nlmsg[NAS_MAX_LENGTH+sizeof(struct nlmsghdr)]; + uint8_t xbuffer[NAS_MAX_LENGTH]; // transmition buffer + uint8_t rbuffer[NAS_MAX_LENGTH]; // reception buffer +}; + struct classifier_entity { uint32_t classref; @@ -122,29 +142,7 @@ struct classifier_entity { struct rb_entity *rb_rx; //pointer to rb_entity for receiving (in case of forwarding rule) nasRadioBearerId_t rab_id; // RAB identification for sending nasRadioBearerId_t rab_id_rx; // RAB identification for receiving (in case of forwarding rule) - void (*fct)(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst); -}; - - - -//#define NAS_RETRY_LIMIT_DEFAULT 5 - -struct nas_priv { - int irq; - struct timer_list timer; - spinlock_t lock; - struct net_device_stats stats; - uint8_t retry_limit; - uint32_t timer_establishment; - uint32_t timer_release; - struct cx_entity cx[NAS_CX_MAX]; - struct classifier_entity *rclassifier[NAS_DSCP_MAX]; // receive classifier - uint16_t nrclassifier; - int sap[NAS_SAPI_MAX]; - struct sock *nl_sk; - uint8_t nlmsg[NAS_MAX_LENGTH+sizeof(struct nlmsghdr)]; - uint8_t xbuffer[NAS_MAX_LENGTH]; // transmition buffer - uint8_t rbuffer[NAS_MAX_LENGTH]; // reception buffer + void (*fct)(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst, struct nas_priv *gpriv); }; struct ipversion { diff --git a/openair2/NETWORK_DRIVER/MESH/mesh.c b/openair2/NETWORK_DRIVER/MESH/mesh.c index e934a6eb95..9817428c5e 100644 --- a/openair2/NETWORK_DRIVER/MESH/mesh.c +++ b/openair2/NETWORK_DRIVER/MESH/mesh.c @@ -155,9 +155,10 @@ void nas_mesh_start_default_sclassifier(struct cx_entity *cx,struct rb_entity *r } //--------------------------------------------------------------------------- -void nas_mesh_timer(unsigned long data,struct nas_priv *gpriv) +void nas_mesh_timer(unsigned long data) { //--------------------------------------------------------------------------- + struct nas_priv *gpriv=(struct nas_priv *) data; uint8_t cxi; struct cx_entity *cx; struct rb_entity *rb; @@ -168,7 +169,7 @@ void nas_mesh_timer(unsigned long data,struct nas_priv *gpriv) (gpriv->timer).function=nas_mesh_timer; (gpriv->timer).expires=jiffies+NAS_TIMER_TICK; - (gpriv->timer).data=0L; + (gpriv->timer).data=data; return; @@ -381,6 +382,7 @@ int nas_mesh_DC_send_cx_release_request(struct cx_entity *cx, void nas_mesh_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc, + int inst, struct nas_priv *gpriv) { //--------------------------------------------------------------------------- diff --git a/openair2/NETWORK_DRIVER/MESH/proto_extern.h b/openair2/NETWORK_DRIVER/MESH/proto_extern.h index 4c0b89f60f..a362876f83 100644 --- a/openair2/NETWORK_DRIVER/MESH/proto_extern.h +++ b/openair2/NETWORK_DRIVER/MESH/proto_extern.h @@ -96,7 +96,7 @@ void nas_COMMON_receive(unsigned short dlen, */ void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, - struct classifier_entity *gc,int inst); + struct classifier_entity *gc,int inst, struct nas_priv *gpriv); /** \fn void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst) @@ -108,7 +108,7 @@ void nas_COMMON_QOS_send(struct sk_buff *skb, */ void nas_COMMON_del_send(struct sk_buff *skb, struct cx_entity *cx, - struct classifier_entity *gc,int inst); + struct classifier_entity *gc,int inst, struct nas_priv *gpriv); #ifndef PDCP_USE_NETLINK /** @@ -195,19 +195,18 @@ void nas_mesh_init(int inst //!< Instance ID ); -void nas_mesh_timer(unsigned long data, - struct nas_priv *gpriv); +void nas_mesh_timer(unsigned long data); int nas_mesh_DC_receive(struct cx_entity *cx,struct nas_priv *gpriv); int nas_mesh_GC_receive(struct nas_priv *gpriv); int nas_mesh_DC_send_cx_establish_request(struct cx_entity *cx,struct nas_priv *gpriv); int nas_mesh_DC_send_cx_release_request(struct cx_entity *cx,struct nas_priv *gpriv); -void nas_mesh_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,struct nas_priv *gpriv); +void nas_mesh_DC_send_sig_data_request(struct sk_buff *skb, struct cx_entity *cx, struct classifier_entity *gc,int inst, struct nas_priv *gpriv); // iocontrol.c void nas_CTL_send(struct sk_buff *skb, struct cx_entity *cx, - struct classifier_entity *gc); + struct classifier_entity *gc,int inst, struct nas_priv *gpriv); //int nas_CTL_receive_authentication(struct ipv6hdr *iph, struct cx-entity *cx, unsigned char sapi); int nas_CTL_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 1ea5df0d30..8c3e4557d3 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -123,9 +123,7 @@ skb_p->mark = rb_idP; // LG TEST skb_p->ip_summed = CHECKSUM_NONE; skb_p->ip_summed = CHECKSUM_UNNECESSARY; - - - ipv_p = (struct ipversion*)((void*)&(skb_p->data[hard_header_len])); + ipv_p = (ipversion_t *)((void *)&(skb_p->data[hard_header_len])); switch (ipv_p->version) { diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index cfd7342862..a4f714d4c5 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -243,7 +243,11 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) // End debug information netif_stop_queue(dev_pP); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev_pP); +#else dev_pP->trans_start = jiffies; +#endif #ifdef OAI_DRV_DEBUG_DEVICE printk("[UE_IP_DRV][%s] step 1\n", __FUNCTION__); #endif @@ -315,7 +319,11 @@ void ue_ip_tx_timeout(struct net_device *dev_pP) printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; (priv_p->stats).tx_errors++; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) + netif_trans_update(dev_pP); +#else dev_pP->trans_start = jiffies; +#endif netif_wake_queue(dev_pP); printk("[UE_IP_DRV][%s] transmit timed out %s\n", __FUNCTION__,dev_pP->name); } From 353334f69b963d3911afa0c68941c94c48899599 Mon Sep 17 00:00:00 2001 From: fnabet Date: Thu, 16 Mar 2017 16:45:44 +0100 Subject: [PATCH 403/571] RLC AM Rx PDU Segment changes --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 445 +++++++++++------- 1 file changed, 278 insertions(+), 167 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 048466a1a9..62e67b044b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -35,34 +35,72 @@ boolean_t rlc_am_rx_check_vr_reassemble( const protocol_ctxt_t* const ctxt_pP, const rlc_am_entity_t* const rlc_pP) { - mem_block_t* cursor_p = NULL; - cursor_p = rlc_pP->receiver_buffer.head; + mem_block_t* cursor_p = rlc_pP->receiver_buffer.head; + rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = NULL; + sdu_size_t next_waited_so = 0; boolean_t reassemble = FALSE; if (cursor_p != NULL) { rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; rlc_usn_t sn_ref = pdu_info_p->sn; + if (sn_ref != rlc_pP->vr_r) { + /* Case vrR has advanced from head : most likely case */ + reassemble = TRUE; - } - - /* jump up to vrR */ - while ((RLC_AM_DIFF_SN(pdu_info_p->sn,sn_ref) < RLC_AM_DIFF_SN(rlc_pP->vr_r,sn_ref)) && (cursor_p != NULL)) { - if ((pdu_info_p->rf) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO)) { - ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; + /* Handle first SN if it is made of PDU segments : set them all to be reassembled */ + if (pdu_info_p->rf) { + pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + next_waited_so = 0; + AssertFatal(pdu_cursor_mgnt_p->all_segments_received > 0,"AM Rx Check Reassembly head SN=%d with PDU segments != vrR=%d should be fully received LCID=%d\n", + sn_ref,rlc_pP->vr_r,rlc_pP->channel_id); + while ((cursor_p != NULL) && (pdu_info_p->sn == sn_ref) && (pdu_info_p->so == next_waited_so)) { + if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) { + pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; + } + next_waited_so += pdu_info_p->payload_size; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } } - cursor_p = cursor_p->next; - if (cursor_p != NULL) { - pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - } - } - if ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r)) { + /* Now jump up to vrR */ + while ((RLC_AM_DIFF_SN(pdu_info_p->sn,sn_ref) < RLC_AM_DIFF_SN(rlc_pP->vr_r,sn_ref)) && (cursor_p != NULL)) { + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + + /* Handle vrR if it is made of incomplete PDU Segments */ + if ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r)) { + pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + next_waited_so = 0; + AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly vr=%d should be partly received SNHead=%d LCID=%d\n", + rlc_pP->vr_r,sn_ref,rlc_pP->channel_id); + while ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r) && (pdu_info_p->so == next_waited_so)) { + if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) { + pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; + } + next_waited_so += pdu_info_p->payload_size; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + } + } /* end sn_ref != rlc_pP->vr_r */ + else { /* case vrR = partially received */ - rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); - sdu_size_t next_waited_so = 0; - AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly vr=%d should be partly received LCID=%d\n", + + pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + next_waited_so = 0; + AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly SNHead=vr=%d should be partly received LCID=%d\n", rlc_pP->vr_r,rlc_pP->channel_id); while ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r) && (pdu_info_p->so == next_waited_so)) { if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) { @@ -76,8 +114,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; } } - } - + } /*end sn_ref == rlc_pP->vr_r */ } return reassemble; } @@ -287,9 +324,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( mem_block_t* cursor_p = rlc_pP->receiver_buffer.head; mem_block_t* previous_cursor_p = NULL; mem_block_t* next_cursor_p = NULL; - boolean_t prev_segment_found = FALSE; - boolean_t next_segment_found = FALSE; - uint16_t so_start = 0; + uint16_t so_start_min = 0; uint16_t so_end = 0; uint16_t so_start_segment = pdu_rx_info_p->so; uint16_t so_end_segment = pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1; @@ -334,120 +369,73 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( return RLC_AM_DATA_PDU_STATUS_OK; } + /********************************************/ /* Now handle case cursor->sn = received SN */ - // Filter out SN duplicate + /********************************************/ + rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); + // Filter out SN duplicate if (pdu_cursor_mgnt_p->all_segments_received) { return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; } - // Handle the remaining case : some PDU Segments already received for the same SN - // Try to insert the PDU according to its SO and SO+datalength of stored ones - // First find the segment just before the pdu to insert - while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn)) { - if (pdu_rx_info_p->so < pdu_info_cursor_p->so) { - prev_segment_found = TRUE; - break; - } + // Try to Handle the most likely cases first + if (pdu_info_cursor_p->so == 0) { + /* Loop on stored segments and find the stored segment containing received SOStart */ previous_cursor_p = cursor_p; pdu_info_previous_cursor_p = pdu_info_cursor_p; - cursor_p = cursor_p->next; - if (cursor_p != NULL) { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - } - } - - /* if not previously inserted, it will be put after the last segment if it was not LSF*/ - if (!prev_segment_found) { - if (pdu_info_previous_cursor_p->lsf == 0) { - prev_segment_found = TRUE; - next_segment_found = TRUE; // no more segment after the PDU - next_cursor_p = cursor_p; - AssertFatal(previous_cursor_p->next == next_cursor_p,"AM Rx PDU Segment store at the end error, SN=%d \n",pdu_rx_info_p->sn); - } - else - { - // the segment is duplicate - return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; - } - } - - - // Check that the Segment is not duplicate by scanning stored contiguous segments from previous_cursor_p - if ((previous_cursor_p != NULL) && (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn)) { - - so_start = pdu_info_previous_cursor_p->so; - so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - 1; - - pdu_info_cursor_p = pdu_info_previous_cursor_p; - cursor_p = previous_cursor_p->next; - rlc_am_pdu_info_t* pdu_info_cursor_next_p = NULL; - if (cursor_p != NULL) { - pdu_info_cursor_next_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - } - - while ((cursor_p != NULL) && (pdu_info_cursor_next_p->sn == pdu_rx_info_p->sn) - && (pdu_info_cursor_next_p->so == pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size)) { - so_end += pdu_info_cursor_next_p->payload_size; - pdu_info_cursor_p = pdu_info_cursor_next_p; + while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) + && ((pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size) <= so_start_segment)) { + previous_cursor_p = cursor_p; + pdu_info_previous_cursor_p = pdu_info_cursor_p; cursor_p = cursor_p->next; if (cursor_p != NULL) { - pdu_info_cursor_next_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; } } - /* Now discard the PDU segment if it is within so_start so_end */ - if ((so_start <= so_start_segment) && (so_end_segment <= so_end)) { + // Most likely case : no duplicate, the segment is put after all stored segments which are contiguous + if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn) || (pdu_info_cursor_p->so > so_end_segment)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d SOSTART=%d] PDU SEGMENT INSERTED AFTER PDU SEGMENT WITH SOEND=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn,so_start_segment, + pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - 1); + + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + return RLC_AM_DATA_PDU_STATUS_OK; + } + + // Duplicate case : Resume contiguous scan and update previous_cursor_p + so_start_min = pdu_info_previous_cursor_p->so; + so_end = so_start_min + pdu_info_previous_cursor_p->payload_size; + cursor_p = previous_cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) + && (pdu_info_cursor_p->so == so_end)) { + previous_cursor_p = cursor_p; + pdu_info_previous_cursor_p = pdu_info_cursor_p; + so_end += pdu_info_cursor_p->payload_size; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + + /* Now discard the PDU segment if it is within so_start_min and so_end */ + if ((so_start_min <= so_start_segment) && (so_end_segment < so_end)) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; } - } - - - // Now found the segment which will be right after the pdu to insert - if (!next_segment_found) { - /* special case if SN=vrR and some segments have been previously reassembled and not yet discarded */ - /* update previous_cursor_p up to the last reassembled Segment */ - if ((previous_cursor_p != NULL) && (pdu_rx_info_p->sn == rlc_pP->vr_r)) { - if (((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED) { - pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; - so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size; - cursor_p = previous_cursor_p->next; - if (cursor_p != NULL) { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - } - - while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && - (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED)) { - AssertFatal(pdu_info_cursor_p->so == so_end,"AM Rx PDU Segment store contiguous reassembled error, SN=%d \n",pdu_rx_info_p->sn); - so_end += pdu_info_cursor_p->payload_size; - previous_cursor_p = cursor_p; - cursor_p = cursor_p->next; - if (cursor_p != NULL) { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; - } - } - } - } - - if (previous_cursor_p != NULL) { - cursor_p = previous_cursor_p->next; - } - else { - cursor_p = rlc_pP->receiver_buffer.head; - } + // Discard potential embedded segments in the received PDU segment + // The first one is discontigous next_cursor_p = cursor_p; - if (next_cursor_p != NULL) { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; - } - - // Discard embedded segments in the received PDU segment while ((next_cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && - (pdu_rx_info_p->so + pdu_rx_info_p->payload_size >= pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size)) { + (so_end_segment >= pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size - 1)) { /* Discard the segment */ cursor_p = next_cursor_p; next_cursor_p = next_cursor_p->next; @@ -458,75 +446,196 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; } } - } + cursor_p = next_cursor_p; - /* Now remove duplicate bytes */ - // remove duplicate at the begining, only valid if the segment is to be inserted after a PDU segment of the same SN - if (previous_cursor_p != NULL) { - pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; - if ((pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) && (so_start_segment < pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size)) { + //Remove duplicate at the begining + if (so_start_segment < pdu_info_previous_cursor_p->so) { + so_start_segment = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size; + } + else if (so_start_segment < pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size){ so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - so_start_segment); } - } - // remove duplicate at the end - if (next_cursor_p != NULL) { - pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + // Now remove duplicate at the end, only valid if cursor_p SN has the same received SN + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; - if ((pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && (so_end_segment >= pdu_info_cursor_p->so)) { - so_end_segment = pdu_info_cursor_p->so - 1; + if ((pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && (so_end_segment >= pdu_info_cursor_p->so)) { + so_end_segment = pdu_info_cursor_p->so - 1; + } } - } + AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) && + (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), + " AM RX PDU Segment Duplicate elimination error FirstSO=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n", + pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn); - AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) && - (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), - " AM RX PDU Segment Duplicate elimination error OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n", - pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn); - - /* Last step : Insertion */ - /* If some duplicate bytes had been removed, build a new PDU segment */ - if ((pdu_rx_info_p->so != so_start_segment) || (so_end_segment != pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1)) { - - mem_block_t* trunc_segment = create_new_segment_from_pdu(tb_pP,so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1); - if (trunc_segment != NULL) { - LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1,pdu_rx_info_p->sn); - - if (previous_cursor_p != NULL) { - list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer); - } - else { - list2_insert_before_element(trunc_segment, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer); - } - - /* Free original PDU Segment */ - free_mem_block(tb_pP, __func__); + } // end pdu_info_cursor_p->so == 0 + else { + // Handle most likely case : PDU Segment without duplicate is inserted before first stored PDU segment + if (so_end_segment < pdu_info_cursor_p->so) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d SOSTART=%d SOEND=%d] PDU SEGMENT INSERTED BEFORE PDU SEGMENT WITH SOSTART=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn,so_start_segment,so_end_segment, + pdu_info_cursor_p->so); + list2_insert_before_element(tb_pP, cursor_p, &rlc_pP->receiver_buffer); return RLC_AM_DATA_PDU_STATUS_OK; } - else { - return RLC_AM_DATA_PDU_STATUS_BUFFER_FULL; + + // Handle duplicate case + if (so_start_segment < pdu_info_cursor_p->so) { + // First Case : only duplicate at the end + // Scan for embedded segments to be discarded + next_cursor_p = cursor_p; + while ((next_cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && + (so_end_segment >= pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size - 1)) { + /* Discard the segment */ + cursor_p = next_cursor_p; + next_cursor_p = next_cursor_p->next; + list2_remove_element (cursor_p, &rlc_pP->receiver_buffer); + free_mem_block(cursor_p, __func__); + + if (next_cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + } + } + cursor_p = next_cursor_p; + + // Now remove duplicate at the end, only valid if cursor_p SN has the same received SN + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + + if ((pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && (so_end_segment >= pdu_info_cursor_p->so)) { + so_end_segment = pdu_info_cursor_p->so - 1; + } + } + + AssertFatal((so_start_segment <= so_end_segment) && + (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), + " AM RX PDU Segment Duplicate elimination at the end error FirstSO!=0 SOStart=%d OldSOEnd=%d newSOEnd =%d SN=%d\n", + pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_end_segment,pdu_rx_info_p->sn); + } - } - else - { + else { + // Second Case: Duplicate at the begining and potentially at the end + /* Loop on stored segments and find the stored segment containing received SOStart */ + + previous_cursor_p = cursor_p; + pdu_info_previous_cursor_p = pdu_info_cursor_p; + while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) + && ((pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size) <= so_start_segment)) { + previous_cursor_p = cursor_p; + pdu_info_previous_cursor_p = pdu_info_cursor_p; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + + // Most likely case : no duplicate, the segment is put after all stored segments which are contiguous + if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn) || (pdu_info_cursor_p->so > so_end_segment)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d SOSTART=%d] PDU SEGMENT INSERTED AFTER PDU SEGMENT WITH SOEND=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn,so_start_segment, + pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - 1); + + list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + return RLC_AM_DATA_PDU_STATUS_OK; + } + + // Now look for contiguous segments to check whether the received segment is not fully duplicate + so_start_min = pdu_info_previous_cursor_p->so; + so_end = so_start_min + pdu_info_previous_cursor_p->payload_size; + cursor_p = previous_cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) + && (pdu_info_cursor_p->so == so_end)) { + previous_cursor_p = cursor_p; + pdu_info_previous_cursor_p = pdu_info_cursor_p; + so_end += pdu_info_cursor_p->payload_size; + cursor_p = cursor_p->next; + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + } + } + + /* Now discard the PDU segment if it is within so_start_min and so_end */ + if ((so_start_min <= so_start_segment) && (so_end_segment < so_end)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); + return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; + } + + //Remove duplicate at the begining + if (so_start_segment < pdu_info_previous_cursor_p->so) { + so_start_segment = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size; + } + else if (so_start_segment < pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size){ + so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - so_start_segment); + } + + + // Now Scan for embedded segments to be discarded + next_cursor_p = cursor_p; + while ((next_cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && + (so_end_segment >= pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size - 1)) { + /* Discard the segment */ + cursor_p = next_cursor_p; + next_cursor_p = next_cursor_p->next; + list2_remove_element (cursor_p, &rlc_pP->receiver_buffer); + free_mem_block(cursor_p, __func__); + + if (next_cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + } + } + cursor_p = next_cursor_p; + + // Now remove duplicate at the end, only valid if cursor_p SN has the same received SN + if (cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + + if ((pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && (so_end_segment >= pdu_info_cursor_p->so)) { + so_end_segment = pdu_info_cursor_p->so - 1; + } + } + + AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) && + (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), + " AM RX PDU Segment Duplicate elimination error FirstSO!=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n", + pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn); + } + + } // end pdu_info_cursor_p->so != 0 + + + /* Last step : duplicate bytes had been removed, build a new PDU segment */ + AssertFatal((pdu_rx_info_p->so != so_start_segment) || (so_end_segment != pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), + " AM RX PDU Segment Duplicate elimination error FirstSO!=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n", + pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn); + + mem_block_t* trunc_segment = create_new_segment_from_pdu(tb_pP,so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1); + if (trunc_segment != NULL) { + LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1,pdu_rx_info_p->sn); + if (previous_cursor_p != NULL) { - pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d NOT EMPTY] PDU SEGMENT INSERTED AFTER PDU SN=%d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, - pdu_info_previous_cursor_p->sn); - list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); + list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer); } else { - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d NOT EMPTY] PDU SEGMENT INSERTED BEFORE PDU SN=%d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, - pdu_rx_info_p->sn); - list2_insert_before_element(tb_pP, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer); + list2_insert_before_element(trunc_segment, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer); } + /* Free original PDU Segment */ + free_mem_block(tb_pP, __func__); + return RLC_AM_DATA_PDU_STATUS_OK; } + else { + return RLC_AM_DATA_PDU_STATUS_BUFFER_FULL; + } + } rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu( @@ -1316,10 +1425,12 @@ rlc_am_rx_list_reassemble_rlc_sdus( } /* Reset Management pointers */ - if ((cursor_p != NULL) && - ((((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == RLC_AM_NEXT_SN(sn)) || - (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING))) { + if (cursor_p != NULL) { rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); + /* Next SN must be the same or SN+1 */ + if (RLC_AM_DIFF_SN(rlc_am_rx_pdu_management_p->pdu_info.sn,sn) > 1) { + return; + } } else { return; From d5a9334306b18ead84f6cc9c9ec4bfbc61ac9b37 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 16 Mar 2017 17:06:34 +0100 Subject: [PATCH 404/571] 20MHz improvement for scope (still need to be fixed for 20MHz LLR) and Log --- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 5 ++-- openair1/PHY/LTE_TRANSPORT/proto.h | 2 +- openair1/PHY/TOOLS/lte_phy_scope.c | 28 ++++++++++++++++++--- openair1/PHY/defs.h | 2 +- openair1/SCHED/phy_procedures_lte_ue.c | 28 +++++++++++++-------- 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index a8c9fab621..9f8ee6cec7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -160,7 +160,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_DLSCH_t *dlsch, LTE_DL_UE_HARQ_t *harq_process, - uint8_t frame, + uint32_t frame, uint8_t subframe, uint8_t harq_pid, uint8_t is_crnti, @@ -472,6 +472,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, } start_meas(dlsch_turbo_decoding_stats); + LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); ret = tc (&harq_process->d[r][96], harq_process->c[r], @@ -626,7 +627,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break; - //printf("CRC failed, segment %d\n",r); + LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); err_flag = 1; } } diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index be317712da..409c41da4f 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1268,7 +1268,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, LTE_DL_FRAME_PARMS *lte_frame_parms, LTE_UE_DLSCH_t *dlsch, LTE_DL_UE_HARQ_t *harq_process, - uint8_t frame, + uint32_t frame, uint8_t subframe, uint8_t harq_pid, uint8_t is_crnti, diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 325e9f8215..0a5470e7b8 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -699,7 +699,14 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); - fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); + if (frame_parms->N_RB_DL != 100) + { + fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); + } + else + { + LOG_E(PHY,"PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!"); + } } // PDCCH I/Q of MF Output @@ -708,8 +715,14 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, I[i] = pdcch_comp[2*i]; Q[i] = pdcch_comp[2*i+1]; } - - fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); + if (frame_parms->N_RB_DL != 100) + { + fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); + } + else + { + LOG_E(PHY,"PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!"); + } } // PDSCH LLRs @@ -720,7 +733,14 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword); - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","",""); + if (frame_parms->N_RB_DL != 100) + { + fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","",""); + } + else + { + LOG_E(PHY,"PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!"); + } } // PDSCH I/Q of MF Output diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 921d2be1fc..2720510006 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -896,7 +896,7 @@ typedef struct { time_stats_t rx_dft_stats; time_stats_t dlsch_channel_estimation_stats; time_stats_t dlsch_freq_offset_estimation_stats; - time_stats_t dlsch_decoding_stats; + time_stats_t dlsch_decoding_stats[2]; time_stats_t dlsch_demodulation_stats; time_stats_t dlsch_rate_unmatching_stats; time_stats_t dlsch_turbo_decoding_stats; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 4e5e6cb7b1..a05d445e23 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1991,7 +1991,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", Mod_id, ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, - frame_tx, subframe_tx, + frame_tx%1024, subframe_tx, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, isShortenPucch, ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, @@ -3532,7 +3532,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols); #endif - start_meas(&ue->dlsch_decoding_stats); + start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]); ret = dlsch_decoding(ue, pdsch_vars->llr[0], &ue->frame_parms, @@ -3543,12 +3543,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, harq_pid, pdsch==PDSCH?1:0, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); - stop_meas(&ue->dlsch_decoding_stats); + stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]); LOG_D(PHY," --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_D(PHY," --> Turbo Decoding for CW0 %5.3f\n", - (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", + frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx&0x1].p_time)/(cpuf*1000.0)); + if(is_cw1_active) { @@ -3582,7 +3583,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo); LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols); #endif - start_meas(&ue->dlsch_decoding_stats); + + start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]); + ret1 = dlsch_decoding(ue, pdsch_vars->llr[1], &ue->frame_parms, @@ -3593,12 +3596,13 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, harq_pid, pdsch==PDSCH?1:0, dlsch1->harq_processes[harq_pid]->TBS>256?1:0); - stop_meas(&ue->dlsch_decoding_stats); + stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]); + LOG_D(PHY," --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_D(PHY," --> Turbo Decoding for CW1 %5.3f\n", - (ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); + LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", + frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx&0x1].p_time)/(cpuf*1000.0)); } LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ \n", frame_rx, subframe_rx); @@ -3620,10 +3624,11 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if(dlsch0->rnti != 0xffff) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->round, dlsch0->harq_processes[harq_pid]->mcs, dlsch0->harq_processes[harq_pid]->TBS); } @@ -3632,10 +3637,11 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, } else { if(dlsch0->rnti != 0xffff) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,mcs %d,TBS %d)\n", + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, harq_pid,frame_rx,subframe_rx, dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->round, dlsch0->harq_processes[harq_pid]->mcs, dlsch0->harq_processes[harq_pid]->TBS); } From c6581031d5edf5777dcf942c7ba63579e0bf5507 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 16 Mar 2017 17:37:05 +0100 Subject: [PATCH 405/571] various quick fixes --- openair1/PHY/MODULATION/ofdm_mod.c | 1 - openair1/SCHED/phy_procedures_lte_eNb.c | 2 +- targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 04645eb8c1..f6f0c1f618 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -163,7 +163,6 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input #ifndef __AVX2__ if (fftsize==128) -#else #endif { for (j=0; jUE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits 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", + LOG_D(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", eNB->Mod_id, eNB->CC_id, frame, diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index a98df19cf7..f2d2af55c7 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -128,10 +128,10 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) { /*! \brief Set Gains (TX/RX) on LMSSDR * \param device the hardware to use * \param openair0_cfg openair0 Config structure - * \returns 0 in success + * \returns 0 in success, -1 on error */ int trx_lms_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { - int ret; + int ret = 0; if (openair0_cfg->rx_gain[0] > 70+openair0_cfg->rx_gain_offset[0]) { printf("[LMS] Reduce RX Gain 0 by %f dB\n",openair0_cfg->rx_gain[0]-openair0_cfg->rx_gain_offset[0]-70); From c13d5c21f37f49ea799044ee3dbfdabb3d345c1e Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 16 Mar 2017 18:05:23 +0100 Subject: [PATCH 406/571] added null pointer check for ulsim --- openair1/SCHED/phy_procedures_lte_ue.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 386dd8b52c..e1ee5fa847 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -641,9 +641,9 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id } uint8_t pucch_ack_payload[2]; - if (get_ack(&ue->frame_parms, + if ((ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack) && (get_ack(&ue->frame_parms, ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, - subframe_tx,pucch_ack_payload,0) > 0) + subframe_tx,pucch_ack_payload,0) > 0)) { is_sr_an_subframe = 1; } @@ -2261,12 +2261,14 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui } // reset DL ACK/NACK status - reset_ack(&ue->frame_parms, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, - subframe_tx, - ue->ulsch[eNB_id]->o_ACK,0); + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0] != NULL) + reset_ack(&ue->frame_parms, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, + subframe_tx, + ue->ulsch[eNB_id]->o_ACK,0); - reset_ack(&ue->frame_parms, + if (ue->dlsch_SI[eNB_id] != NULL) + reset_ack(&ue->frame_parms, ue->dlsch_SI[eNB_id]->harq_ack, subframe_tx, ue->ulsch[eNB_id]->o_ACK,0); From 7f9b19cce843c3fb4288b2bdd0a174fa03f1e6fc Mon Sep 17 00:00:00 2001 From: fnabet Date: Fri, 17 Mar 2017 10:52:59 +0100 Subject: [PATCH 407/571] UE Issue224 fix on TCRNTI --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index c4e379b45a..fc57b6eda7 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -5144,6 +5144,7 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, uint16_t rnti, + uint16_t tc_rnti, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, @@ -5206,6 +5207,13 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, } else //CRNTI { + if (rnti == tc_rnti) { + //fix for standalone Contention Resolution Id + pdlsch0_harq->DCINdi = (uint8_t)-1; + LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n", + rnti,harq_pid,pdlsch0_harq->DCINdi); + } + // DCI has been toggled or this is the first transmission if (ndi1!=pdlsch0_harq->DCINdi) { @@ -5992,6 +6000,7 @@ int generate_ue_dlsch_params_from_dci(int frame, frame_parms, subframe, rnti, + tc_rnti, si_rnti, ra_rnti, p_rnti, @@ -6092,6 +6101,7 @@ int generate_ue_dlsch_params_from_dci(int frame, frame_parms, subframe, rnti, + tc_rnti, si_rnti, ra_rnti, p_rnti, From 19bd4d8cf7693c13fd47f6dabc956c25ed48e782 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Mar 2017 16:08:25 +0100 Subject: [PATCH 408/571] test setup v2: simplify softmodem tests variable definition --- cmake_targets/autotests/v2/main.py | 64 +++++++----------------------- 1 file changed, 15 insertions(+), 49 deletions(-) diff --git a/cmake_targets/autotests/v2/main.py b/cmake_targets/autotests/v2/main.py index 14e5442720..8ed24da76c 100644 --- a/cmake_targets/autotests/v2/main.py +++ b/cmake_targets/autotests/v2/main.py @@ -280,55 +280,21 @@ machine_list.wait_all_free() # run eNB softmodem tests # ############################################################################## -tests = { - 'b210' : { - 'alu' : { - 'fdd' : { - '5' : { - 'bandrich' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}, - 'sony' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}, - '10' : { - 'bandrich' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}, - 'sony' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}, - '20' : { - 'bandrich' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}, - 'sony' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}}, - 'tdd' : { - '5' : { - '3276' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}, - '10' : { - '3276' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}, - '20' : { - '3276' : { - 'tcp' : { 'ul': False, 'dl' : False }, - 'udp' : { 'ul': False, 'dl' : False }}}}}, - 'openair-cn' : {} - }, - 'x310' : { - 'alu' : {}, - 'openair-cn' : {} - }, - 'exmimo2' : { - 'alu' : {}, - 'openair-cn' : {} - } -} +tests = {} +for a in { 'b210', 'x310', 'exmimo2' }: + tests[a] = {} + for b in { 'alu', 'openair-cn' }: + tests[a][b] = {} + for c in { 'fdd', 'tdd' }: + tests[a][b][c] = {} + for d in { '5', '10', '20' }: + tests[a][b][c][d] = {} + for e in { 'bandrich', 'sony', '3276' }: + tests[a][b][c][d][e] = {} + for f in { 'tcp', 'udp' }: + tests[a][b][c][d][e][f] = {} + for g in { 'dl', 'ul' }: + tests[a][b][c][d][e][f][g] = False todo_tests_ids = [] for test in todo_tests: From a19a27ff33557a8e3dbb45d9cea538d3ae88a7b4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 17 Mar 2017 18:58:55 +0100 Subject: [PATCH 409/571] test setup v2: add RRU/RRC tests - README.txt modified - tests added in test_case_list.xml (only for test setup v2) - python code modified - configuration files added --- cmake_targets/autotests/README.txt | 14 ++ cmake_targets/autotests/test_case_list.xml | 13 ++ cmake_targets/autotests/v2/alu_test.py | 177 ++++++++++++++-- .../v2/config/rcc.band7.tm1.if4p5.10MHz.conf | 192 +++++++++++++++++ .../v2/config/rcc.band7.tm1.if4p5.20MHz.conf | 192 +++++++++++++++++ .../v2/config/rcc.band7.tm1.if4p5.5MHz.conf | 192 +++++++++++++++++ ...ru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf | 194 ++++++++++++++++++ ...ru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf | 194 ++++++++++++++++++ ...rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf | 194 ++++++++++++++++++ cmake_targets/autotests/v2/main.py | 15 +- 10 files changed, 1357 insertions(+), 20 deletions(-) create mode 100644 cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf create mode 100644 cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf create mode 100644 cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf create mode 100644 cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf create mode 100644 cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf create mode 100644 cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index 6cd0307b48..b94d99bff7 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -239,6 +239,20 @@ Obj.# Case# Test# Description 01 75 04 Band 7 FDD 10MHz DL Throughput for 300 sec for 1TX/1RX 01 75 05 Band 7 FDD 20MHz DL Throughput for 300 sec for 1TX/1RX +01 76 lte-softmodem + RRU (NGFI IF4P5, UDP) tests with B210 RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX +01 76 00 Band 7 FDD 5MHz UL Throughput (UDP) for 300 sec for 1TX/1RX +01 76 01 Band 7 FDD 10MHz UL Throughput (UDP) for 300 sec for 1TX/1RX +01 76 02 Band 7 FDD 20MHz UL Throughput (UDP) for 300 sec for 1TX/1RX +01 76 03 Band 7 FDD 5MHz DL Throughput (UDP) for 300 sec for 1TX/1RX +01 76 04 Band 7 FDD 10MHz DL Throughput (UDP) for 300 sec for 1TX/1RX +01 76 05 Band 7 FDD 20MHz DL Throughput (UDP) for 300 sec for 1TX/1RX +01 76 06 Band 7 FDD 5MHz UL Throughput (TCP) for 300 sec for 1TX/1RX +01 76 07 Band 7 FDD 10MHz UL Throughput (TCP) for 300 sec for 1TX/1RX +01 76 08 Band 7 FDD 20MHz UL Throughput (TCP) for 300 sec for 1TX/1RX +01 76 09 Band 7 FDD 5MHz DL Throughput (TCP) for 300 sec for 1TX/1RX +01 76 10 Band 7 FDD 10MHz DL Throughput (TCP) for 300 sec for 1TX/1RX +01 76 11 Band 7 FDD 20MHz DL Throughput (TCP) for 300 sec for 1TX/1RX + 01 80 lte-softmodem + RRU (NGFI) tests with BladeRF RF as eNB and ALU EPC w/ Bandrich COTS UE for TX/1RX 01 80 00 Band 7 FDD 5MHz UL Throughput for 300 sec for 1TX/1RX 01 80 01 Band 7 FDD 10MHz UL Throughput for 300 sec for 1TX/1RX diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index c55a29c975..0c80e960a4 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -8664,6 +8664,19 @@ c 10 + + + + + + + + + + + + + diff --git a/cmake_targets/autotests/v2/alu_test.py b/cmake_targets/autotests/v2/alu_test.py index 8ba6ab857a..762e414a95 100644 --- a/cmake_targets/autotests/v2/alu_test.py +++ b/cmake_targets/autotests/v2/alu_test.py @@ -9,18 +9,24 @@ class alu_test: openair, user, password, log_subdir, - env): - self.epc_machine = epc - self.enb_machine = enb - self.ue_machine = ue - self.openair_dir = openair - self.oai_user = user - self.oai_password = password - self.env = env + env, + enb_rru = "", + enb_rcc = ""): + self.epc_machine = epc + self.enb_machine = enb + self.ue_machine = ue + self.openair_dir = openair + self.oai_user = user + self.oai_password = password + self.env = env + self.enb_rru_machine = enb_rru + self.enb_rcc_machine = enb_rcc - self.task_hss = None - self.task_enb = None - self.task_ue = None + self.task_hss = None + self.task_enb = None + self.task_ue = None + self.task_rru_enb = None + self.task_rcc_enb = None self.logdir = openair + '/cmake_targets/autotests/log/' + log_subdir quickshell('mkdir -p ' + self.logdir) @@ -40,6 +46,10 @@ class alu_test: self.task_enb.kill() if self.task_ue != None and self.task_ue.alive(): self.task_ue.kill() + if self.task_rru_enb != None and self.task_rru_enb.alive(): + self.task_rru_enb.kill() + if self.task_rcc_enb != None and self.task_rcc_enb.alive(): + self.task_rcc_enb.kill() ########################################################################## # start_epc @@ -101,7 +111,7 @@ class alu_test: ########################################################################## # compile_enb ########################################################################## - def compile_enb(self, build_arguments): + def compile_enb(self, build_arguments, log_suffix=""): log("INFO: ALU test: compile softmodem on " + self.enb_machine) envcomp = list(self.env) envcomp.append('BUILD_ARGUMENTS="' + build_arguments + '"') @@ -120,7 +130,8 @@ class alu_test: self.oai_user, self.oai_password, envcomp, - self.logdir + "/compile_softmodem." + self.enb_machine, + self.logdir + "/compile_softmodem." + log_suffix + \ + self.enb_machine, post_action=post_action) ret = task.wait() if ret != 0: @@ -162,6 +173,62 @@ class alu_test: #not sure if we have to quit here or not #os._exit(1) + ########################################################################## + # start_enb_rru_rcc + ########################################################################## + def start_enb_rru_rcc(self, rru_config_file, rcc_config_file): + #copy wanted configuration files + quickshell("sshpass -p " + self.oai_password + + " scp config/" + rru_config_file + " " + + self.oai_user + "@" + self.enb_rru_machine+":/tmp/enb.conf") + quickshell("sshpass -p " + self.oai_password + + " scp config/" + rcc_config_file + " " + + self.oai_user + "@" + self.enb_rcc_machine+":/tmp/enb.conf") + + #run RRU/RCC softmodem + log("INFO: ALU test: run RRU softmodem with configuration file " + + rru_config_file) + self.task_rru_enb = Task("actions/run_enb.bash", + "run_RRU_softmodem", + self.enb_rru_machine, + self.oai_user, + self.oai_password, + self.env, + self.logdir + "/run_softmodem." + self.enb_rru_machine, + event=self.event) + self.task_rru_enb.waitlog('[RRH] binding to') + log("INFO: ALU test: run RCC softmodem with configuration file " + + rcc_config_file) + self.task_rcc_enb = Task("actions/run_enb.bash", + "run_RCC_softmodem", + self.enb_rcc_machine, + self.oai_user, + self.oai_password, + self.env, + self.logdir + "/run_softmodem." + self.enb_rcc_machine, + event=self.event) + self.task_rcc_enb.waitlog('[BBU] local ip addr') + #wait for RRU and RCC to be connected + self.task_rru_enb.waitlog('devices ok (eNB_thread_asynch_rx)') + + ########################################################################## + # stop_enb_rru_rcc + ########################################################################## + def stop_enb_rru_rcc(self): + log("INFO: ALU test: stop RRU/RCC softmodem") + self.task_rru_enb.sendnow("%c" % 3) + ret = self.task_rru_enb.wait() + if ret != 0: + log("ERROR: ALU test: RRU softmodem failed") + #not sure if we have to quit here or not + #os._exit(1) + self.task_rcc_enb.sendnow("%c" % 3) + ret = self.task_rcc_enb.wait() + if ret != 0: + log("ERROR: ALU test: RCC softmodem failed") + #not sure if we have to quit here or not + #os._exit(1) + ########################################################################## # start_ue ########################################################################## @@ -185,7 +252,9 @@ class alu_test: self.event.clear() - if ( not self.task_enb.alive() or + if ( (self.task_enb != None and not self.task_enb.alive()) or + (self.task_rru_enb!=None and not self.task_rru_enb.alive()) or + (self.task_rcc_enb!=None and not self.task_rcc_enb.alive()) or not self.task_hss.alive() or not self.task_ue.alive()): log("ERROR: ALU test: eNB, HSS or UE task died") @@ -250,14 +319,20 @@ class alu_test: self.event.wait() log("DEBUG: event.wait() done") - if ( not self.task_enb.alive() or + if ( (self.task_enb != None and not self.task_enb.alive()) or + (self.task_rru_enb!=None and not self.task_rru_enb.alive()) or + (self.task_rcc_enb!=None and not self.task_rcc_enb.alive()) or not self.task_hss.alive() or not self.task_ue.alive()): log("ERROR: unexpected task exited, test failed, kill all") if task_traffic_client.alive(): task_traffic_client.kill() - if self.task_enb.alive(): + if (self.task_enb != None and self.task_enb.alive()): self.task_enb.kill() + if (self.task_rru_enb != None and self.task_rru_enb.alive()): + self.task_rru_enb.kill() + if (self.task_rcc_enb != None and self.task_rcc_enb.alive()): + self.task_rcc_enb.kill() if self.task_ue.alive(): self.task_ue.kill() @@ -277,7 +352,9 @@ class alu_test: self.event.clear() - if ( not self.task_enb.alive() or + if ( (self.task_enb != None and not self.task_enb.alive()) or + (self.task_rru_enb!=None and not self.task_rru_enb.alive()) or + (self.task_rcc_enb!=None and not self.task_rcc_enb.alive()) or not self.task_hss.alive() or not self.task_ue.alive()): log("ERROR: ALU test: eNB, HSS or UE task died") @@ -334,8 +411,6 @@ class alu_test: ############################################################################## def run_b210_alu(tests, openair_dir, oai_user, oai_password, env): - if not do_tests(tests['b210']['alu']): - return #compile eNB (two cases: one for FDD and one for TDD) @@ -365,6 +440,44 @@ def run_b210_alu(tests, openair_dir, oai_user, oai_password, env): log("ERROR: ALU test failed: eNB compilation failed: " + str(e)) return + #compile RRU/RCC eNB + + if do_tests(tests['remote b210']['alu']['fdd']): + #RRU + alu = alu_test(epc='amerique', ue='stevens', + openair=openair_dir, + user=oai_user, password=oai_password, + log_subdir='enb_tests/remote_b210_alu/compile_enb_rru', + env=env, + #hack: set 'enb' to reuse 'compile_enb' + enb = 'superserver', + enb_rru = 'superserver', enb_rcc = 'starsky') + + try: + alu.compile_enb("--eNB -x -c -w USRP -t ETHERNET", + log_suffix='rru.') + except BaseException, e: + log("ERROR: ALU test failed: RRU eNB compilation failed: "+str(e)) + return + + #RCC + alu = alu_test(epc='amerique', ue='stevens', + openair=openair_dir, + user=oai_user, password=oai_password, + log_subdir='enb_tests/remote_b210_alu/compile_enb_rcc', + env=env, + #hack: set 'enb' to reuse 'compile_enb' + enb = 'starsky', + enb_rru = 'superserver', enb_rcc = 'starsky') + + try: + alu.compile_enb("--eNB -w None -t ETHERNET", + log_suffix='rcc.') + except BaseException, e: + log("ERROR: ALU test failed: RCC eNB compilation failed: "+str(e)) + return + + #run tests udp_dl_bandwidth = { "5" : "15M", @@ -410,3 +523,29 @@ def run_b210_alu(tests, openair_dir, oai_user, oai_password, env): except BaseException, e: log("ERROR: ALU test failed: " + str(e)) alu.finish() + if do_tests(tests['remote b210']['alu'][mode][bw]): + log("INFO: ALU test: run RRU/RCC tests for bandwidth " + bw + " MHz") + ctest = tests['remote b210']['alu'][mode][bw] + alu = alu_test(epc='amerique', enb='', ue=ue_machine[mode], + openair=openair_dir, + user=oai_user, password=oai_password, + log_subdir='enb_tests/remote_b210_alu/' + bw, + env=env, + enb_rru='superserver', enb_rcc='starsky') + try: + alu.start_epc() + alu.start_enb_rru_rcc("rru.band7.tm1.if4p5." + bw + "MHz.udp.usrpb210.conf", + "rcc.band7.tm1.if4p5." + bw + "MHz.conf") + for ue in ('bandrich', '3276'): + if ue in ctest and do_tests(ctest[ue]): + alu.start_ue(ue) + if do_tests(ctest[ue]['tcp']['dl']): alu.dl_tcp(ue) + if do_tests(ctest[ue]['tcp']['ul']): alu.ul_tcp(ue) + if do_tests(ctest[ue]['udp']['dl']): alu.dl_udp(ue, udp_dl_bandwidth[bw]) + if do_tests(ctest[ue]['udp']['ul']): alu.ul_udp(ue, udp_ul_bandwidth[bw]) + alu.stop_ue(ue) + alu.stop_enb_rru_rcc() + alu.stop_epc() + except BaseException, e: + log("ERROR: ALU test failed: " + str(e)) + alu.finish() diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf new file mode 100644 index 0000000000..81eed5f4b1 --- /dev/null +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf @@ -0,0 +1,192 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.18/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.18/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth1"; + remote_address = "10.10.10.157"; + local_address = "10.10.10.18"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf new file mode 100644 index 0000000000..4b4190f8ce --- /dev/null +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf @@ -0,0 +1,192 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.18/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.18/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth1"; + remote_address = "10.10.10.157"; + local_address = "10.10.10.18"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf new file mode 100644 index 0000000000..99b9a66226 --- /dev/null +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf @@ -0,0 +1,192 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.18/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.18/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth1"; + remote_address = "10.10.10.157"; + local_address = "10.10.10.18"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf new file mode 100644 index 0000000000..4cc40b6d84 --- /dev/null +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf @@ -0,0 +1,194 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RRU_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth3"; + remote_address = "10.10.10.18"; + local_address = "10.10.10.157"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf new file mode 100644 index 0000000000..787cedb18d --- /dev/null +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf @@ -0,0 +1,194 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RRU_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth3"; + remote_address = "10.10.10.18"; + local_address = "10.10.10.157"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf new file mode 100644 index 0000000000..d9d46bf944 --- /dev/null +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf @@ -0,0 +1,194 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = "1"; + + mobile_country_code = "208"; + + mobile_network_code = "92"; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RRU_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -104; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.11"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.215/24"; + ENB_INTERFACE_NAME_FOR_S1U = "eth3"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.215/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + rrh_gw_config = ( + { + local_if_name = "eth3"; + remote_address = "10.10.10.18"; + local_address = "10.10.10.157"; + local_port = 50000; #for raw option local port must be the same to remote + remote_port = 50000; + rrh_gw_active = "yes"; + tr_preference = "udp_if4p5"; + rf_preference = "usrp_b200"; + iq_txshift = 4; + tx_sample_advance = 80; + tx_scheduling_advance = 9; + if_compression = "alaw"; + } + ); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + } +); diff --git a/cmake_targets/autotests/v2/main.py b/cmake_targets/autotests/v2/main.py index 8ed24da76c..da38432dbc 100644 --- a/cmake_targets/autotests/v2/main.py +++ b/cmake_targets/autotests/v2/main.py @@ -281,7 +281,7 @@ machine_list.wait_all_free() ############################################################################## tests = {} -for a in { 'b210', 'x310', 'exmimo2' }: +for a in { 'b210', 'remote b210', 'x310', 'exmimo2' }: tests[a] = {} for b in { 'alu', 'openair-cn' }: tests[a][b] = {} @@ -407,6 +407,19 @@ for test in todo_tests_ids: if test=='017504':log('WARNING: skip test ' + test) #TODO if test=='017505':log('WARNING: skip test ' + test) #TODO + if test=='017600':tests['remote b210']['alu']['fdd'][ '5']['bandrich']['udp']['ul']=True + if test=='017601':tests['remote b210']['alu']['fdd']['10']['bandrich']['udp']['ul']=True + if test=='017602':tests['remote b210']['alu']['fdd']['20']['bandrich']['udp']['ul']=True + if test=='017603':tests['remote b210']['alu']['fdd'][ '5']['bandrich']['udp']['dl']=True + if test=='017604':tests['remote b210']['alu']['fdd']['10']['bandrich']['udp']['dl']=True + if test=='017605':tests['remote b210']['alu']['fdd']['20']['bandrich']['udp']['dl']=True + if test=='017606':tests['remote b210']['alu']['fdd'][ '5']['bandrich']['tcp']['ul']=True + if test=='017607':tests['remote b210']['alu']['fdd']['10']['bandrich']['tcp']['ul']=True + if test=='017608':tests['remote b210']['alu']['fdd']['20']['bandrich']['tcp']['ul']=True + if test=='017609':tests['remote b210']['alu']['fdd'][ '5']['bandrich']['tcp']['dl']=True + if test=='017610':tests['remote b210']['alu']['fdd']['10']['bandrich']['tcp']['dl']=True + if test=='017611':tests['remote b210']['alu']['fdd']['20']['bandrich']['tcp']['dl']=True + if test=='018000':log('WARNING: skip test ' + test) #TODO if test=='018001':log('WARNING: skip test ' + test) #TODO if test=='018002':log('WARNING: skip test ' + test) #TODO From 1c57eadd336add1fc3e354325b84a54f09fc500a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 18 Mar 2017 00:09:04 +0100 Subject: [PATCH 410/571] fix: remove useless test One check introduced by previous commit was not necessary. --- openair1/SCHED/phy_procedures_lte_ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index e1ee5fa847..3084b207c2 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -641,9 +641,9 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id } uint8_t pucch_ack_payload[2]; - if ((ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack) && (get_ack(&ue->frame_parms, + if (get_ack(&ue->frame_parms, ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, - subframe_tx,pucch_ack_payload,0) > 0)) + subframe_tx,pucch_ack_payload,0) > 0) { is_sr_an_subframe = 1; } From 1e2f952a9cc898970b51458ceee57b350e1f69c8 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Mon, 20 Mar 2017 09:18:02 +0100 Subject: [PATCH 411/571] Remove to frequent log in 20 MHz --- openair1/PHY/TOOLS/lte_phy_scope.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 0a5470e7b8..13beb469e4 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -705,7 +705,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } else { - LOG_E(PHY,"PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!"); + LOG_D(PHY,"UE PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -721,7 +721,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } else { - LOG_E(PHY,"PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!"); + LOG_D(PHY,"UE PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -739,7 +739,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } else { - LOG_E(PHY,"PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!"); + LOG_D(PHY,"UE PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } From fd1e01579c90819db09dfff182500a6c86fabb43 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 10:28:11 +0100 Subject: [PATCH 412/571] bugfix: set cpuf in oaisim --- targets/SIMU/USER/oaisim.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 7c1ea1a3c8..f1b3944a16 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1332,6 +1332,8 @@ main (int argc, char **argv) if (oai_emulation.info.opp_enabled == 1) reset_opp_meas_oaisim (); + cpuf=get_cpu_freq_GHz(); + init_time (); init_slot_isr (); From 41dda3d3de411c652606d2c44dc5fd17901ae107 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 10:38:25 +0100 Subject: [PATCH 413/571] integration fix: let dlsim_tm4 compile again The variables that were duplicated per processing thread were adapted. 'cpuf' was defined and initialized. --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 70 ++++++++++++------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index b45bfdf324..26d51d049d 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -68,6 +68,7 @@ extern uint8_t interf_unaw_shift; PHY_VARS_eNB *eNB; PHY_VARS_UE *UE; +double cpuf; int otg_enabled=0; /*the following parameters are used to control the processing times calculations*/ @@ -296,7 +297,7 @@ int main(int argc, char **argv) int threequarter_fs=0; - + cpuf = get_cpu_freq_GHz(); opp_enabled=1; // to enable the time meas @@ -867,7 +868,7 @@ int main(int argc, char **argv) // bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); } - UE->pdcch_vars[0]->crnti = n_rnti; + UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti; UE->transmission_mode[eNB_id]=transmission_mode; if (UE->transmission_mode[eNB_id] !=4) UE->measurements.rank[eNB_id]=0; @@ -2087,7 +2088,8 @@ int main(int argc, char **argv) reset_meas(&UE->dlsch_freq_offset_estimation_stats); reset_meas(&UE->rx_dft_stats); reset_meas(&UE->dlsch_llr_stats); - reset_meas(&UE->dlsch_decoding_stats); + reset_meas(&UE->dlsch_decoding_stats[0]); + reset_meas(&UE->dlsch_decoding_stats[1]); reset_meas(&UE->dlsch_turbo_decoding_stats); reset_meas(&UE->dlsch_deinterleaving_stats); reset_meas(&UE->dlsch_rate_unmatching_stats); @@ -3488,9 +3490,7 @@ int main(int argc, char **argv) UE->UE_mode[0] = PUSCH; start_meas(&UE->dlsch_rx_pdcch_stats); - rx_pdcch(&UE->common_vars, - UE->pdcch_vars, - &UE->frame_parms, + rx_pdcch(UE, trials, subframe, 0, @@ -3500,7 +3500,7 @@ int main(int argc, char **argv) stop_meas(&UE->dlsch_rx_pdcch_stats); // overwrite number of pdcch symbols - UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; + UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols; dci_cnt = dci_decoding_procedure(UE, dci_alloc_rx,1, @@ -3544,14 +3544,14 @@ int main(int argc, char **argv) 0, P_RNTI, transmission_mode<7?0:transmission_mode, - UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0)==0)) { + UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0)==0)) { dump_dci(&UE->frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword[0]= get_G(&eNB->frame_parms, UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, - UE->pdcch_vars[0]->num_pdcch_symbols, + UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); @@ -3561,7 +3561,7 @@ int main(int argc, char **argv) UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, get_Qm(UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, - UE->pdcch_vars[1]->num_pdcch_symbols, + UE->pdcch_vars[subframe&0x1][1]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); @@ -3570,7 +3570,7 @@ int main(int argc, char **argv) rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs); */ - printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); + printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); dlsch_active = 1; // what does it indicates??? } else { @@ -3591,8 +3591,8 @@ int main(int argc, char **argv) } } } else { //dci_flag == 0 - UE->pdcch_vars[0]->crnti = n_rnti; - UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; + UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti; + UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols; if (round == 0) { UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1; @@ -3613,7 +3613,7 @@ int main(int argc, char **argv) 0, P_RNTI, transmission_mode<7?0:transmission_mode, - UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0); + UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0); break; case 3: @@ -3631,7 +3631,7 @@ int main(int argc, char **argv) 0, P_RNTI, transmission_mode<7?0:transmission_mode, - UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0); + UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0); //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); break; case 4: @@ -3647,7 +3647,7 @@ int main(int argc, char **argv) 0, P_RNTI, transmission_mode<7?0:transmission_mode, - UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0); + UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0); break; case 5: @@ -3664,7 +3664,7 @@ int main(int argc, char **argv) 0, P_RNTI, transmission_mode<7?0:transmission_mode, - UE->pdcch_vars[0]->crnti_is_temporary? UE->pdcch_vars[0]->crnti: 0); + UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0); break; } dlsch_active = 1; @@ -3690,7 +3690,7 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_llr_stats); - for (m=UE->pdcch_vars[0]->num_pdcch_symbols; mpdcch_vars[subframe&0x1][0]->num_pdcch_symbols; mpdcch_vars[0]->num_pdcch_symbols)?1:0, + (m==UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols)?1:0, rx_type, i_mod, UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1){ @@ -3849,7 +3849,7 @@ int main(int argc, char **argv) subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); - start_meas(&UE->dlsch_decoding_stats); + start_meas(&UE->dlsch_decoding_stats[subframe&0x1]); ret[TB] = dlsch_decoding(UE, UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword], &UE->frame_parms, @@ -3859,7 +3859,7 @@ int main(int argc, char **argv) subframe, UE->dlsch[subframe&0x1][0][TB]->current_harq_pid, 1,llr8_flag); - stop_meas(&UE->dlsch_decoding_stats); + stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]); #ifdef DEBUG_HARQ printf("[DLSIM] ret[%d] = %d\n", TB, ret[TB]); #endif @@ -4208,7 +4208,7 @@ int main(int argc, char **argv) subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); - start_meas(&UE->dlsch_decoding_stats); + start_meas(&UE->dlsch_decoding_stats[subframe&0x1]); ret[1] = dlsch_decoding(UE, UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], @@ -4219,7 +4219,7 @@ int main(int argc, char **argv) subframe, UE->dlsch[subframe&0x1][0][1]->current_harq_pid, 1,llr8_flag); - stop_meas(&UE->dlsch_decoding_stats); + stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]); #ifdef DEBUG_HARQ printf("[DLSIM] Decoding TB1 in SIC: ret[1] = %d, round sic %d\n", ret[1], round_sic); @@ -4419,11 +4419,11 @@ int main(int argc, char **argv) */ //pdcch_vars - write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[subframe&0x1][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4); + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[subframe&0x1][eNB_id]->llr,2400,1,4); if (round == 3) exit(-1); } @@ -4534,7 +4534,7 @@ int main(int argc, char **argv) double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0; double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_dec = (double)UE->dlsch_decoding_stats[subframe&0x1].p_time/cpu_freq_GHz/1000.0; if (t_tx > t_tx_max) @@ -4891,12 +4891,12 @@ int main(int argc, char **argv) printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3); printf("DLSCH unscrambling time :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0, UE->dlsch_unscrambling_stats.trials); - std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->dlsch_decoding_stats.trials - pow((double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000,2)); + std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/UE->dlsch_decoding_stats[subframe&0x1].trials - pow((double)UE->dlsch_decoding_stats[subframe&0x1].diff/UE->dlsch_decoding_stats[subframe&0x1].trials/cpu_freq_GHz/1000,2)); printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f) :%f us (%d trials, max %f)\n", eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter[0]/iter_trials[0], - (double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats.trials, - (double)UE->dlsch_decoding_stats.max/cpu_freq_GHz/1000.0); + (double)UE->dlsch_decoding_stats[subframe&0x1].diff/UE->dlsch_decoding_stats[subframe&0x1].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[subframe&0x1].trials, + (double)UE->dlsch_decoding_stats[subframe&0x1].max/cpu_freq_GHz/1000.0); printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); @@ -5194,7 +5194,7 @@ int main(int argc, char **argv) UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, UE->dlsch_unscrambling_stats.trials, - UE->dlsch_decoding_stats.trials + UE->dlsch_decoding_stats[subframe&0x1].trials ); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;", get_time_meas_us(&eNB->phy_proc_tx), @@ -5207,7 +5207,7 @@ int main(int argc, char **argv) get_time_meas_us(&UE->dlsch_rx_pdcch_stats), 3*get_time_meas_us(&UE->dlsch_llr_stats), get_time_meas_us(&UE->dlsch_unscrambling_stats), - get_time_meas_us(&UE->dlsch_decoding_stats) + get_time_meas_us(&UE->dlsch_decoding_stats[subframe&0x1]) ); //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); @@ -5247,7 +5247,7 @@ int main(int argc, char **argv) UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, UE->dlsch_unscrambling_stats.trials, - UE->dlsch_decoding_stats.trials); + UE->dlsch_decoding_stats[subframe&0x1].trials); */ printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate[0]); break; From f2e9e3f2dc3779f4d8bb82073d0179b5d17e9271 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 10:40:26 +0100 Subject: [PATCH 414/571] integration fix: let dlsim compile again Same as previous commit 41dda3d3de411c652606d2c44dc5fd17901ae107 but for dlsim. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index ac26a9259c..e29c60fead 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -57,6 +57,8 @@ PHY_VARS_eNB *eNB; PHY_VARS_UE *UE; +double cpuf; + int otg_enabled=0; /*the following parameters are used to control the processing times calculations*/ double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */ @@ -1409,6 +1411,8 @@ int main(int argc, char **argv) #endif printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + cpuf = cpu_freq_GHz; + //signal(SIGSEGV, handler); //signal(SIGABRT, handler); @@ -2259,7 +2263,8 @@ int main(int argc, char **argv) reset_meas(&UE->dlsch_channel_estimation_stats); reset_meas(&UE->dlsch_freq_offset_estimation_stats); reset_meas(&UE->rx_dft_stats); - reset_meas(&UE->dlsch_decoding_stats); + reset_meas(&UE->dlsch_decoding_stats[0]); + reset_meas(&UE->dlsch_decoding_stats[1]); reset_meas(&UE->dlsch_turbo_decoding_stats); reset_meas(&UE->dlsch_deinterleaving_stats); reset_meas(&UE->dlsch_rate_unmatching_stats); @@ -2708,7 +2713,7 @@ int main(int argc, char **argv) double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0; double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_dec = (double)UE->dlsch_decoding_stats[subframe&1].p_time/cpu_freq_GHz/1000.0; if (t_tx > t_tx_max) t_tx_max = t_tx; @@ -2921,12 +2926,12 @@ int main(int argc, char **argv) printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3); printf("DLSCH unscrambling time :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0, UE->dlsch_unscrambling_stats.trials); - std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->dlsch_decoding_stats.trials - pow((double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000,2)); + std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[subframe&1].diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/UE->dlsch_decoding_stats[subframe&1].trials - pow((double)UE->dlsch_decoding_stats[subframe&1].diff/UE->dlsch_decoding_stats[subframe&1].trials/cpu_freq_GHz/1000,2)); printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f) :%f us (%d trials, max %f)\n", eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials, - (double)UE->dlsch_decoding_stats.diff/UE->dlsch_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats.trials, - (double)UE->dlsch_decoding_stats.max/cpu_freq_GHz/1000.0); + (double)UE->dlsch_decoding_stats[subframe&1].diff/UE->dlsch_decoding_stats[subframe&1].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[subframe&1].trials, + (double)UE->dlsch_decoding_stats[subframe&1].max/cpu_freq_GHz/1000.0); printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); @@ -3114,7 +3119,7 @@ int main(int argc, char **argv) UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, UE->dlsch_unscrambling_stats.trials, - UE->dlsch_decoding_stats.trials + UE->dlsch_decoding_stats[subframe&1].trials ); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;", get_time_meas_us(&eNB->phy_proc_tx), @@ -3127,7 +3132,7 @@ int main(int argc, char **argv) get_time_meas_us(&UE->dlsch_rx_pdcch_stats), 3*get_time_meas_us(&UE->dlsch_llr_stats), get_time_meas_us(&UE->dlsch_unscrambling_stats), - get_time_meas_us(&UE->dlsch_decoding_stats) + get_time_meas_us(&UE->dlsch_decoding_stats[subframe&1]) ); //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); @@ -3167,7 +3172,7 @@ int main(int argc, char **argv) UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, UE->dlsch_unscrambling_stats.trials, - UE->dlsch_decoding_stats.trials); + UE->dlsch_decoding_stats[subframe&1].trials); */ printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); break; From 5014b84c3024bbad423064ec7f279e8a42423a44 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 10:43:50 +0100 Subject: [PATCH 415/571] integration fix: let ulsim compile again + minor modification in dlsim_tm4 --- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 4 ++-- openair1/SIMULATION/LTE_PHY/ulsim.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 26d51d049d..57742c5e13 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -297,8 +297,6 @@ int main(int argc, char **argv) int threequarter_fs=0; - cpuf = get_cpu_freq_GHz(); - opp_enabled=1; // to enable the time meas #if defined(__arm__) @@ -317,6 +315,8 @@ int main(int argc, char **argv) #else cpu_freq_GHz = get_cpu_freq_GHz(); #endif + cpuf = cpu_freq_GHz; + printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); //signal(SIGSEGV, handler); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 49dd395d11..3564f597ef 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -50,6 +50,7 @@ PHY_VARS_eNB *eNB; PHY_VARS_UE *UE; +double cpuf; @@ -280,6 +281,7 @@ int main(int argc, char **argv) opp_enabled=1; // to enable the time meas cpu_freq_GHz = (double)get_cpu_freq_GHz(); + cpuf = cpu_freq_GHz; printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); From 7ffc20426b684cbfb6bdca5d42c2679153f3be14 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 11:00:41 +0100 Subject: [PATCH 416/571] integration fix: let simulators compile again - pucchsim - prachsim - pdcchsim - pbchsim - mbmssim Mostly, add and initialize the variable 'cpuf'. Also, pdcchsim was calling rx_pdcch with wrong arguments. --- openair1/SIMULATION/LTE_PHY/mbmssim.c | 3 +++ openair1/SIMULATION/LTE_PHY/pbchsim.c | 4 ++++ openair1/SIMULATION/LTE_PHY/pdcchsim.c | 7 ++++--- openair1/SIMULATION/LTE_PHY/prachsim.c | 4 +++- openair1/SIMULATION/LTE_PHY/pucchsim.c | 4 +++- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c index fb2fa506ac..69de4aee9f 100644 --- a/openair1/SIMULATION/LTE_PHY/mbmssim.c +++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c @@ -50,6 +50,7 @@ PHY_VARS_eNB *eNB; PHY_VARS_UE *UE; +double cpuf; DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_1E[2]; #define UL_RB_ALLOC 0x1ff; @@ -118,6 +119,8 @@ int main(int argc, char **argv) #endif */ + cpuf = get_cpu_freq_GHz(); + logInit(); number_of_cards = 1; diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c index 806a206a2b..f117879d6b 100644 --- a/openair1/SIMULATION/LTE_PHY/pbchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c @@ -50,6 +50,8 @@ PHY_VARS_eNB *eNB,*eNB1,*eNB2; PHY_VARS_UE *UE; +double cpuf; + #define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13 int32_t *dummybuf[4]; @@ -116,6 +118,8 @@ int main(int argc, char **argv) char title[255]; #endif + cpuf = get_cpu_freq_GHz(); + logInit(); number_of_cards = 1; diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index ebc178a55e..4c50aaa5d5 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -50,6 +50,7 @@ PHY_VARS_UE *UE; #define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2) #define DLSCH_RB_ALLOC ((uint16_t)0x1fbf) // igore DC component,RB13 +double cpuf; DCI_PDU DCI_pdu; @@ -457,6 +458,8 @@ int main(int argc, char **argv) number_of_cards = 1; + cpuf = get_cpu_freq_GHz(); + logInit(); @@ -1088,9 +1091,7 @@ int main(int argc, char **argv) UE->pdcch_vars[0][0]->crnti = n_rnti; // printf("Doing RX : num_pdcch_symbols at TX %d\n",num_pdcch_symbols); - rx_pdcch(&UE->common_vars, - UE->pdcch_vars[0], - &UE->frame_parms, + rx_pdcch(UE, trial, subframe, 0, diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c index 7acc07528c..52339cdc5d 100644 --- a/openair1/SIMULATION/LTE_PHY/prachsim.c +++ b/openair1/SIMULATION/LTE_PHY/prachsim.c @@ -45,7 +45,7 @@ PHY_VARS_UE *UE; #define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13 - +double cpuf; extern uint16_t prach_root_sequence_map0_3[838]; @@ -99,6 +99,8 @@ int main(int argc, char **argv) int NCS_config = 1,rootSequenceIndex=0; int threequarter_fs = 0; + cpuf = get_cpu_freq_GHz(); + logInit(); number_of_cards = 1; diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index 77bfcb18cf..d1db3c29e1 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -47,7 +47,7 @@ PHY_VARS_UE *UE; #define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13 - +double cpuf; int main(int argc, char **argv) { @@ -101,6 +101,8 @@ int main(int argc, char **argv) number_of_cards = 1; + cpuf = get_cpu_freq_GHz(); + while ((c = getopt (argc, argv, "har:pf:g:n:s:S:x:y:z:N:F:T:R:")) != -1) { switch (c) { case 'a': From 1218cc8f65d6b8d5fa572ab3a60a12a77e22c491 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 11:15:57 +0100 Subject: [PATCH 417/571] bugfix: fix dump_dlsch2 the argument 'coded_bits_per_codeword' has to be an array in case of several codewords. The calling sites have been adapted. Today, only the first index is used, so calling sites where 'coded_bits_per_codeword' is an integer pass the address of it. It is expected that 'dump_dlsch2' will check in the future that there is one or two codewords and only access 'coded_bits_per_codeword[1]' when it's sure there are really two codewords. --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- openair1/SCHED/defs.h | 2 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 4 ++-- openair1/SIMULATION/LTE_PHY/dlsim_tm7.c | 4 ++-- openair1/SIMULATION/LTE_PHY/syncsim.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index efac41a6f0..cb1129f8cb 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -5880,7 +5880,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, #ifdef USER_MODE -void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid) +void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) { unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; char fname[32],vname[32]; @@ -5959,7 +5959,7 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint16_t coded_ sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round); sprintf(vname,"dl%d_r%d_llr",eNB_id,round); - write_output(fname,vname, ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0],coded_bits_per_codeword,1,0); + write_output(fname,vname, ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0); sprintf(fname,"dlsch%d_r%d_mag1.m",eNB_id,round); sprintf(vname,"dl%d_r%d_mag1",eNB_id,round); write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1); diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index ac2d7957f2..fd4b868382 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -511,7 +511,7 @@ void dump_dlsch(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe); -void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, uint16_t coded_bits_per_codeword,int round, unsigned char harq_pid); +void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe, unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid); /*@}*/ diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index e29c60fead..6acfc646c7 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2548,7 +2548,7 @@ int main(int argc, char **argv) //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); @@ -2649,7 +2649,7 @@ int main(int argc, char **argv) } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); //write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 6c306d6d46..3055e99b07 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -3504,7 +3504,7 @@ PMI_FEEDBACK: UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round); //dump_dlsch2(UE,eNB_id_i,coded_bits_per_codeword); write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); @@ -3721,7 +3721,7 @@ PMI_FEEDBACK: } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round); /* write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index 6e74f7bc01..97a94a1a43 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -406,7 +406,7 @@ int main(int argc, char **argv) DCI_ALLOC_t dci_alloc[8],dci_alloc_rx[8]; uint16_t n_rnti=1234,dci_cnt; - uint16_t coded_bits_per_codeword; + unsigned int coded_bits_per_codeword; double tmp_re,tmp_im,foff,deltaF=0.0,cs,sn; uint32_t carrier_freq[4]= {1907600000,1907600000,1907600000,1907600000}; uint32_t rf_mode[4] = {55759,55759,55759,55759}; @@ -1739,7 +1739,7 @@ int main(int argc, char **argv) PHY_vars_UE[0]->lte_ue_pdcch_vars[0]->num_pdcch_symbols, 0); - dump_dlsch2(PHY_vars_UE[0],0,0,coded_bits_per_codeword); + dump_dlsch2(PHY_vars_UE[0],0,0,&coded_bits_per_codeword); } } else { From e2350103f4e67bce9704c26a50bc23eee5b80409 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 13:32:45 +0100 Subject: [PATCH 418/571] hotfix: LLR was calling qam64_qam16_avx2 instead of qam64_qam64_avx2 Not sure of this one, to be checked by TCL. --- openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 48b777fcde..e2de78f9ca 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -8847,7 +8847,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, memcpy(ch_mag_i_256i, ch_mag_i, len*4); memcpy(rho_256i, rho, len*4); -#if 1 +#if 0 qam64_qam16_avx2((short *)rxF_256i, (short *)rxF_i_256i, (short *)ch_mag_256i, From d0a51bec01e2a199fe3a3d08f96092abf5784131 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 20 Mar 2017 13:45:29 +0100 Subject: [PATCH 419/571] hotfix: put back "system" for UE to setup its IP settings We'll need to to do it in a separate thread/process. To be done. In the meantime, put it back. It impacts oaisim. --- openair3/NAS/UE/ESM/esm_ebr_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 31f215e359..bfa4a04cc8 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -286,7 +286,7 @@ int esm_ebr_context_create( LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); - //if (system(command_line)) ; /* TODO: what to do? */ + if (system(command_line)) ; /* TODO: what to do? */ break; From e2d46f8040bc1e693e58a7bb44171abd1f03818e Mon Sep 17 00:00:00 2001 From: Calisson Date: Mon, 20 Mar 2017 09:49:03 +0100 Subject: [PATCH 420/571] adding mechanism for SRS scheduling of multiple UEs. --- openair1/SCHED/defs.h | 2 +- openair1/SCHED/phy_procedures_lte_ue.c | 4 +-- openair1/SIMULATION/LTE_PHY/ulsim.c | 3 +- openair2/ENB_APP/enb_config.c | 2 +- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 31 +++++++++++++++++-- .../CONF/enb.band7.tm1.usrpb210.conf | 6 ++-- 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 4aad186f76..f283014af7 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -379,7 +379,7 @@ void process_timing_advance_rar(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,ui unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb); -void phy_reset_ue( PHY_VARS_UE *ue ); +void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); /*! \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch. For diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index ca9ee8df7c..41ea1339d5 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -258,14 +258,14 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1); } - -void phy_reset_ue(PHY_VARS_UE *ue) +void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) { // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later // for more flexibility uint8_t i,j,k,s; + PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; //[NUMBER_OF_CONNECTED_eNB_MAX][2]; for(i=0; iUE_mode[eNB_id]=PUSCH; for (trials = 0; trialssrs_enable[j]) { printf( "\tsrs_BandwidthConfig for CC %d:\t%ld:\n",j,enb_properties.properties[i]->srs_BandwidthConfig[j]); - printf( "\tsrs_BandwidthConfig for CC %d:\t%ld:\n",j,enb_properties.properties[i]->srs_SubframeConfig[j]); + printf( "\tsrs_SubframeConfig for CC %d:\t%ld:\n",j,enb_properties.properties[i]->srs_SubframeConfig[j]); printf( "\tsrs_ackNackST for CC %d:\t%d:\n",j,enb_properties.properties[i]->srs_ackNackST[j]); printf( "\tsrs_MaxUpPts for CC %d:\t%d:\n",j,enb_properties.properties[i]->srs_MaxUpPts[j]); } diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index f6a5a0c9df..08584c883b 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -99,7 +99,7 @@ int errno; # endif #endif -//#define XER_PRINT +#define XER_PRINT extern Enb_properties_array_t enb_properties; typedef struct xer_sprint_string_s { @@ -1593,8 +1593,33 @@ do_RRCConnectionSetup( SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=2; - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0; + if (frame_parms->frame_type==FDD) { + if (enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]!=2) + LOG_W(RRC,"This code has been optimized for SRS Subframe Config 2, but current config is %d. Expect undefined behaviour!\n", + enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]); + if (ue_context_pP->local_uid >=10) + LOG_W(RRC,"This code has been optimized for up to 10 UEs, but current UE_id is %d. Expect undefined behaviour!\n", + ue_context_pP->local_uid); + //the current code will allow for 20 UEs - to be revised for more + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=8+2*(ue_context_pP->local_uid/2); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb= ue_context_pP->local_uid%2; + } + else { + if (enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]!=6) { + LOG_W(RRC,"This code has been optimized for SRS Subframe Config 6 and TDD config 3, but current configs are %d and %d. Expect undefined behaviour!\n", + enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id], + enb_properties.properties[ctxt_pP->module_id]->tdd_config[CC_id]); + } + if (ue_context_pP->local_uid >=6) + LOG_W(RRC,"This code has been optimized for up to 4 UEs, but current UE_id is %d. Expect undefined behaviour!\n", + ue_context_pP->local_uid); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=18+ue_context_pP->local_uid/2; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb= ue_context_pP->local_uid%2; + } + LOG_W(RRC,"local UID %d, srs ConfigIndex %d, TransmissionComb %d\n",ue_context_pP->local_uid, + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift= SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index a9933a6444..878daf4cf8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -62,9 +62,9 @@ eNBs = pusch_nDMRS1 = 1; phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; - srs_enable = "ENABLE"; + srs_enable = "DISABLE"; srs_BandwidthConfig = 2; - srs_SubframeConfig = 3; + srs_SubframeConfig = 2; srs_ackNackST = "DISABLE"; srs_MaxUpPts = "DISABLE"; @@ -137,7 +137,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.70"; + mme_ip_address = ( { ipv4 = "192.168.12.26"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; From 98efcd522077cb4cd3c08b6c50cf1d0cf1ec1191 Mon Sep 17 00:00:00 2001 From: Calisson Date: Tue, 21 Mar 2017 09:37:08 +0100 Subject: [PATCH 421/571] fixing a bug related to SRS procedures --- openair1/SCHED/phy_procedures_lte_eNb.c | 5 +++-- .../GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index b9fdc5d226..36d6ca8ff9 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -843,6 +843,7 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC 1<L); is_srs_pos = is_srs_occasion_common(fp,pdcch_alloc2ul_frame(fp,frame,subframe),pdcch_alloc2ul_subframe(fp,subframe)); + /* if (is_srs_pos && eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup) { srsConfigIndex = eNB->soundingrs_ul_config_dedicated[UE_id].srs_ConfigIndex; compute_srs_pos(fp->frame_type, srsConfigIndex, &srsPeriodicity, &srsOffset); @@ -850,10 +851,10 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC do_srs = 1; } } - LOG_D(PHY,"frame %d (%d), subframe %d (%d), UE_id %d: is_srs_pos %d, do_SRS %d, index %d, period %d, offset %d \n", frame,pdcch_alloc2ul_frame(fp,frame,subframe),subframe,pdcch_alloc2ul_subframe(fp,subframe), UE_id,is_srs_pos,do_srs,srsConfigIndex,srsPeriodicity,srsOffset); + */ generate_eNB_ulsch_params_from_dci(eNB, proc, @@ -865,7 +866,7 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC 0, P_RNTI, CBA_RNTI, - do_srs); // do_srs + is_srs_pos); LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n", eNB->Mod_id,frame,subframe,dci_alloc->rnti, diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf index 024be3b775..a33c2eb41b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpb210.conf @@ -62,11 +62,11 @@ eNBs = pusch_nDMRS1 = 1; phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; - srs_SubframeConfig =; - srs_ackNackST =; - srs_MaxUpPts =;*/ + srs_enable = "ENABLE"; + srs_BandwidthConfig = 2; + srs_SubframeConfig = 7; + srs_ackNackST = "DISABLE"; + srs_MaxUpPts = "DISABLE"; pusch_p0_Nominal = -90; pusch_alpha = "AL1"; From 7685cf18118bc3f6042c202959d8049596029500 Mon Sep 17 00:00:00 2001 From: Calisson Date: Tue, 21 Mar 2017 14:05:16 +0100 Subject: [PATCH 422/571] fixing srs in msg3. now all SRS subframe configs work. --- openair1/PHY/LTE_TRANSPORT/rar_tools.c | 17 +++++++++++++++-- openair1/SCHED/phy_procedures_lte_eNb.c | 11 +++-------- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 16 ++++++++-------- .../CONF/enb.band7.tm1.usrpb210.conf | 2 +- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c index 60fa52df16..2629c6ba7f 100644 --- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c @@ -31,6 +31,7 @@ */ #include "PHY/defs.h" #include "PHY/extern.h" +#include "SCHED/defs.h" #include "SCHED/extern.h" #include "LAYER2/MAC/defs.h" #include "SCHED/defs.h" @@ -69,6 +70,7 @@ int generate_eNB_ulsch_params_from_rar(unsigned char *rar_pdu, uint8_t cqireq; uint16_t *RIV2nb_rb_LUT, *RIV2first_rb_LUT; uint16_t RIV_max; + uint16_t use_srs=0; LOG_D(PHY,"[eNB][RAPROC] generate_eNB_ulsch_params_from_rar: subframe %d (harq_pid %d)\n",subframe,harq_pid); @@ -133,8 +135,6 @@ int generate_eNB_ulsch_params_from_rar(unsigned char *rar_pdu, ulsch->beta_offset_ri_times8 = 10; ulsch->beta_offset_harqack_times8 = 16; - - ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1); ulsch->rnti = (((uint16_t)rar[4])<<8)+rar[5]; if (ulsch->harq_processes[harq_pid]->round == 0) { @@ -151,6 +151,19 @@ int generate_eNB_ulsch_params_from_rar(unsigned char *rar_pdu, ulsch->harq_processes[harq_pid]->round++; } + + ulsch->Msg3_active = 1; + + get_Msg3_alloc(frame_parms, + subframe, + frame, + &ulsch->Msg3_frame, + &ulsch->Msg3_subframe); + + use_srs = is_srs_occasion_common(frame_parms,ulsch->Msg3_frame,ulsch->Msg3_subframe); + ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); + ulsch->harq_processes[harq_pid]->srs_active = use_srs; + #ifdef DEBUG_RAR msg("ulsch ra (eNB): harq_pid %d\n",harq_pid); msg("ulsch ra (eNB): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 36d6ca8ff9..821cfef7df 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -822,10 +822,12 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int frame = proc->frame_tx; int subframe = proc->subframe_tx; + /* uint16_t srsPeriodicity=0; uint16_t srsOffset=0; uint16_t srsConfigIndex=0; uint16_t do_srs=0; + */ uint16_t is_srs_pos=0; LOG_D(PHY, @@ -1006,17 +1008,10 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d generate_eNB_ulsch_params_from_rar(DLSCH_pdu, frame, - (subframe), + subframe, eNB->ulsch[(uint32_t)UE_id], fp); - eNB->ulsch[(uint32_t)UE_id]->Msg3_active = 1; - - get_Msg3_alloc(fp, - subframe, - frame, - &eNB->ulsch[(uint32_t)UE_id]->Msg3_frame, - &eNB->ulsch[(uint32_t)UE_id]->Msg3_subframe); LOG_D(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n", frame, subframe, diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 08584c883b..13fafcade8 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -1594,26 +1594,26 @@ do_RRCConnectionSetup( physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; if (frame_parms->frame_type==FDD) { - if (enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]!=2) - LOG_W(RRC,"This code has been optimized for SRS Subframe Config 2, but current config is %d. Expect undefined behaviour!\n", + if (enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]!=0) + LOG_W(RRC,"This code has been optimized for SRS Subframe Config 0, but current config is %d. Expect undefined behaviour!\n", enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]); - if (ue_context_pP->local_uid >=10) + if (ue_context_pP->local_uid >=20) LOG_W(RRC,"This code has been optimized for up to 10 UEs, but current UE_id is %d. Expect undefined behaviour!\n", ue_context_pP->local_uid); //the current code will allow for 20 UEs - to be revised for more - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=8+2*(ue_context_pP->local_uid/2); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=7+ue_context_pP->local_uid/2; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb= ue_context_pP->local_uid%2; } else { - if (enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]!=6) { - LOG_W(RRC,"This code has been optimized for SRS Subframe Config 6 and TDD config 3, but current configs are %d and %d. Expect undefined behaviour!\n", + if (enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id]!=7) { + LOG_W(RRC,"This code has been optimized for SRS Subframe Config 7 and TDD config 3, but current configs are %d and %d. Expect undefined behaviour!\n", enb_properties.properties[ctxt_pP->module_id]->srs_SubframeConfig[CC_id], enb_properties.properties[ctxt_pP->module_id]->tdd_config[CC_id]); } if (ue_context_pP->local_uid >=6) - LOG_W(RRC,"This code has been optimized for up to 4 UEs, but current UE_id is %d. Expect undefined behaviour!\n", + LOG_W(RRC,"This code has been optimized for up to 6 UEs, but current UE_id is %d. Expect undefined behaviour!\n", ue_context_pP->local_uid); - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=18+ue_context_pP->local_uid/2; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=17+ue_context_pP->local_uid/2; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb= ue_context_pP->local_uid%2; } LOG_W(RRC,"local UID %d, srs ConfigIndex %d, TransmissionComb %d\n",ue_context_pP->local_uid, diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf index 878daf4cf8..d563f3af7e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.usrpb210.conf @@ -64,7 +64,7 @@ eNBs = phich_resource = "ONESIXTH"; srs_enable = "DISABLE"; srs_BandwidthConfig = 2; - srs_SubframeConfig = 2; + srs_SubframeConfig = 0; srs_ackNackST = "DISABLE"; srs_MaxUpPts = "DISABLE"; From 9d3eed3b433bf2c3b7a31451076778c70f7c4816 Mon Sep 17 00:00:00 2001 From: Calisson Date: Tue, 21 Mar 2017 15:02:20 +0100 Subject: [PATCH 423/571] fixing ulsim --- cmake_targets/lte-simulators/CMakeLists.txt | 1 - openair1/SIMULATION/LTE_PHY/ulsim.c | 19 +++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index 79ff0bfbd2..5ed4d93d80 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -3,7 +3,6 @@ set(PACKAGE_NAME "unitary_tests_simulators") set(PHYSIM True) set(RF_BOARD None) set(XFORMS True) -set(ENABLE_ITTI False) set(DEBUG_PHY False) set(MU_RECIEVER False) diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 013b65c249..d5f1407224 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -42,6 +42,7 @@ #include "SCHED/vars.h" #include "LAYER2/MAC/vars.h" #include "OCG_vars.h" +#include "intertask_interface_init.h" #include "unitary_defs.h" @@ -285,11 +286,15 @@ int main(int argc, char **argv) printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); - logInit(); + /* + // enable these lines if you need debug info + // however itti will catch all signals, so ctrl-c won't work anymore + // alternatively you can disable ITTI completely in CMakeLists.txt + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); set_comp_log(PHY,LOG_DEBUG,LOG_MED,1); - set_glog(LOG_INFO,LOG_MED); - + set_glog(LOG_DEBUG,LOG_MED); + */ while ((c = getopt (argc, argv, "hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF")) != -1) { switch (c) { @@ -571,6 +576,11 @@ int main(int argc, char **argv) osf, 0); + // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE + PHY_vars_UE_g = (PHY_VARS_UE***)malloc(sizeof(PHY_VARS_UE**)); + PHY_vars_UE_g[0] = (PHY_VARS_UE**) malloc(sizeof(PHY_VARS_UE*)); + PHY_vars_UE_g[0][0] = UE; + if (nb_rb_set == 0) nb_rb = eNB->frame_parms.N_RB_UL; @@ -585,8 +595,6 @@ int main(int argc, char **argv) txdata = UE->common_vars.txdata; - - nsymb = (eNB->frame_parms.Ncp == NORMAL) ? 14 : 12; @@ -934,7 +942,6 @@ int main(int argc, char **argv) ndi=0; - PHY_vars_UE_g = UE; phy_reset_ue(0,0,0); UE->UE_mode[eNB_id]=PUSCH; From fe0b84ddaf0d38a46f79a94551f8b3056bc21b41 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 22 Mar 2017 12:38:03 +0100 Subject: [PATCH 424/571] fix: revert ue_eurecom_test_sfr.conf to its previous state Keys/IDs have been inadvertently changed. --- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index 05db6be4d1..84ec59a36b 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -86,14 +86,14 @@ UE0: }; SIM: { - MSIN="000001234"; - USIM_API_K="000102030405060708090A0B0C0D0E0F"; + MSIN="0100001111"; + USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; OPC="C42449363BBAD02B66D16BC975D77CC1"; - MSISDN="000000000000";//"33611123456"; + MSISDN="33611123456"; }; # Home PLMN Selector with Access Technology - HPLMN= "00101"; + HPLMN= "20893"; # User controlled PLMN Selector with Access Technology UCPLMN_LIST = (); From 238b22e5b52c45ca72b64d55af9a6789265ca82f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 23 Mar 2017 09:23:07 +0100 Subject: [PATCH 425/571] fixes for IF5 This work was done by Bruno Mongazon. --- targets/RT/USER/lte-enb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 21d34d40b1..b88b094f08 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1724,7 +1724,7 @@ void init_eNB_proc(int inst) { proc->CC_id = CC_id; proc->instance_cnt_synch = -1; - proc->first_rx=2; + proc->first_rx=1; proc->first_tx=1; proc->frame_offset = 0; @@ -2060,6 +2060,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst printf("Exiting, cannot initialize transport protocol\n"); exit(-1); } + malloc_IF5_buffer(eNB); break; case NGFI_RRU_IF4p5: eNB->do_precoding = 0; @@ -2149,6 +2150,7 @@ void init_eNB(eNB_func_t node_function[], eNB_timing_t node_timing[],int nb_inst printf("Exiting, cannot initialize transport protocol\n"); exit(-1); } + malloc_IF5_buffer(eNB); break; case NGFI_RCC_IF4p5: eNB->do_precoding = 0; From 89f747a218768b0eec97222a3b9b9d3cb6cf7a55 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 23 Mar 2017 10:40:47 +0100 Subject: [PATCH 426/571] minor fixes --- targets/RT/USER/lte-softmodem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 03f6ba1a2e..741425c895 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -319,8 +319,8 @@ void help (void) { printf(" --ue-rxgain set UE RX gain\n"); printf(" --ue-rxgain-off external UE amplifier offset\n"); printf(" --ue-txgain set UE TX gain\n"); - printf(" --ue-nb-ant-rx set UE number of rx antennas "); - printf(" --ue-scan_carrier set UE to scan around carrier\n"); + printf(" --ue-nb-ant-rx set UE number of rx antennas\n"); + printf(" --ue-scan-carrier set UE to scan around carrier\n"); printf(" --dlsch-demod-shift dynamic shift for LLR compuation for TM3/4 (default 0)\n"); printf(" --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n"); printf(" --mmapped-dma sets flag for improved EXMIMO UE performance\n"); From cff9149920249b7923dc51f03eb93c5b4bf13f47 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 23 Mar 2017 12:34:24 +0100 Subject: [PATCH 427/571] fix issue 227 - UE IP settings disrupts realtime see https://gitlab.eurecom.fr/oai/openairinterface5g/issues/227 When the UE connects to the eNodeB and receives its IP address from the network, it calls system() to set it in the linux kernel world. This call is not done in a realtime thread, but in the NAS, which uses its own thread, independent of the realtime processing. In some situations this totally disrupts realtime processing. It is difficult to know precisely why that happens, but it seems that calling fork(), as system() does, in a multi-threaded program is not a good idea. (So say several people on the internet.) It is not clear why the softmodem is impacted, but it seems that fork() is really what triggers the disruption. Several tests lead to that conclusion. To fix the problem, we create a child background process very early in main() (before anything else basically). Then instead of calling system(), the main process sends the string to the background process. The background process gets the string, passes it to system() and reports the success/failure back to the main process. This solution involves a lot of system calls, but calling system() in the first place is not cheap either. As long as no realtime thread uses this mechanism, things should be fine. Time will tell. --- cmake_targets/CMakeLists.txt | 2 + cmake_targets/at_commands/CMakeLists.txt | 1 + common/utils/system.c | 186 +++++++++++++++++++++++ common/utils/system.h | 39 +++++ openair3/NAS/UE/ESM/esm_ebr_context.c | 14 +- targets/RT/USER/lte-softmodem.c | 4 + targets/SIMU/USER/oaisim.c | 3 + 7 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 common/utils/system.c create mode 100644 common/utils/system.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index d7cd81cf58..dd2eec6d2f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1769,6 +1769,7 @@ add_executable(lte-softmodem ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c ${GTPU_need_ITTI} ${HW_SOURCE} ${TRANSPORT_SOURCE} @@ -1900,6 +1901,7 @@ add_executable(oaisim ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c ${GTPU_need_ITTI} ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${HW_SOURCE} diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index 61d1565bac..db49a9181d 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -716,6 +716,7 @@ ADD_EXECUTABLE(at_nas_ue ${OPENAIR_NAS_DIR}/UE/UEprocess.c ${OPENAIR_NAS_DIR}/UE/nas_proc.c ${OPENAIR_NAS_DIR}/UE/nas_user.c ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c ) target_link_libraries (at_nas_ue diff --git a/common/utils/system.c b/common/utils/system.c new file mode 100644 index 0000000000..52fb950e37 --- /dev/null +++ b/common/utils/system.c @@ -0,0 +1,186 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* This module provides a separate process to run system(). + * The communication between this process and the main processing + * is done through unix pipes. + * + * Motivation: the UE sets its IP address using system() and + * that disrupts realtime processing in some cases. Having a + * separate process solves this problem. + */ + +#include "system.h" +#include +#include +#include +#include +#include + +#define MAX_COMMAND 4096 + +static int command_pipe_read; +static int command_pipe_write; +static int result_pipe_read; +static int result_pipe_write; + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + +static int module_initialized = 0; + +/********************************************************************/ +/* util functions */ +/********************************************************************/ + +static void lock_system(void) +{ + if (pthread_mutex_lock(&lock) != 0) { + printf("pthread_mutex_lock fails\n"); + abort(); + } +} + +static void unlock_system(void) +{ + if (pthread_mutex_unlock(&lock) != 0) { + printf("pthread_mutex_unlock fails\n"); + abort(); + } +} + +static void write_pipe(int p, char *b, int size) +{ + while (size) { + int ret = write(p, b, size); + if (ret <= 0) exit(0); + b += ret; + size -= ret; + } +} + +static void read_pipe(int p, char *b, int size) +{ + while (size) { + int ret = read(p, b, size); + if (ret <= 0) exit(0); + b += ret; + size -= ret; + } +} + +/********************************************************************/ +/* background process */ +/********************************************************************/ + +/* This function is run by background process. It waits for a command, + * runs it, and reports status back. It exits (in normal situations) + * when the main process exits, because then a "read" on the pipe + * will return 0, in which case "read_pipe" exits. + */ +static void background_system_process(void) +{ + int len; + int ret; + char command[MAX_COMMAND+1]; + + while (1) { + read_pipe(command_pipe_read, (char*)&len, sizeof(int)); + read_pipe(command_pipe_read, command, len); + ret = system(command); + write_pipe(result_pipe_write, (char *)&ret, sizeof(int)); + } +} + +/********************************************************************/ +/* background_system() */ +/* return -1 on error, 0 on success */ +/********************************************************************/ + +int background_system(char *command) +{ + int res; + int len; + + if (module_initialized == 0) { + printf("FATAL: calling 'background_system' but 'start_background_system' was not called\n"); + abort(); + } + + len = strlen(command)+1; + if (len > MAX_COMMAND) { + printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND); + printf("command was: '%s'\n", command); + abort(); + } + /* only one command can run at a time, so let's lock/unlock */ + lock_system(); + write_pipe(command_pipe_write, (char*)&len, sizeof(int)); + write_pipe(command_pipe_write, command, len); + read_pipe(result_pipe_read, (char*)&res, sizeof(int)); + unlock_system(); + if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1; + return 0; +} + +/********************************************************************/ +/* start_background_system() */ +/* initializes the "background system" module */ +/* to be called very early by the main processing */ +/********************************************************************/ + +void start_background_system(void) +{ + int p[2]; + pid_t son; + + module_initialized = 1; + + if (pipe(p) == -1) { + perror("pipe"); + exit(1); + } + command_pipe_read = p[0]; + command_pipe_write = p[1]; + + if (pipe(p) == -1) { + perror("pipe"); + exit(1); + } + result_pipe_read = p[0]; + result_pipe_write = p[1]; + + son = fork(); + if (son == -1) { + perror("fork"); + exit(1); + } + + if (son) { + close(result_pipe_write); + close(command_pipe_read); + return; + } + + close(result_pipe_read); + close(command_pipe_write); + + background_system_process(); +} diff --git a/common/utils/system.h b/common/utils/system.h new file mode 100644 index 0000000000..784c15fc9a --- /dev/null +++ b/common/utils/system.h @@ -0,0 +1,39 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _SYSTEM_H_OAI_ +#define _SYSTEM_H_OAI_ + +/**************************************************** + * send a command to the background process + * return -1 on error, 0 on success + ****************************************************/ + +int background_system(char *command); + +/**************************************************** + * initialize the background process + * to be called very early + ****************************************************/ + +void start_background_system(void); + +#endif /* _SYSTEM_H_OAI_ */ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index bfa4a04cc8..4700187da1 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -47,6 +47,7 @@ Description Defines functions used to handle EPS bearer contexts. #include "esm_ebr_context.h" #include "emm_sap.h" +#include "system.h" #if defined(ENABLE_ITTI) # include "assertions.h" @@ -286,7 +287,18 @@ int esm_ebr_context_create( LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); - if (system(command_line)) ; /* TODO: what to do? */ + /* Calling system() here disrupts UE's realtime processing in some cases. + * This may be because of the call to fork(), which, for some + * unidentified reason, interacts badly with other (realtime) threads. + * background_system() is a replacement mechanism relying on a + * background process that does the system() and reports result to + * the parent process (lte-softmodem, oaisim, ...). The background + * process is created very early in the life of the parent process. + * The processes interact through standard pipes. See + * common/utils/system.c for details. + */ + if (background_system(command_line) != 0) + LOG_TRACE(ERROR, "ESM-PROC - failed command '%s'", command_line); break; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 03f6ba1a2e..ee31831a6b 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -74,6 +74,8 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "create_tasks.h" #endif +#include "system.h" + #ifdef XFORMS #include "PHY/TOOLS/lte_phy_scope.h" #include "stats.h" @@ -1371,6 +1373,8 @@ int main( int argc, char **argv ) { int ret; #endif + start_background_system(); + #ifdef DEBUG_CONSOLE setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index f1b3944a16..ab801d685c 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -59,6 +59,7 @@ #include "SCHED/defs.h" #include "SCHED/vars.h" +#include "system.h" #include "PHY/TOOLS/lte_phy_scope.h" @@ -1194,6 +1195,8 @@ main (int argc, char **argv) clock_t t; + start_background_system(); + #ifdef SMBV // Rohde&Schwarz SMBV100A vector signal generator strcpy(smbv_ip,DEFAULT_SMBV_IP); From 4fcb6272f4c4f43231ab0122950ca0b05c536e06 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 23 Mar 2017 18:00:58 +0100 Subject: [PATCH 428/571] RRC Rel14 - import RRC ASN.1 defintions from the specifications (file openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e10.asn) contrary to rel8/10, all modules have been imported, maybe it's too much to refine in case of problems - deal with rel14 in fix_asn1 - all code that was for Rel10 is now for Rel10/Rel14 - some incompatible changes (mostly in naming) were resolved in favor of rel14, see in openair2/RRC/LITE/defs.h - unsure about the rlc layer, some arrays have changed (values appended), I only changed the definition and in tests in the code, I changed the index limit, maybe it's not enough Rel14 is the default compilation mode. --- cmake_targets/CMakeLists.txt | 4 +- cmake_targets/build_oai | 5 +- cmake_targets/tools/fix_asn1 | 8 + .../RRC.rel14/SystemInformation-r8-IEs.h.diff | 23 + openair1/PHY/INIT/defs.h | 4 +- openair1/PHY/INIT/lte_init.c | 2 +- openair1/PHY/LTE_TRANSPORT/print_stats.c | 2 +- openair1/SCHED/defs.h | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 6 +- openair1/SCHED/phy_procedures_lte_ue.c | 12 +- openair2/COMMON/mac_rrc_primitives.h | 4 +- openair2/COMMON/platform_constants.h | 2 +- openair2/COMMON/rrc_messages_types.h | 2 +- openair2/ENB_APP/enb_app.c | 2 +- openair2/ENB_APP/enb_config.c | 50 +- openair2/ENB_APP/enb_config.h | 2 +- openair2/LAYER2/MAC/config.c | 18 +- openair2/LAYER2/MAC/defs.h | 14 +- openair2/LAYER2/MAC/eNB_scheduler.c | 6 +- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 6 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 2 +- openair2/LAYER2/MAC/main.c | 8 +- openair2/LAYER2/MAC/proto.h | 6 +- openair2/LAYER2/MAC/ra_procedures.c | 22 +- openair2/LAYER2/MAC/ue_procedures.c | 52 +- openair2/LAYER2/MAC/vars.h | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 14 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 8 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 2 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 12 + .../RLC/UM_v9.3.0/rlc_um_control_primitives.c | 10 +- openair2/LAYER2/RLC/rlc.c | 16 +- openair2/LAYER2/RLC/rlc.h | 6 +- openair2/LAYER2/RLC/rlc_rrc.c | 18 +- openair2/PHY_INTERFACE/defs.h | 8 +- openair2/RRC/LITE/L2_interface.c | 8 +- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 32 +- openair2/RRC/LITE/MESSAGES/asn1_msg.h | 6 +- .../MESSAGES/asn1c/ASN1_files/RRC-e10.asn | 12010 ++++++++++++++++ openair2/RRC/LITE/defs.h | 69 +- openair2/RRC/LITE/rrc_UE.c | 98 +- openair2/RRC/LITE/rrc_common.c | 4 +- openair2/RRC/LITE/rrc_eNB.c | 94 +- openair2/RRC/LITE/rrc_eNB_S1AP.c | 14 +- openair2/RRC/LITE/vars.h | 6 +- targets/SIMU/USER/oaisim.c | 2 +- targets/SIMU/USER/oaisim_functions.c | 6 +- 47 files changed, 12415 insertions(+), 294 deletions(-) create mode 100644 cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff create mode 100644 openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e10.asn diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index d7cd81cf58..db5a544ada 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -283,8 +283,10 @@ if (${RRC_ASN1_VERSION} STREQUAL "Rel8") set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn) elseif (${RRC_ASN1_VERSION} STREQUAL "CBA") set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn) -else() +elseif (${RRC_ASN1_VERSION} STREQUAL "Rel10") set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn) +else() + set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e10.asn) endif (${RRC_ASN1_VERSION} STREQUAL "Rel8") set (RRC_FULL_DIR ${asn1_generated_dir}/${RRC_ASN1_VERSION}) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index de1addcee3..119c013832 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -41,7 +41,7 @@ VCD_TIMING="False" DEADLINE_SCHEDULER_FLAG_USER="False" FORCE_DEADLINE_SCHEDULER_FLAG_USER="" CPU_AFFINITY_FLAG_USER="False" #Only valid when lowlatecy flag is set to False -REL="Rel10" +REL="Rel14" HW="None" TP="None" NOS1=0 @@ -95,8 +95,9 @@ Options -a | --agent Enables agent for software-defined control of the eNB -r | --3gpp-release - default is Rel10, + default is Rel14, Rel8 limits the implementation to 3GPP Release 8 version + Rel10 limits the implementation to 3GPP Release 10 version -w | --hardware EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, None (Default) Adds this RF board support (in external packages installation and in compilation) diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1 index 0661d7878d..442d2c4444 100755 --- a/cmake_targets/tools/fix_asn1 +++ b/cmake_targets/tools/fix_asn1 @@ -3,6 +3,10 @@ # in those arrays, each line is: # +RRC_Rel14=( + "SystemInformation-r8-IEs.h" 562e3c3aeb7c6d76d722f31bf24488a26e627f33 "fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff" +) + RRC_Rel10=( "SystemInformation-r8-IEs.h" 603cd6615cff36ec7020692d72c0d6de7c4859cb "fix_asn1.data/RRC.rel10/SystemInformation-r8-IEs.h.diff" ) @@ -94,6 +98,10 @@ function patch_rrc() local version="$2" case "$version" in + Rel14 ) + echo "patching RRC files release 14" + apply_patches "$directory" RRC_Rel14 ${#RRC_Rel14[*]} + ;; Rel10 ) echo "patching RRC files release 10" apply_patches "$directory" RRC_Rel10 ${#RRC_Rel10[*]} diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff new file mode 100644 index 0000000000..b2d32cf052 --- /dev/null +++ b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff @@ -0,0 +1,23 @@ +73,77d72 +< /* SystemInformation-r8-IEs */ +< typedef struct SystemInformation_r8_IEs { +< struct SystemInformation_r8_IEs__sib_TypeAndInfo { +< A_SEQUENCE_OF(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member { +< SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR present; +103c98,102 +< } choice; +--- +> }; +> +> struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member { +> SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR present; +> union SystemInformation_r8_IEs__sib_TypeAndInfo__Member_u choice; +107c106,111 +< } ) list; +--- +> }; +> +> /* SystemInformation-r8-IEs */ +> typedef struct SystemInformation_r8_IEs { +> struct SystemInformation_r8_IEs__sib_TypeAndInfo { +> A_SEQUENCE_OF(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member) list; diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index 27303cb57d..61cc063fb3 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -31,7 +31,7 @@ #include "TDD-Config.h" #include "MBSFN-SubframeConfigList.h" #include "MobilityControlInfo.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "SCellToAddMod-r10.h" #endif /** @addtogroup _PHY_STRUCTURES_ @@ -317,7 +317,7 @@ void lte_param_init(unsigned char N_tx_port_eNB, uint8_t osf, uint32_t perfect_ce); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, SCellToAddMod_r10_t *sCellToAddMod_r10, diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index d2a814c175..3123906d84 100755 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -706,7 +706,7 @@ void phy_config_dedicated_eNB(uint8_t Mod_id, } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, SCellToAddMod_r10_t *sCellToAddMod_r10, diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c index 0bebff8c35..9e8fa931ad 100644 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c @@ -507,7 +507,7 @@ int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length len += sprintf(&buffer[len], "[UE PROC] DLSCH Total %d, Error %d, FER %d\n",ue->dlsch_received[0],ue->dlsch_errors[0],ue->dlsch_fer[0]); len += sprintf(&buffer[len], "[UE PROC] DLSCH (SI) Total %d, Error %d\n",ue->dlsch_SI_received[0],ue->dlsch_SI_errors[0]); len += sprintf(&buffer[len], "[UE PROC] DLSCH (RA) Total %d, Error %d\n",ue->dlsch_ra_received[0],ue->dlsch_ra_errors[0]); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) int i=0; //len += sprintf(&buffer[len], "[UE PROC] MCH Total %d\n", ue->dlsch_mch_received[0]); diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index fd4b868382..c5b9b88d48 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -104,7 +104,7 @@ void phy_procedures_eNB_lte(uint8_t subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t */ void phy_procedures_UE_lte(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /*! \brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs. @param last_slot Index of last slot (0-19) @param next_slot Index of next_slot (0-19) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 97c8fb0837..934d8cec2a 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -409,7 +409,7 @@ DCI_PDU DCI_pdu_tmp; void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,relaying_type_t r_type) { -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) MCH_PDU *mch_pduP; MCH_PDU mch_pdu; // uint8_t sync_area=255; @@ -425,7 +425,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,rel subframe<<1,1); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) // 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(eNB->Mod_id, @@ -3461,7 +3461,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const #undef DEBUG_PHY_PROC -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type) { diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index a94847f83f..a7768e958e 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -3136,7 +3136,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) pmch_mcs = mac_xface->ue_query_mch(ue->Mod_id, CC_id, frame_rx, @@ -3234,7 +3234,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs if (subframe_rx==9) mac_xface->macphy_exit("Why are we exiting here?"); } else { // decoding successful -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (mcch_active == 1) { mac_xface->ue_send_mch_sdu(ue->Mod_id, @@ -3256,7 +3256,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs } -#endif // Rel10 +#endif // Rel10 || Rel14 } // decoding sucessful } // pmch_mcs>=0 } // is_pmch_subframe=true @@ -4158,7 +4158,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin return (0); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type) { @@ -4254,7 +4254,7 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) || (ue->frame_parms.frame_type == FDD)) { -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 ) #endif @@ -4268,7 +4268,7 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) && (slot==0)) { -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 ) #endif diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index dfa641ee66..79172276f5 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -33,7 +33,7 @@ #include "RadioResourceConfigCommonSIB.h" #include "RadioResourceConfigDedicated.h" #include "MeasGapConfig.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-SubframeConfigList.h" #endif @@ -380,7 +380,7 @@ typedef struct { TDD_Config_t *tdd_Config, uint8_t *SIwindowsize, uint16_t *SIperiod -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , MBMS_flag_t MBMS_Flag, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList, diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 6ad9ef078b..377773b642 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -86,7 +86,7 @@ #define DEFAULT_RAB_ID 1 #define NB_RB_MAX (maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */ -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) #define NB_RB_MBMS_MAX (maxSessionPerPMCH*maxServiceCount) #else // Do not allocate unused memory diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 8a4c27f5eb..0e3cd844d9 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -122,7 +122,7 @@ typedef struct RrcConfigurationReq_s { long pucch_delta_shift[MAX_NUM_CCs]; long pucch_nRB_CQI[MAX_NUM_CCs]; long pucch_nCS_AN[MAX_NUM_CCs]; -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) long pucch_n1_AN[MAX_NUM_CCs]; #endif long pdsch_referenceSignalPower[MAX_NUM_CCs]; diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 60415aad86..de0d0490aa 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -151,7 +151,7 @@ static void configure_rrc(uint32_t enb_id, const Enb_properties_array_t *enb_pro RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[CC_id] = enb_properties->properties[enb_id]->pucch_delta_shift[CC_id]; RRC_CONFIGURATION_REQ (msg_p).pucch_nRB_CQI[CC_id] = enb_properties->properties[enb_id]->pucch_nRB_CQI[CC_id]; RRC_CONFIGURATION_REQ (msg_p).pucch_nCS_AN[CC_id] = enb_properties->properties[enb_id]->pucch_nCS_AN[CC_id]; -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[CC_id] = enb_properties->properties[enb_id]->pucch_n1_AN[CC_id]; #endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 36b9e03935..3a706a067e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -115,7 +115,7 @@ #define ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT "pucch_delta_shift" #define ENB_CONFIG_STRING_PUCCH_NRB_CQI "pucch_nRB_CQI" #define ENB_CONFIG_STRING_PUCCH_NCS_AN "pucch_nCS_AN" -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) #define ENB_CONFIG_STRING_PUCCH_N1_AN "pucch_n1_AN" #endif #define ENB_CONFIG_STRING_PDSCH_RS_EPRE "pdsch_referenceSignalPower" @@ -418,7 +418,7 @@ void enb_config_display(void) printf( "\tpucch_delta_shift for CC %d:\t%ld:\n",j,enb_properties.properties[i]->pucch_delta_shift[j]); printf( "\tpucch_nRB_CQI for CC %d:\t%ld:\n",j,enb_properties.properties[i]->pucch_nRB_CQI[j]); printf( "\tpucch_nCS_AN for CC %d:\t%ld:\n",j,enb_properties.properties[i]->pucch_nCS_AN[j]); -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) printf( "\tpucch_n1_AN for CC %d:\t%ld:\n",j,enb_properties.properties[i]->pucch_n1_AN[j]); #endif @@ -589,7 +589,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) libconfig_int pucch_delta_shift = 0; libconfig_int pucch_nRB_CQI = 0; libconfig_int pucch_nCS_AN = 0; -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) libconfig_int pucch_n1_AN = 0; #endif libconfig_int pdsch_referenceSignalPower = 0; @@ -868,7 +868,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT, &pucch_delta_shift) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_NRB_CQI, &pucch_nRB_CQI) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_NCS_AN, &pucch_nCS_AN) -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_N1_AN, &pucch_n1_AN) #endif && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PDSCH_RS_EPRE, &pdsch_referenceSignalPower) @@ -913,7 +913,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UETIMERS_N311, &ue_TimersAndConstants_n311) && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, &ue_TransmissionMode) -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #endif )) { @@ -1162,7 +1162,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", lib_config_file_name_pP, i, pucch_nCS_AN); -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) enb_properties.properties[enb_properties_index]->pucch_n1_AN[j] = pucch_n1_AN; if ((pucch_n1_AN <0) || (pucch_n1_AN > 2047)) @@ -1347,21 +1347,21 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) lib_config_file_name_pP, i, pusch_p0_Nominal); if (strcmp(pusch_alpha,"AL0")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al0; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al0; } else if (strcmp(pusch_alpha,"AL04")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al04; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al04; } else if (strcmp(pusch_alpha,"AL05")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al05; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al05; } else if (strcmp(pusch_alpha,"AL06")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al06; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al06; } else if (strcmp(pusch_alpha,"AL07")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al07; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al07; } else if (strcmp(pusch_alpha,"AL08")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al08; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al08; } else if (strcmp(pusch_alpha,"AL09")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al09; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al08; } else if (strcmp(pusch_alpha,"AL1")==0) { - enb_properties.properties[enb_properties_index]->pusch_alpha[j] = UplinkPowerControlCommon__alpha_al1; + enb_properties.properties[enb_properties_index]->pusch_alpha[j] = Alpha_r12_al1; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", @@ -1553,47 +1553,47 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP) switch (rach_preambleTransMax) { case 3: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n3; break; case 4: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n4; break; case 5: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n5; break; case 6: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n6; break; case 7: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n7; break; case 8: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n8; break; case 10: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n10; break; case 20: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n20; break; case 50: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n50; break; case 100: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n100; break; case 200: - enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200; + enb_properties.properties[enb_properties_index]->rach_preambleTransMax[j] = PreambleTransMax_n200; break; default: diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 343a3c26ec..a508a82e1f 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -154,7 +154,7 @@ typedef struct Enb_properties_s { long pucch_delta_shift[1+MAX_NUM_CCs]; long pucch_nRB_CQI[1+MAX_NUM_CCs]; long pucch_nCS_AN[1+MAX_NUM_CCs]; -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) long pucch_n1_AN[1+MAX_NUM_CCs]; #endif long pdsch_referenceSignalPower[1+MAX_NUM_CCs]; diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index b5d613e4ae..12dbeecf16 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -42,7 +42,7 @@ #include "extern.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-AreaInfo-r9.h" #include "MBSFN-SubframeConfigList.h" @@ -93,7 +93,7 @@ rrc_mac_config_req( uint8_t eNB_index, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, struct PhysicalConfigDedicated *physicalConfigDedicated, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) SCellToAddMod_r10_t *sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -110,7 +110,7 @@ rrc_mac_config_req( long *ul_Bandwidth, AdditionalSpectrumEmission_t *additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,uint8_t MBMS_Flag, MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, PMCH_InfoList_r9_t *pmch_InfoList @@ -217,7 +217,7 @@ rrc_mac_config_req( if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) { UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = (uint16_t) *mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; } else { - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = (uint16_t) MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity; + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = (uint16_t) PeriodicBSR_Timer_r12_infinity; } if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) { @@ -230,11 +230,11 @@ rrc_mac_config_req( if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) { UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = (uint16_t) mac_MainConfig->ul_SCH_Config->retxBSR_Timer; } else { - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = (uint16_t)MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = (uint16_t)RetxBSR_Timer_r12_sf2560; } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = (uint16_t) *mac_MainConfig->ext1->sr_ProhibitTimer_r9; @@ -310,7 +310,7 @@ rrc_mac_config_req( } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (sCellToAddMod_r10 != NULL) { @@ -449,7 +449,7 @@ rrc_mac_config_req( eNB_mac_inst[Mod_idP].common_channels[0].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) eNB_mac_inst[Mod_idP].common_channels[0].MBMS_flag = MBMS_Flag; #endif } else { // UE @@ -465,7 +465,7 @@ rrc_mac_config_req( } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (mbsfn_AreaInfoList != NULL) { if (eNB_flagP == 1) { diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 3c0223e59e..18b8e7c38c 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -57,7 +57,7 @@ #include "RACH-ConfigCommon.h" #include "MeasObjectToAddModList.h" #include "MobilityControlInfo.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-SubframeConfigList.h" #include "PMCH-InfoList-r9.h" @@ -80,7 +80,7 @@ #define SCH_PAYLOAD_SIZE_MAX 4096 /// Logical channel ids from 36-311 (Note BCCH is not specified in 36-311, uses the same as first DRB) -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) // Mask for identifying subframe for MBMS #define MBSFN_TDD_SF3 0x80// for TDD @@ -276,7 +276,7 @@ typedef struct { uint8_t payload[PCCH_PAYLOAD_SIZE_MAX] ; } __attribute__((__packed__))PCCH_PDU; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /*! \brief MCCH payload */ typedef struct { uint8_t payload[MCCH_PAYLOAD_SIZE_MAX] ; @@ -327,7 +327,7 @@ typedef struct { /*!\brief LCID of padding LCID for DLSCH */ #define SHORT_PADDING 31 -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) // MCH LCHAN IDs (table6.2.1-4 TS36.321) /*!\brief LCID of MCCH for DL */ #define MCCH_LCHANID 0 @@ -889,7 +889,7 @@ typedef struct { struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /// MBMS Flag uint8_t MBMS_flag; /// Outgoing MCCH pdu for PHY @@ -1058,7 +1058,7 @@ typedef struct { struct RACH_ConfigDedicated *rach_ConfigDedicated; /// pointer to RRC PHY configuration struct PhysicalConfigDedicated *physicalConfigDedicated; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /// pointer to RRC PHY configuration SCEll struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10; #endif @@ -1132,7 +1132,7 @@ typedef struct { struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /// number of active MBSFN area uint8_t num_active_mbsfn_area; /// MBSFN Area Info diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index dee7c51a6e..1993d92c57 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -127,7 +127,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, for (CC_id=0; CC_idNum_common_dci = 0; DCI_pdu[CC_id]->Num_ue_spec_dci = 0; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0; #endif eNB_mac_inst[module_idP].frame = frameP; @@ -305,7 +305,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, // TODO process CCCH data req. break; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) case RRC_MAC_MCCH_DATA_REQ: LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d, mbsfn_sync_area %d\n", @@ -346,7 +346,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, 0, // eNB index, unused in eNB CC_id); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) for (CC_id=0; CC_id0) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 1dac7af704..acf28c805f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -61,7 +61,7 @@ #define DEBUG_eNB_SCHEDULER 1 -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) int8_t get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area) { // currently there is one-to-one mapping between sf allocation pattern and sync area @@ -466,7 +466,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra } TBS = mac_xface->get_TBS_DL(eNB_mac_inst[module_idP].common_channels[CC_id].MCH_pdu.mcs, mac_xface->frame_parms->N_RB_DL); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) // do not let mcch and mtch multiplexing when relaying is active // for sync area 1, so not transmit data //if ((i == 0) && ((eNB_mac_inst[module_idP].MBMS_flag != multicast_relay) || (eNB_mac_inst[module_idP].mcch_active==0))) { @@ -538,7 +538,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) // } #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 9a6fc29a58..56ede260e8 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -525,7 +525,7 @@ void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag) /* - #ifdef Rel10 + #if defined(Rel10) || defined(Rel14) unsigned char generate_mch_header( unsigned char *mac_header, unsigned char num_sdus, unsigned short *sdu_lengths, diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 8553c118dc..e04d7c3b8a 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -181,7 +181,7 @@ int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, ui #ifdef PHY_EMUL Mac_rlc_xface->Is_cluster_head[Mod_id]=2;//0: MR, 1: CH, 2: not CH neither MR #endif - /*#ifdef Rel10 + /*#if defined(Rel10) || defined(Rel14) int n; for (n=0;n<4096;n++) eNB_mac_inst[Mod_id].MCH_pdu.payload[n] = taus(); @@ -479,7 +479,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui mac_xface->ue_decode_si = ue_decode_si; mac_xface->ue_decode_p = ue_decode_p; mac_xface->ue_send_sdu = ue_send_sdu; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) mac_xface->ue_send_mch_sdu = ue_send_mch_sdu; mac_xface->ue_query_mch = ue_query_mch; #endif @@ -517,7 +517,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui mac_xface->phy_config_sib2_eNB = phy_config_sib2_eNB; mac_xface->phy_config_sib2_ue = phy_config_sib2_ue; mac_xface->phy_config_afterHO_ue = phy_config_afterHO_ue; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) mac_xface->phy_config_sib13_eNB = phy_config_sib13_eNB; mac_xface->phy_config_sib13_ue = phy_config_sib13_ue; #endif @@ -542,7 +542,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui mac_xface->get_prach_prb_offset = get_prach_prb_offset; mac_xface->is_prach_subframe = is_prach_subframe; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) mac_xface->get_mch_sdu = get_mch_sdu; mac_xface->phy_config_dedicated_scell_eNB= phy_config_dedicated_scell_eNB; mac_xface->phy_config_dedicated_scell_ue= phy_config_dedicated_scell_ue; diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 77a60794cc..3343e8821e 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -405,7 +405,7 @@ void ue_decode_p(module_id_t module_idP, int CC_id,frame_t frame, uint8_t CH_ind void ue_send_sdu(module_id_t module_idP, uint8_t CC_id,frame_t frame, sub_frame_t subframe, uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /* \brief Called by PHY to transfer MCH transport block to ue MAC. @param Mod_id Index of module instance @param frame Frame index @@ -754,7 +754,7 @@ int rrc_mac_config_req(module_id_t module_idP, uint8_t eNB_index, RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, struct PhysicalConfigDedicated *physicalConfigDedicated, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) SCellToAddMod_r10_t *sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -771,7 +771,7 @@ int rrc_mac_config_req(module_id_t module_idP, long *ul_Bandwidth, AdditionalSpectrumEmission_t *additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , uint8_t MBMS_Flag, MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index 43bc113798..8264699f43 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -499,37 +499,37 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP, (rach_ConfigCommon->powerRampingParameters.powerRampingStep<<1); // 2dB increments in ASN.1 definition int preambleTransMax = -1; switch (rach_ConfigCommon->ra_SupervisionInfo.preambleTransMax) { - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3: + case PreambleTransMax_n3: preambleTransMax = 3; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4: + case PreambleTransMax_n4: preambleTransMax = 4; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5: + case PreambleTransMax_n5: preambleTransMax = 5; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6: + case PreambleTransMax_n6: preambleTransMax = 6; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7: + case PreambleTransMax_n7: preambleTransMax = 7; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8: + case PreambleTransMax_n8: preambleTransMax = 8; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10: + case PreambleTransMax_n10: preambleTransMax = 10; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20: + case PreambleTransMax_n20: preambleTransMax = 20; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50: + case PreambleTransMax_n50: preambleTransMax = 50; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100: + case PreambleTransMax_n100: preambleTransMax = 100; break; - case RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200: + case PreambleTransMax_n200: preambleTransMax = 200; break; } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 6d304051d4..c27c0d524e 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -93,8 +93,8 @@ void ue_init_mac(module_id_t module_idP) // default values as deined in 36.331 sec 9.2.2 LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP); //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL; - UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240; - UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity; + UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= RetxBSR_Timer_r12_sf10240; + UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=PeriodicBSR_Timer_r12_infinity; UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; @@ -579,7 +579,7 @@ void ue_decode_p(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_in } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) unsigned char *parse_mch_header(unsigned char *mac_header, unsigned char *num_sdu, unsigned char *rx_lcids, @@ -1352,7 +1352,7 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf } // periodicBSR-Timer expires, trigger BSR - if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity) + if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != PeriodicBSR_Timer_r12_infinity) && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF == 0)){ // Trigger BSR Periodic UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PERIODIC; @@ -1904,7 +1904,7 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) UE_mac_inst[module_idP].scheduling_info.retxBSR_SF); // Reset Periodic Timer except when BSR is truncated - if ((bsr_t == NULL) && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity)) + if ((bsr_t == NULL) && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != PeriodicBSR_Timer_r12_infinity)) { UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer); @@ -2530,63 +2530,63 @@ int get_sf_periodicBSRTimer(uint8_t sf_offset) { switch (sf_offset) { - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf5: + case PeriodicBSR_Timer_r12_sf5: return 5; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf10: + case PeriodicBSR_Timer_r12_sf10: return 10; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf16: + case PeriodicBSR_Timer_r12_sf16: return 16; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf20: + case PeriodicBSR_Timer_r12_sf20: return 20; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf32: + case PeriodicBSR_Timer_r12_sf32: return 32; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf40: + case PeriodicBSR_Timer_r12_sf40: return 40; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64: + case PeriodicBSR_Timer_r12_sf64: return 64; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf80: + case PeriodicBSR_Timer_r12_sf80: return 80; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf128: + case PeriodicBSR_Timer_r12_sf128: return 128; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf160: + case PeriodicBSR_Timer_r12_sf160: return 160; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf320: + case PeriodicBSR_Timer_r12_sf320: return 320; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf640: + case PeriodicBSR_Timer_r12_sf640: return 640; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf1280: + case PeriodicBSR_Timer_r12_sf1280: return 1280; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf2560: + case PeriodicBSR_Timer_r12_sf2560: return 2560; break; - case MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity: + case PeriodicBSR_Timer_r12_infinity: default: return 0xFFFF; break; @@ -2597,27 +2597,27 @@ int get_sf_retxBSRTimer(uint8_t sf_offset) { switch (sf_offset) { - case MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320: + case RetxBSR_Timer_r12_sf320: return 320; break; - case MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf640: + case RetxBSR_Timer_r12_sf640: return 640; break; - case MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf1280: + case RetxBSR_Timer_r12_sf1280: return 1280; break; - case MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560: + case RetxBSR_Timer_r12_sf2560: return 2560; break; - case MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf5120: + case RetxBSR_Timer_r12_sf5120: return 5120; break; - case MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240: + case RetxBSR_Timer_r12_sf10240: return 10240; break; diff --git a/openair2/LAYER2/MAC/vars.h b/openair2/LAYER2/MAC/vars.h index edd8548e64..434a9e7c9c 100644 --- a/openair2/LAYER2/MAC/vars.h +++ b/openair2/LAYER2/MAC/vars.h @@ -132,7 +132,7 @@ DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu; DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu; DCI1_5MHz_TDD_t DLSCH_alloc_pdu; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) DCI1C_5MHz_t MCCH_alloc_pdu; #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 0c5e4cb9e1..8dad83a90a 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -1070,7 +1070,7 @@ rrc_pdcp_config_asn1_req ( uint8_t *const kRRCenc_pP, uint8_t *const kRRCint_pP, uint8_t *const kUPenc_pP -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,PMCH_InfoList_r9_t* const pmch_InfoList_r9_pP #endif ,rb_id_t *const defaultDRB @@ -1097,7 +1097,7 @@ rrc_pdcp_config_asn1_req ( hashtable_rc_t h_rc; hash_key_t key_defaultDRB = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_defaultDRB_rc; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) int i,j; MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; @@ -1395,7 +1395,7 @@ rrc_pdcp_config_asn1_req ( } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (pmch_InfoList_r9_pP != NULL) { for (i=0; ilist.count; i++) { @@ -1590,7 +1590,7 @@ pdcp_config_req_asn1 ( memset(pdcp_pP, 0, sizeof(pdcp_t)); break; -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) case CONFIG_ACTION_MBMS_ADD: case CONFIG_ACTION_MBMS_MODIFY: @@ -1908,7 +1908,7 @@ void pdcp_layer_init(void) { module_id_t instance; -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) mbms_session_id_t session_id; mbms_service_id_t service_id; #endif @@ -1920,7 +1920,7 @@ void pdcp_layer_init(void) AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed"); for (instance = 0; instance < NUMBER_OF_UE_MAX; instance++) { -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) for (service_id = 0; service_id < maxServiceCount; service_id++) { for (session_id = 0; session_id < maxSessionPerPMCH; session_id++) { @@ -1934,7 +1934,7 @@ void pdcp_layer_init(void) for (instance = 0; instance < NUMBER_OF_eNB_MAX; instance++) { -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) for (service_id = 0; service_id < maxServiceCount; service_id++) { for (session_id = 0; session_id < maxSessionPerPMCH; session_id++) { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 366f79dc9d..94084273d1 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -74,7 +74,7 @@ #include "DRB-ToAddModList.h" #include "SRB-ToAddMod.h" #include "SRB-ToAddModList.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "MBMS-SessionInfoList-r9.h" #include "PMCH-InfoList-r9.h" #endif @@ -184,7 +184,7 @@ typedef struct pdcp_s { } pdcp_t; -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) typedef struct pdcp_mbms_s { boolean_t instanciated_instance; rb_id_t rb_id; @@ -284,7 +284,7 @@ public_pdcp( uint8_t *const kRRCenc, uint8_t *const kRRCint, uint8_t *const kUPenc -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif ,rb_id_t *const defaultDRB @@ -448,7 +448,7 @@ public_pdcp(pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX];) protected_pdcp(rnti_t pdcp_UE_UE_module_id_to_rnti[NUMBER_OF_UE_MAX];) protected_pdcp(rnti_t pdcp_eNB_UE_instance_to_rnti[NUMBER_OF_UE_MAX];) // for noS1 mode protected_pdcp(unsigned int pdcp_eNB_UE_instance_to_rnti_index;) -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) public_pdcp(pdcp_mbms_t pdcp_mbms_array_ue[NUMBER_OF_UE_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h public_pdcp(pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH];) // some constants from openair2/RRC/LITE/MESSAGES/asn1_constants.h #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 37b38121b9..0da894df82 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -431,7 +431,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ || (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ || (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) { -#if defined (Rel10) +#if defined(Rel10) || defined(Rel14) PDCP_TRANSMISSION_MODE_TRANSPARENT; #else pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 4051a88ef2..726b52be53 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -153,9 +153,15 @@ config_req_rlc_am ( uint32_t pollPDU_tab[PollPDU_pInfinity+1]= {4,8,16,32,64,128,256,1024}; // What is PollPDU_pInfinity??? 1024 for now uint32_t maxRetxThreshold_tab[UL_AM_RLC__maxRetxThreshold_t32+1]= {1,2,3,4,6,8,16,32}; uint32_t pollByte_tab[PollByte_spare1]= {25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,10000}; // What is PollByte_kBinfinity??? 10000 for now +#if defined(Rel14) +uint32_t PollRetransmit_tab[T_PollRetransmit_spare5]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,2000,4000}; +uint32_t am_t_Reordering_tab[32]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200,1600}; +uint32_t t_StatusProhibit_tab[T_StatusProhibit_spare2]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,1200,1600,2000,2400}; +#else uint32_t PollRetransmit_tab[T_PollRetransmit_spare9]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; uint32_t am_t_Reordering_tab[T_Reordering_spare1]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; uint32_t t_StatusProhibit_tab[T_StatusProhibit_spare8]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; +#endif //----------------------------------------------------------------------------- void config_req_rlc_am_asn1 ( @@ -178,9 +184,15 @@ void config_req_rlc_am_asn1 ( if ((config_am_pP->ul_AM_RLC.maxRetxThreshold <= UL_AM_RLC__maxRetxThreshold_t32) && (config_am_pP->ul_AM_RLC.pollPDU<=PollPDU_pInfinity) && (config_am_pP->ul_AM_RLC.pollByteul_AM_RLC.t_PollRetransmitdl_AM_RLC.t_Reordering<32) && + (config_am_pP->dl_AM_RLC.t_StatusProhibitul_AM_RLC.t_PollRetransmitdl_AM_RLC.t_Reorderingdl_AM_RLC.t_StatusProhibitenb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE, diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c index bda2b88458..14ca1a62a9 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c @@ -78,7 +78,11 @@ void config_req_rlc_um ( } } //----------------------------------------------------------------------------- +#if defined(Rel14) +const uint32_t const t_Reordering_tab[32] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200,1600}; +#else const uint32_t const t_Reordering_tab[T_Reordering_spare1] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; +#endif void config_req_rlc_um_asn1 ( const protocol_ctxt_t* const ctxt_pP, @@ -99,7 +103,7 @@ void config_req_rlc_um_asn1 ( hash_key_t key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); hashtable_rc_t h_rc; -#if Rel10 +#if defined(Rel10) || defined(Rel14) if (mbms_flagP) { AssertFatal(dl_rlc_pP, "No RLC UM DL config"); @@ -194,7 +198,11 @@ void config_req_rlc_um_asn1 ( return; } +#if defined(Rel14) + if (dl_rlc_pP->t_Reordering<32) { +#else if (dl_rlc_pP->t_Reorderingt_Reordering]; } else { LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID T_Reordering %ld, RLC NOT CONFIGURED\n", diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 96057231a6..7aca1b9cc6 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -328,7 +328,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t log_ch_id = 0; #endif @@ -342,7 +342,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, sdu_sizeP, sdu_pP); #endif -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #else AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP); #endif @@ -366,13 +366,13 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, DevAssert(sdu_pP != NULL); DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0); -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) DevCheck(MBMS_flagP == 0, MBMS_flagP, 0, 0); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -499,7 +499,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) } else { /* MBMS_flag != 0 */ // LOG_I(RLC,"DUY rlc_data_req: mbms_rb_id in RLC instant is: %d\n", mbms_rb_id); if (sdu_pP != NULL) { @@ -538,7 +538,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, else /* MBMS_flag != 0 */ { free_mem_block(sdu_pP, __func__); - LOG_E(RLC, "MBMS_flag != 0 while Rel10 is not defined...\n"); + LOG_E(RLC, "MBMS_flag != 0 while Rel10/Rel14 is not defined...\n"); //handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : parameter module_id out of bounds :%d\n", __FILE__, __LINE__, module_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT); return RLC_OP_STATUS_BAD_PARAMETER; @@ -617,7 +617,7 @@ rlc_module_init (void) AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed"); for (module_id1=0; module_id1 < NUMBER_OF_UE_MAX; module_id1++) { -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) for (k=0; k < RLC_MAX_MBMS_LC; k++) { rlc_mbms_lcid2service_session_id_ue[module_id1][k].service_id = 0; @@ -632,7 +632,7 @@ rlc_module_init (void) } for (module_id1=0; module_id1 < NUMBER_OF_eNB_MAX; module_id1++) { -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) for (k=0; k < RLC_MAX_MBMS_LC; k++) { rlc_mbms_lcid2service_session_id_eNB[module_id1][k].service_id = 0; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 3fd5b8c3bc..465492bec9 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -55,7 +55,7 @@ # include "SRB-ToAddModList.h" # include "DRB-ToReleaseList.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "PMCH-InfoList-r9.h" #endif @@ -224,7 +224,7 @@ typedef struct rlc_mbms_id_s { mbms_session_id_t session_id; } rlc_mbms_id_t; -#if !defined(Rel10) +#if !defined(Rel10) && !defined(Rel14) # if !defined(maxServiceCount) //unused arrays rlc_mbms_array_ue rlc_mbms_array_eNB # define maxServiceCount 1 @@ -309,7 +309,7 @@ private_rlc_mac(struct mac_data_ind mac_rlc_deserialize_tb (char*, tb_size_t, //----------------------------------------------------------------------------- // PUBLIC INTERFACE WITH RRC //----------------------------------------------------------------------------- -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /*! \fn rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, const SRB_ToAddMod_t* const srb2addmod, const DRB_ToAddModList_t* const drb2add_listP, const DRB_ToReleaseList_t* const drb2release_listP, const PMCH_InfoList_r9_t * const pmch_info_listP) * \brief Function for RRC to configure a Radio Bearer. * \param[in] ctxtP Running context. diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 8304752e8e..a45838603e 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -42,7 +42,7 @@ #include "SRB-ToAddMod.h" #include "SRB-ToAddModList.h" #include "DL-UM-RLC.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "PMCH-InfoList-r9.h" #endif @@ -53,7 +53,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP const SRB_ToAddModList_t * const srb2add_listP, const DRB_ToAddModList_t * const drb2add_listP, const DRB_ToReleaseList_t * const drb2release_listP -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) ,const PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP #endif ) @@ -69,7 +69,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP rlc_union_t *rlc_union_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) int i, j; MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; @@ -344,7 +344,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP } } -#if defined(Rel10) +#if defined(Rel10) || defined(Rel14) if (pmch_InfoList_r9_pP != NULL) { for (i=0; ilist.count; i++) { @@ -487,7 +487,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( hash_key_t key_lcid = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_lcid_rc; rlc_union_t *rlc_union_p = NULL; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) rlc_mbms_id_t *mbms_id_p = NULL; #endif #ifdef OAI_EMU @@ -498,7 +498,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( /* for no gcc warnings */ (void)lcid; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -592,7 +592,7 @@ rlc_union_t* rrc_rlc_add_rlc ( hash_key_t key_lcid = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_lcid_rc; rlc_union_t *rlc_union_p = NULL; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t lcid = 0; #endif @@ -608,7 +608,7 @@ rlc_union_t* rrc_rlc_add_rlc ( AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -650,7 +650,7 @@ rlc_union_t* rrc_rlc_add_rlc ( h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p); if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flagP == TRUE) { LOG_I(RLC, PROTOCOL_CTXT_FMT" RLC service id %u session id %u rrc_rlc_add_rlc\n", diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h index 4973252054..5769d94a37 100644 --- a/openair2/PHY_INTERFACE/defs.h +++ b/openair2/PHY_INTERFACE/defs.h @@ -112,7 +112,7 @@ typedef struct { AdditionalSpectrumEmission_t *additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /// Configure Common PHY parameters from SIB13 void (*phy_config_sib13_eNB)(module_id_t Mod_id,int CC_id, int mbsfn_Area_idx, long mbsfn_AreaId_r9); @@ -127,7 +127,7 @@ typedef struct { void (*phy_config_dedicated_eNB)(module_id_t Mod_id,int CC_id,rnti_t rnti, struct PhysicalConfigDedicated *physicalConfigDedicated); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /// Get MCH sdu and corresponding MCS for particular MBSFN subframe MCH_PDU* (*get_mch_sdu)(module_id_t Mod_id, int CC_id, frame_t frameP,sub_frame_t subframe); #endif @@ -154,7 +154,7 @@ typedef struct { /// Send a received DLSCH sdu to MAC void (*ue_send_sdu)(module_id_t Mod_id,uint8_t CC_id,frame_t frameP,sub_frame_t subframe,uint8_t *sdu,uint16_t sdu_len,uint8_t CH_index); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /// Send a received MCH sdu to MAC void (*ue_send_mch_sdu)(module_id_t Mod_id,uint8_t CC_id, frame_t frameP,uint8_t *sdu,uint16_t sdu_len,uint8_t eNB_index,uint8_t sync_area); @@ -202,7 +202,7 @@ typedef struct { AdditionalSpectrumEmission_t *additionalSpectrumEmission, struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /// Configure Common PHY parameters from SIB13 void (*phy_config_sib13_ue)(uint8_t Mod_id,int CC_id, uint8_t eNB_index,int mbsfn_Area_idx, long mbsfn_AreaId_r9); diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c index fa5a4d6409..64734cac9a 100644 --- a/openair2/RRC/LITE/L2_interface.c +++ b/openair2/RRC/LITE/L2_interface.c @@ -222,7 +222,7 @@ mac_rrc_data_req( return (Sdu_size); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if((Srb_id & RAB_OFFSET) == MCCH) { if(eNB_rrc_inst[Mod_idP].carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) { @@ -281,7 +281,7 @@ mac_rrc_data_req( //return(0); } -#endif //Rel10 +#endif //Rel10 || Rel14 } else { //This is an UE LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); @@ -428,7 +428,7 @@ mac_rrc_data_ind( } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if ((srb_idP & RAB_OFFSET) == MCCH) { LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", @@ -459,7 +459,7 @@ mac_rrc_data_ind( #endif } -#endif // Rel10 +#endif // Rel10 || Rel14 } else { // This is an eNB Srb_info = &eNB_rrc_inst[module_idP].carrier[CC_id].Srb0; diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 4537303fca..6f169eb8c4 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -58,7 +58,7 @@ #include "RRCConnectionSetup.h" #include "SRB-ToAddModList.h" #include "DRB-ToAddModList.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "MCCH-Message.h" //#define MRB1 1 #endif @@ -614,7 +614,7 @@ uint8_t do_SIB23(uint8_t Mod_id, BCCH_DL_SCH_Message_t *bcch_message, SystemInformationBlockType2_t **sib2, SystemInformationBlockType3_t **sib3 -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , SystemInformationBlockType13_r9_t **sib13, uint8_t MBMS_flag @@ -625,7 +625,7 @@ uint8_t do_SIB23(uint8_t Mod_id, ) { struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part; MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList; MBSFN_AreaInfoList_r9_t *MBSFNArea_list; @@ -650,7 +650,7 @@ uint8_t do_SIB23(uint8_t Mod_id, exit(-1); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) LOG_I(RRC,"[eNB %d] Configuration SIB2/3, MBMS = %d\n", Mod_id, MBMS_flag); #else LOG_I(RRC,"[eNB %d] Configuration SIB2/3\n", Mod_id); @@ -666,7 +666,7 @@ uint8_t do_SIB23(uint8_t Mod_id, *sib2 = &sib2_part->choice.sib2; *sib3 = &sib3_part->choice.sib3; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flag > 0) { sib13_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); @@ -680,7 +680,7 @@ uint8_t do_SIB23(uint8_t Mod_id, // sib2 (*sib2)->ac_BarringInfo = NULL; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #if 0 (*sib2)->ssac_BarringForMMTEL_Voice_r9 = NULL; (*sib2)->ssac_BarringForMMTEL_Video_r9 = NULL; @@ -769,7 +769,7 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->pucch_nRB_CQI[CC_id]; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN = configuration->pucch_nCS_AN[CC_id]; -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN = configuration->pucch_n1_AN[CC_id]; #endif @@ -929,7 +929,7 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->freqInfo.ul_Bandwidth = NULL; // (*sib2)->mbsfn_SubframeConfigList = NULL; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flag > 0) { LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2\n"); @@ -985,7 +985,7 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->timeAlignmentTimerCommon=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; /// (*SIB3) -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (*sib3)->ext1 = NULL; #if 0 (*sib3)->s_IntraSearch_v920=NULL; @@ -1020,7 +1020,7 @@ uint8_t do_SIB23(uint8_t Mod_id, // SIB13 // fill in all elements of SIB13 if present -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flag > 0 ) { // Notification for mcch change @@ -1102,7 +1102,7 @@ uint8_t do_SIB23(uint8_t Mod_id, sib2_part); ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib3_part); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (MBMS_flag > 0) { ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list,sib13_part); @@ -1563,7 +1563,7 @@ do_RRCConnectionSetup( // CQI ReportConfig physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= CQI_ReportModeAperiodic_rm30; #else *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI @@ -1776,7 +1776,7 @@ do_SecurityModeCommand( SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; // the two following information could be based on the mod_id dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm - = (e_SecurityAlgorithmConfig__cipheringAlgorithm)cipheringAlgorithm; + = (CipheringAlgorithm_r12_t)cipheringAlgorithm; dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; @@ -1929,7 +1929,7 @@ do_RRCConnectionReconfiguration( struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , SCellToAddMod_r10_t *SCell_config #endif ) @@ -2224,7 +2224,7 @@ uint8_t do_RRCConnectionRelease( uint8_t TMGI[5] = {4,3,2,1,0};//TMGI is a string of octet, ref. TS 24.008 fig. 10.5.4a -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, LTE_DL_FRAME_PARMS *frame_parms, uint8_t sync_area, @@ -2396,7 +2396,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension)); measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measId=measid; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrpResult=rsrp_s; measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrqResult=rsrq_s; #else diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h index 881a778030..4466457075 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h @@ -93,7 +93,7 @@ uint8_t do_SIB23(uint8_t Mod_id, BCCH_DL_SCH_Message_t *systemInformation, SystemInformationBlockType2_t **sib2, SystemInformationBlockType3_t **sib3 -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , SystemInformationBlockType13_r9_t **sib13, uint8_t MBMS_flag @@ -197,7 +197,7 @@ do_RRCConnectionReconfiguration( RSRP_Range_t *rsrp, C_RNTI_t *cba_rnti, struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList* dedicatedInfoNASList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , SCellToAddMod_r10_t *SCell_config #endif ); @@ -238,7 +238,7 @@ uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer,int Transaction_ * @returns Size of encoded bit stream in bytes */ uint8_t do_MCCHMessage(uint8_t *buffer); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /*** * \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) * @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU diff --git a/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e10.asn b/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e10.asn new file mode 100644 index 0000000000..cb13f30c0e --- /dev/null +++ b/openair2/RRC/LITE/MESSAGES/asn1c/ASN1_files/RRC-e10.asn @@ -0,0 +1,12010 @@ + +EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + + +BCCH-BCH-Message ::= SEQUENCE { + message BCCH-BCH-MessageType +} + +BCCH-BCH-MessageType ::= MasterInformationBlock + + +BCCH-DL-SCH-Message ::= SEQUENCE { + message BCCH-DL-SCH-MessageType +} + +BCCH-DL-SCH-MessageType ::= CHOICE { + c1 CHOICE { + systemInformation SystemInformation, + systemInformationBlockType1 SystemInformationBlockType1 + }, + messageClassExtension SEQUENCE {} +} + + +BCCH-DL-SCH-Message-BR ::= SEQUENCE { + message BCCH-DL-SCH-MessageType-BR-r13 +} + +BCCH-DL-SCH-MessageType-BR-r13 ::= CHOICE { + c1 CHOICE { + systemInformation-BR-r13 SystemInformation-BR-r13, + systemInformationBlockType1-BR-r13 SystemInformationBlockType1-BR-r13 + }, + messageClassExtension SEQUENCE {} +} + + +MCCH-Message ::= SEQUENCE { + message MCCH-MessageType +} + +MCCH-MessageType ::= CHOICE { + c1 CHOICE { + mbsfnAreaConfiguration-r9 MBSFNAreaConfiguration-r9 + }, + later CHOICE { + c2 CHOICE{ + mbmsCountingRequest-r10 MBMSCountingRequest-r10 + }, + messageClassExtension SEQUENCE {} + } +} + + +PCCH-Message ::= SEQUENCE { + message PCCH-MessageType +} + +PCCH-MessageType ::= CHOICE { + c1 CHOICE { + paging Paging + }, + messageClassExtension SEQUENCE {} +} + + +DL-CCCH-Message ::= SEQUENCE { + message DL-CCCH-MessageType +} + +DL-CCCH-MessageType ::= CHOICE { + c1 CHOICE { + rrcConnectionReestablishment RRCConnectionReestablishment, + rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject, + rrcConnectionReject RRCConnectionReject, + rrcConnectionSetup RRCConnectionSetup + }, + messageClassExtension SEQUENCE {} +} + + +DL-DCCH-Message ::= SEQUENCE { + message DL-DCCH-MessageType +} + +DL-DCCH-MessageType ::= CHOICE { + c1 CHOICE { + csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000, + dlInformationTransfer DLInformationTransfer, + handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest, + mobilityFromEUTRACommand MobilityFromEUTRACommand, + rrcConnectionReconfiguration RRCConnectionReconfiguration, + rrcConnectionRelease RRCConnectionRelease, + securityModeCommand SecurityModeCommand, + ueCapabilityEnquiry UECapabilityEnquiry, + counterCheck CounterCheck, + ueInformationRequest-r9 UEInformationRequest-r9, + loggedMeasurementConfiguration-r10 LoggedMeasurementConfiguration-r10, + rnReconfiguration-r10 RNReconfiguration-r10, + rrcConnectionResume-r13 RRCConnectionResume-r13, + spare3 NULL, spare2 NULL, spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + + +UL-CCCH-Message ::= SEQUENCE { + message UL-CCCH-MessageType +} + +UL-CCCH-MessageType ::= CHOICE { + c1 CHOICE { + rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest, + rrcConnectionRequest RRCConnectionRequest + }, + messageClassExtension CHOICE { + c2 CHOICE { + rrcConnectionResumeRequest-r13 RRCConnectionResumeRequest-r13 + }, + messageClassExtensionFuture-r13 SEQUENCE {} + } +} + + +UL-DCCH-Message ::= SEQUENCE { + message UL-DCCH-MessageType +} + +UL-DCCH-MessageType ::= CHOICE { + c1 CHOICE { + csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000, + measurementReport MeasurementReport, + rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete, + rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete, + rrcConnectionSetupComplete RRCConnectionSetupComplete, + securityModeComplete SecurityModeComplete, + securityModeFailure SecurityModeFailure, + ueCapabilityInformation UECapabilityInformation, + ulHandoverPreparationTransfer ULHandoverPreparationTransfer, + ulInformationTransfer ULInformationTransfer, + counterCheckResponse CounterCheckResponse, + ueInformationResponse-r9 UEInformationResponse-r9, + proximityIndication-r9 ProximityIndication-r9, + rnReconfigurationComplete-r10 RNReconfigurationComplete-r10, + mbmsCountingResponse-r10 MBMSCountingResponse-r10, + interFreqRSTDMeasurementIndication-r10 InterFreqRSTDMeasurementIndication-r10 + }, + messageClassExtension CHOICE { + c2 CHOICE { + ueAssistanceInformation-r11 UEAssistanceInformation-r11, + inDeviceCoexIndication-r11 InDeviceCoexIndication-r11, + mbmsInterestIndication-r11 MBMSInterestIndication-r11, + scgFailureInformation-r12 SCGFailureInformation-r12, + sidelinkUEInformation-r12 SidelinkUEInformation-r12, + wlanConnectionStatusReport-r13 WLANConnectionStatusReport-r13, + rrcConnectionResumeComplete-r13 RRCConnectionResumeComplete-r13, + spare9 NULL, spare8 NULL, spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + messageClassExtensionFuture-r11 SEQUENCE {} + } +} + + +SC-MCCH-Message-r13 ::= SEQUENCE { + message SC-MCCH-MessageType-r13 +} + + +SC-MCCH-MessageType-r13 ::= CHOICE { + c1 CHOICE { + scptmConfiguration-r13 SCPTMConfiguration-r13 + }, + messageClassExtension SEQUENCE {} +} + + +CounterCheck ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + counterCheck-r8 CounterCheck-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +CounterCheck-r8-IEs ::= SEQUENCE { + drb-CountMSB-InfoList DRB-CountMSB-InfoList, + nonCriticalExtension CounterCheck-v8a0-IEs OPTIONAL +} + +CounterCheck-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +DRB-CountMSB-InfoList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info + +DRB-CountMSB-Info ::= SEQUENCE { + drb-Identity DRB-Identity, + countMSB-Uplink INTEGER(0..33554431), + countMSB-Downlink INTEGER(0..33554431) +} + + +CounterCheckResponse ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + counterCheckResponse-r8 CounterCheckResponse-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +CounterCheckResponse-r8-IEs ::= SEQUENCE { + drb-CountInfoList DRB-CountInfoList, + nonCriticalExtension CounterCheckResponse-v8a0-IEs OPTIONAL +} + +CounterCheckResponse-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo + +DRB-CountInfo ::= SEQUENCE { + drb-Identity DRB-Identity, + count-Uplink INTEGER(0..4294967295), + count-Downlink INTEGER(0..4294967295) +} + + +CSFBParametersRequestCDMA2000 ::= SEQUENCE { + criticalExtensions CHOICE { + csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE { + nonCriticalExtension CSFBParametersRequestCDMA2000-v8a0-IEs OPTIONAL +} + +CSFBParametersRequestCDMA2000-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +CSFBParametersResponseCDMA2000 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE { + rand RAND-CDMA2000, + mobilityParameters MobilityParametersCDMA2000, + nonCriticalExtension CSFBParametersResponseCDMA2000-v8a0-IEs OPTIONAL +} + +CSFBParametersResponseCDMA2000-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +DLInformationTransfer ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + dlInformationTransfer-r8 DLInformationTransfer-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +DLInformationTransfer-r8-IEs ::= SEQUENCE { + dedicatedInfoType CHOICE { + dedicatedInfoNAS DedicatedInfoNAS, + dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000, + dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000 + }, + nonCriticalExtension DLInformationTransfer-v8a0-IEs OPTIONAL +} + +DLInformationTransfer-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +HandoverFromEUTRAPreparationRequest ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + handoverFromEUTRAPreparationRequest-r8 + HandoverFromEUTRAPreparationRequest-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE { + cdma2000-Type CDMA2000-Type, + rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type + mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type + nonCriticalExtension HandoverFromEUTRAPreparationRequest-v890-IEs OPTIONAL +} + +HandoverFromEUTRAPreparationRequest-v890-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension HandoverFromEUTRAPreparationRequest-v920-IEs OPTIONAL +} + +HandoverFromEUTRAPreparationRequest-v920-IEs ::= SEQUENCE { + concurrPrepCDMA2000-HRPD-r9 BOOLEAN OPTIONAL, -- Cond cdma2000-Type + nonCriticalExtension HandoverFromEUTRAPreparationRequest-v1020-IEs OPTIONAL +} + +HandoverFromEUTRAPreparationRequest-v1020-IEs ::= SEQUENCE { + dualRxTxRedirectIndicator-r10 ENUMERATED {true} OPTIONAL, -- Cond cdma2000-1XRTT + redirectCarrierCDMA2000-1XRTT-r10 CarrierFreqCDMA2000 OPTIONAL, -- Cond dualRxTxRedirect + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +InDeviceCoexIndication-r11 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + inDeviceCoexIndication-r11 InDeviceCoexIndication-r11-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +InDeviceCoexIndication-r11-IEs ::= SEQUENCE { + affectedCarrierFreqList-r11 AffectedCarrierFreqList-r11 OPTIONAL, + tdm-AssistanceInfo-r11 TDM-AssistanceInfo-r11 OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension InDeviceCoexIndication-v11d0-IEs OPTIONAL +} + +InDeviceCoexIndication-v11d0-IEs ::= SEQUENCE { + ul-CA-AssistanceInfo-r11 SEQUENCE { + affectedCarrierFreqCombList-r11 AffectedCarrierFreqCombList-r11 OPTIONAL, + victimSystemType-r11 VictimSystemType-r11 + } OPTIONAL, + nonCriticalExtension InDeviceCoexIndication-v1310-IEs OPTIONAL +} + +InDeviceCoexIndication-v1310-IEs ::= SEQUENCE { + affectedCarrierFreqList-v1310 AffectedCarrierFreqList-v1310 OPTIONAL, + affectedCarrierFreqCombList-r13 AffectedCarrierFreqCombList-r13 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +AffectedCarrierFreqList-r11 ::= SEQUENCE (SIZE (1..maxFreqIDC-r11)) OF AffectedCarrierFreq-r11 + +AffectedCarrierFreqList-v1310 ::= SEQUENCE (SIZE (1..maxFreqIDC-r11)) OF AffectedCarrierFreq-v1310 + +AffectedCarrierFreq-r11 ::= SEQUENCE { + carrierFreq-r11 MeasObjectId, + interferenceDirection-r11 ENUMERATED {eutra, other, both, spare} +} + +AffectedCarrierFreq-v1310 ::= SEQUENCE { + carrierFreq-v1310 MeasObjectId-v1310 OPTIONAL +} + +AffectedCarrierFreqCombList-r11 ::= SEQUENCE (SIZE (1..maxCombIDC-r11)) OF AffectedCarrierFreqComb-r11 + +AffectedCarrierFreqCombList-r13 ::= SEQUENCE (SIZE (1..maxCombIDC-r11)) OF AffectedCarrierFreqComb-r13 + +AffectedCarrierFreqComb-r11 ::= SEQUENCE (SIZE (2..maxServCell-r10)) OF MeasObjectId + +AffectedCarrierFreqComb-r13 ::= SEQUENCE (SIZE (2..maxServCell-r13)) OF MeasObjectId-r13 + +TDM-AssistanceInfo-r11 ::= CHOICE { + drx-AssistanceInfo-r11 SEQUENCE { + drx-CycleLength-r11 ENUMERATED {sf40, sf64, sf80, sf128, sf160, + sf256, spare2, spare1}, + drx-Offset-r11 INTEGER (0..255) OPTIONAL, + drx-ActiveTime-r11 ENUMERATED {sf20, sf30, sf40, sf60, sf80, + sf100, spare2, spare1} + }, + idc-SubframePatternList-r11 IDC-SubframePatternList-r11, + ... +} + +IDC-SubframePatternList-r11 ::= SEQUENCE (SIZE (1..maxSubframePatternIDC-r11)) OF IDC-SubframePattern-r11 + +IDC-SubframePattern-r11 ::= CHOICE { + subframePatternFDD-r11 BIT STRING (SIZE (4)), + subframePatternTDD-r11 CHOICE { + subframeConfig0-r11 BIT STRING (SIZE (70)), + subframeConfig1-5-r11 BIT STRING (SIZE (10)), + subframeConfig6-r11 BIT STRING (SIZE (60)) + }, + ... +} + +VictimSystemType-r11 ::= SEQUENCE { + gps-r11 ENUMERATED {true} OPTIONAL, + glonass-r11 ENUMERATED {true} OPTIONAL, + bds-r11 ENUMERATED {true} OPTIONAL, + galileo-r11 ENUMERATED {true} OPTIONAL, + wlan-r11 ENUMERATED {true} OPTIONAL, + bluetooth-r11 ENUMERATED {true} OPTIONAL +} + + +InterFreqRSTDMeasurementIndication-r10 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + interFreqRSTDMeasurementIndication-r10 InterFreqRSTDMeasurementIndication-r10-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +InterFreqRSTDMeasurementIndication-r10-IEs ::= SEQUENCE { + rstd-InterFreqIndication-r10 CHOICE { + start SEQUENCE { + rstd-InterFreqInfoList-r10 RSTD-InterFreqInfoList-r10 + }, + stop NULL + }, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +RSTD-InterFreqInfoList-r10 ::= SEQUENCE (SIZE(1..maxRSTD-Freq-r10)) OF RSTD-InterFreqInfo-r10 + +RSTD-InterFreqInfo-r10 ::= SEQUENCE { + carrierFreq-r10 ARFCN-ValueEUTRA, + measPRS-Offset-r10 INTEGER (0..39), + ..., + [[ carrierFreq-v1090 ARFCN-ValueEUTRA-v9e0 OPTIONAL + ]] +} + + +LoggedMeasurementConfiguration-r10 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + loggedMeasurementConfiguration-r10 LoggedMeasurementConfiguration-r10-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + + +LoggedMeasurementConfiguration-r10-IEs ::= SEQUENCE { + traceReference-r10 TraceReference-r10, + traceRecordingSessionRef-r10 OCTET STRING (SIZE (2)), + tce-Id-r10 OCTET STRING (SIZE (1)), + absoluteTimeInfo-r10 AbsoluteTimeInfo-r10, + areaConfiguration-r10 AreaConfiguration-r10 OPTIONAL, -- Need OR + loggingDuration-r10 LoggingDuration-r10, + loggingInterval-r10 LoggingInterval-r10, + nonCriticalExtension LoggedMeasurementConfiguration-v1080-IEs OPTIONAL +} + +LoggedMeasurementConfiguration-v1080-IEs ::= SEQUENCE { + lateNonCriticalExtension-r10 OCTET STRING OPTIONAL, + nonCriticalExtension LoggedMeasurementConfiguration-v1130-IEs OPTIONAL +} + +LoggedMeasurementConfiguration-v1130-IEs ::= SEQUENCE { + plmn-IdentityList-r11 PLMN-IdentityList3-r11 OPTIONAL, -- Need OR + areaConfiguration-v1130 AreaConfiguration-v1130 OPTIONAL, -- Need OR + nonCriticalExtension LoggedMeasurementConfiguration-v1250-IEs OPTIONAL +} + +LoggedMeasurementConfiguration-v1250-IEs ::= SEQUENCE { + targetMBSFN-AreaList-r12 TargetMBSFN-AreaList-r12 OPTIONAL, -- Need OP + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +TargetMBSFN-AreaList-r12 ::= SEQUENCE (SIZE (0..maxMBSFN-Area)) OF TargetMBSFN-Area-r12 + +TargetMBSFN-Area-r12 ::= SEQUENCE { + mbsfn-AreaId-r12 MBSFN-AreaId-r12 OPTIONAL, -- Need OR + carrierFreq-r12 ARFCN-ValueEUTRA-r9, + ... +} + + +MasterInformationBlock ::= SEQUENCE { + dl-Bandwidth ENUMERATED { + n6, n15, n25, n50, n75, n100}, + phich-Config PHICH-Config, + systemFrameNumber BIT STRING (SIZE (8)), + schedulingInfoSIB1-BR-r13 INTEGER (0..31), + spare BIT STRING (SIZE (5)) +} + + + +MBMSCountingRequest-r10 ::= SEQUENCE { + countingRequestList-r10 CountingRequestList-r10, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +CountingRequestList-r10 ::= SEQUENCE (SIZE (1..maxServiceCount)) OF CountingRequestInfo-r10 + +CountingRequestInfo-r10 ::= SEQUENCE { + tmgi-r10 TMGI-r9, + ... +} + + +MBMSCountingResponse-r10 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + countingResponse-r10 MBMSCountingResponse-r10-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +MBMSCountingResponse-r10-IEs ::= SEQUENCE { + mbsfn-AreaIndex-r10 INTEGER (0..maxMBSFN-Area-1) OPTIONAL, + countingResponseList-r10 CountingResponseList-r10 OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +CountingResponseList-r10 ::= SEQUENCE (SIZE (1..maxServiceCount)) OF CountingResponseInfo-r10 + +CountingResponseInfo-r10 ::= SEQUENCE { + countingResponseService-r10 INTEGER (0..maxServiceCount-1), + ... +} + + +MBMSInterestIndication-r11 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + interestIndication-r11 MBMSInterestIndication-r11-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +MBMSInterestIndication-r11-IEs ::= SEQUENCE { + mbms-FreqList-r11 CarrierFreqListMBMS-r11 OPTIONAL, + mbms-Priority-r11 ENUMERATED {true} OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension MBMSInterestIndication-v1310-IEs OPTIONAL +} + +MBMSInterestIndication-v1310-IEs ::= SEQUENCE { + mbms-Services-r13 MBMS-ServiceList-r13 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +MBSFNAreaConfiguration-r9 ::= SEQUENCE { + commonSF-Alloc-r9 CommonSF-AllocPatternList-r9, + commonSF-AllocPeriod-r9 ENUMERATED { + rf4, rf8, rf16, rf32, rf64, rf128, rf256}, + pmch-InfoList-r9 PMCH-InfoList-r9, + nonCriticalExtension MBSFNAreaConfiguration-v930-IEs OPTIONAL +} + +MBSFNAreaConfiguration-v930-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension MBSFNAreaConfiguration-v1250-IEs OPTIONAL +} + +MBSFNAreaConfiguration-v1250-IEs ::= SEQUENCE { + pmch-InfoListExt-r12 PMCH-InfoListExt-r12 OPTIONAL, -- Need OR + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +CommonSF-AllocPatternList-r9 ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig + + +MeasurementReport ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + measurementReport-r8 MeasurementReport-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +MeasurementReport-r8-IEs ::= SEQUENCE { + measResults MeasResults, + nonCriticalExtension MeasurementReport-v8a0-IEs OPTIONAL +} + +MeasurementReport-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +MobilityFromEUTRACommand ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs, + mobilityFromEUTRACommand-r9 MobilityFromEUTRACommand-r9-IEs, + spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE { + cs-FallbackIndicator BOOLEAN, + purpose CHOICE{ + handover Handover, + cellChangeOrder CellChangeOrder + }, + nonCriticalExtension MobilityFromEUTRACommand-v8a0-IEs OPTIONAL +} + +MobilityFromEUTRACommand-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension MobilityFromEUTRACommand-v8d0-IEs OPTIONAL +} + +MobilityFromEUTRACommand-v8d0-IEs ::= SEQUENCE { + bandIndicator BandIndicatorGERAN OPTIONAL, -- Cond GERAN + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +MobilityFromEUTRACommand-r9-IEs ::= SEQUENCE { + cs-FallbackIndicator BOOLEAN, + purpose CHOICE{ + handover Handover, + cellChangeOrder CellChangeOrder, + e-CSFB-r9 E-CSFB-r9, + ... + }, + nonCriticalExtension MobilityFromEUTRACommand-v930-IEs OPTIONAL +} + +MobilityFromEUTRACommand-v930-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension MobilityFromEUTRACommand-v960-IEs OPTIONAL +} + +MobilityFromEUTRACommand-v960-IEs ::= SEQUENCE { + bandIndicator BandIndicatorGERAN OPTIONAL, -- Cond GERAN + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +Handover ::= SEQUENCE { + targetRAT-Type ENUMERATED { + utra, geran, cdma2000-1XRTT, cdma2000-HRPD, + spare4, spare3, spare2, spare1, ...}, + targetRAT-MessageContainer OCTET STRING, + nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN + systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO +} + +CellChangeOrder ::= SEQUENCE { + t304 ENUMERATED { + ms100, ms200, ms500, ms1000, + ms2000, ms4000, ms8000, ms10000-v1310}, + targetRAT-Type CHOICE { + geran SEQUENCE { + physCellId PhysCellIdGERAN, + carrierFreq CarrierFreqGERAN, + networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP + systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP + }, + ... + } +} + +SI-OrPSI-GERAN ::= CHOICE { + si SystemInfoListGERAN, + psi SystemInfoListGERAN +} + +E-CSFB-r9 ::= SEQUENCE { + messageContCDMA2000-1XRTT-r9 OCTET STRING OPTIONAL, -- Need ON + mobilityCDMA2000-HRPD-r9 ENUMERATED { + handover, redirection + } OPTIONAL, -- Need OP + messageContCDMA2000-HRPD-r9 OCTET STRING OPTIONAL, -- Cond concHO + redirectCarrierCDMA2000-HRPD-r9 CarrierFreqCDMA2000 OPTIONAL -- Cond concRedir +} + + +Paging ::= SEQUENCE { + pagingRecordList PagingRecordList OPTIONAL, -- Need ON + systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON + etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension Paging-v890-IEs OPTIONAL +} + +Paging-v890-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension Paging-v920-IEs OPTIONAL +} + +Paging-v920-IEs ::= SEQUENCE { + cmas-Indication-r9 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension Paging-v1130-IEs OPTIONAL +} + +Paging-v1130-IEs ::= SEQUENCE { + eab-ParamModification-r11 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension Paging-v1310-IEs OPTIONAL +} + +Paging-v1310-IEs ::= SEQUENCE { + redistributionIndication-r13 ENUMERATED {true} OPTIONAL, --Need ON + systemInfoModification-eDRX-r13 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord + +PagingRecord ::= SEQUENCE { + ue-Identity PagingUE-Identity, + cn-Domain ENUMERATED {ps, cs}, + ... +} + +PagingUE-Identity ::= CHOICE { + s-TMSI S-TMSI, + imsi IMSI, + ... +} + +IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit + +IMSI-Digit ::= INTEGER (0..9) + + +ProximityIndication-r9 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + proximityIndication-r9 ProximityIndication-r9-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +ProximityIndication-r9-IEs ::= SEQUENCE { + type-r9 ENUMERATED {entering, leaving}, + carrierFreq-r9 CHOICE { + eutra-r9 ARFCN-ValueEUTRA, + utra-r9 ARFCN-ValueUTRA, + ..., + eutra2-v9e0 ARFCN-ValueEUTRA-v9e0 + }, + nonCriticalExtension ProximityIndication-v930-IEs OPTIONAL +} + +ProximityIndication-v930-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RNReconfiguration-r10 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + rnReconfiguration-r10 RNReconfiguration-r10-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RNReconfiguration-r10-IEs ::= SEQUENCE { + rn-SystemInfo-r10 RN-SystemInfo-r10 OPTIONAL, -- Need ON + rn-SubframeConfig-r10 RN-SubframeConfig-r10 OPTIONAL, -- Need ON + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +RN-SystemInfo-r10 ::= SEQUENCE { + systemInformationBlockType1-r10 OCTET STRING (CONTAINING SystemInformationBlockType1) OPTIONAL, -- Need ON + systemInformationBlockType2-r10 SystemInformationBlockType2 OPTIONAL, -- Need ON + ... +} + + +RNReconfigurationComplete-r10 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + rnReconfigurationComplete-r10 RNReconfigurationComplete-r10-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RNReconfigurationComplete-r10-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReconfiguration ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE { + measConfig MeasConfig OPTIONAL, -- Need ON + mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO + dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF + DedicatedInfoNAS OPTIONAL, -- Cond nonHO + radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA + securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO + nonCriticalExtension RRCConnectionReconfiguration-v890-IEs OPTIONAL +} + +RRCConnectionReconfiguration-v890-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING (CONTAINING RRCConnectionReconfiguration-v8m0-IEs) OPTIONAL, + nonCriticalExtension RRCConnectionReconfiguration-v920-IEs OPTIONAL +} + +-- Late non-critical extensions: +RRCConnectionReconfiguration-v8m0-IEs ::= SEQUENCE { + -- Following field is only for pre REL-10 late non-critical extensions + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCConnectionReconfiguration-v10i0-IEs OPTIONAL +} + +RRCConnectionReconfiguration-v10i0-IEs ::= SEQUENCE { + antennaInfoDedicatedPCell-v10i0 AntennaInfoDedicated-v10i0 OPTIONAL, -- Need ON + -- Following field is only for late non-critical extensions from REL-10 + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- Regular non-critical extensions: +RRCConnectionReconfiguration-v920-IEs ::= SEQUENCE { + otherConfig-r9 OtherConfig-r9 OPTIONAL, -- Need ON + fullConfig-r9 ENUMERATED {true} OPTIONAL, -- Cond HO-Reestab + nonCriticalExtension RRCConnectionReconfiguration-v1020-IEs OPTIONAL +} + +RRCConnectionReconfiguration-v1020-IEs ::= SEQUENCE { + sCellToReleaseList-r10 SCellToReleaseList-r10 OPTIONAL, -- Need ON + sCellToAddModList-r10 SCellToAddModList-r10 OPTIONAL, -- Need ON + nonCriticalExtension RRCConnectionReconfiguration-v1130-IEs OPTIONAL +} + +RRCConnectionReconfiguration-v1130-IEs ::= SEQUENCE { + systemInformationBlockType1Dedicated-r11 OCTET STRING (CONTAINING SystemInformationBlockType1) OPTIONAL, -- Need ON + nonCriticalExtension RRCConnectionReconfiguration-v1250-IEs OPTIONAL +} + +RRCConnectionReconfiguration-v1250-IEs ::= SEQUENCE { + wlan-OffloadInfo-r12 CHOICE { + release NULL, + setup SEQUENCE { + wlan-OffloadConfigDedicated-r12 WLAN-OffloadConfig-r12, + t350-r12 ENUMERATED {min5, min10, min20, min30, min60, + min120, min180, spare1} OPTIONAL -- Need OR + } + } OPTIONAL, -- Need ON + scg-Configuration-r12 SCG-Configuration-r12 OPTIONAL, -- Cond nonFullConfig + sl-SyncTxControl-r12 SL-SyncTxControl-r12 OPTIONAL, -- Need ON + sl-DiscConfig-r12 SL-DiscConfig-r12 OPTIONAL, -- Need ON + sl-CommConfig-r12 SL-CommConfig-r12 OPTIONAL, -- Need ON + nonCriticalExtension RRCConnectionReconfiguration-v1310-IEs OPTIONAL +} + +RRCConnectionReconfiguration-v1310-IEs ::= SEQUENCE { + sCellToReleaseListExt-r13 SCellToReleaseListExt-r13 OPTIONAL, -- Need ON + sCellToAddModListExt-r13 SCellToAddModListExt-r13 OPTIONAL, -- Need ON + lwa-Configuration-r13 LWA-Configuration-r13 OPTIONAL, -- Need ON + lwip-Configuration-r13 LWIP-Configuration-r13 OPTIONAL, -- Need ON + rclwi-Configuration-r13 RCLWI-Configuration-r13 OPTIONAL, -- Need ON + nonCriticalExtension RRCConnectionReconfiguration-v14x0-IEs OPTIONAL +} + +RRCConnectionReconfiguration-v14x0-IEs ::= SEQUENCE { + sl-V2X-ConfigDedicated-r14 SL-V2X-ConfigDedicated-r14 OPTIONAL, -- Need ON + sCellToAddModListExt-v14xy SCellToAddModListExt-v14xy OPTIONAL, -- Need ON + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +SL-SyncTxControl-r12 ::= SEQUENCE { + networkControlledSyncTx-r12 ENUMERATED {on, off} OPTIONAL -- Need OP +} + +PSCellToAddMod-r12 ::= SEQUENCE { + sCellIndex-r12 SCellIndex-r10, + cellIdentification-r12 SEQUENCE { + physCellId-r12 PhysCellId, + dl-CarrierFreq-r12 ARFCN-ValueEUTRA-r9 + } OPTIONAL, -- Cond SCellAdd + radioResourceConfigCommonPSCell-r12 RadioResourceConfigCommonPSCell-r12 OPTIONAL, -- Cond SCellAdd + radioResourceConfigDedicatedPSCell-r12 RadioResourceConfigDedicatedPSCell-r12 OPTIONAL, -- Cond SCellAdd2 + ..., + [[ antennaInfoDedicatedPSCell-v1280 AntennaInfoDedicated-v10i0 OPTIONAL -- Need ON + ]], + [[ sCellIndex-r13 SCellIndex-r13 OPTIONAL -- Need ON + ]] +} + +PowerCoordinationInfo-r12 ::= SEQUENCE { + p-MeNB-r12 INTEGER (1..16), + p-SeNB-r12 INTEGER (1..16), + powerControlMode-r12 INTEGER (1..2) +} + +SCellToAddModList-r10 ::= SEQUENCE (SIZE (1..maxSCell-r10)) OF SCellToAddMod-r10 + +SCellToAddModListExt-r13 ::= SEQUENCE (SIZE (1..maxSCell-r13)) OF SCellToAddModExt-r13 + +SCellToAddModListExt-v14xy ::= SEQUENCE (SIZE (1..maxSCell-r13)) OF SCellToAddModExt-v14xy + +SCellToAddMod-r10 ::= SEQUENCE { + sCellIndex-r10 SCellIndex-r10, + cellIdentification-r10 SEQUENCE { + physCellId-r10 PhysCellId, + dl-CarrierFreq-r10 ARFCN-ValueEUTRA + } OPTIONAL, -- Cond SCellAdd + radioResourceConfigCommonSCell-r10 RadioResourceConfigCommonSCell-r10 OPTIONAL, -- Cond SCellAdd + radioResourceConfigDedicatedSCell-r10 RadioResourceConfigDedicatedSCell-r10 OPTIONAL, -- Cond SCellAdd2 + ..., + [[ dl-CarrierFreq-v1090 ARFCN-ValueEUTRA-v9e0 OPTIONAL -- Cond EARFCN-max + ]], + [[ antennaInfoDedicatedSCell-v10i0 AntennaInfoDedicated-v10i0 OPTIONAL -- Need ON + ]], + [[ srs-SwitchFromServCellIndex-r14 INTEGER (0.. 31) OPTIONAL -- Need ON + ]] +} + +SCellToAddModExt-r13 ::= SEQUENCE { + sCellIndex-r13 SCellIndex-r13, + cellIdentification-r13 SEQUENCE { + physCellId-r13 PhysCellId, + dl-CarrierFreq-r13 ARFCN-ValueEUTRA-r9 + } OPTIONAL, -- Cond SCellAdd + radioResourceConfigCommonSCell-r13 RadioResourceConfigCommonSCell-r10 OPTIONAL, -- Cond SCellAdd + radioResourceConfigDedicatedSCell-r13 RadioResourceConfigDedicatedSCell-r10 OPTIONAL, -- Cond SCellAdd2 + antennaInfoDedicatedSCell-r13 AntennaInfoDedicated-v10i0 OPTIONAL -- Need ON +} + +SCellToAddModExt-v14xy ::= SEQUENCE { + srs-SwitchFromServCellIndex-r14 INTEGER (0.. 31) OPTIONAL -- Need ON +} + +SCellToReleaseList-r10 ::= SEQUENCE (SIZE (1..maxSCell-r10)) OF SCellIndex-r10 + +SCellToReleaseListExt-r13 ::= SEQUENCE (SIZE (1..maxSCell-r13)) OF SCellIndex-r13 + +SCG-Configuration-r12 ::= CHOICE { + release NULL, + setup SEQUENCE { + scg-ConfigPartMCG-r12 SEQUENCE { + scg-Counter-r12 INTEGER (0.. 65535) OPTIONAL, -- Need ON + powerCoordinationInfo-r12 PowerCoordinationInfo-r12 OPTIONAL, -- Need ON + ... + } OPTIONAL, -- Need ON + scg-ConfigPartSCG-r12 SCG-ConfigPartSCG-r12 OPTIONAL -- Need ON + } +} + +SCG-ConfigPartSCG-r12 ::= SEQUENCE { + radioResourceConfigDedicatedSCG-r12 RadioResourceConfigDedicatedSCG-r12 OPTIONAL, -- Need ON + sCellToReleaseListSCG-r12 SCellToReleaseList-r10 OPTIONAL, -- Need ON + pSCellToAddMod-r12 PSCellToAddMod-r12 OPTIONAL, -- Need ON + sCellToAddModListSCG-r12 SCellToAddModList-r10 OPTIONAL, -- Need ON + mobilityControlInfoSCG-r12 MobilityControlInfoSCG-r12 OPTIONAL, -- Need ON + ..., + [[ + sCellToReleaseListSCG-Ext-r13 SCellToReleaseListExt-r13 OPTIONAL, -- Need ON + sCellToAddModListSCG-Ext-r13 SCellToAddModListExt-r13 OPTIONAL -- Need ON + ]] +} + +SecurityConfigHO ::= SEQUENCE { + handoverType CHOICE { + intraLTE SEQUENCE { + securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Cond fullConfig + keyChangeIndicator BOOLEAN, + nextHopChainingCount NextHopChainingCount + }, + interRAT SEQUENCE { + securityAlgorithmConfig SecurityAlgorithmConfig, + nas-SecurityParamToEUTRA OCTET STRING (SIZE(6)) + } + }, + ... +} + + + +RRCConnectionReconfigurationComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcConnectionReconfigurationComplete-r8 + RRCConnectionReconfigurationComplete-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE { + nonCriticalExtension RRCConnectionReconfigurationComplete-v8a0-IEs OPTIONAL +} + +RRCConnectionReconfigurationComplete-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCConnectionReconfigurationComplete-v1020-IEs OPTIONAL +} + +RRCConnectionReconfigurationComplete-v1020-IEs ::= SEQUENCE { + rlf-InfoAvailable-r10 ENUMERATED {true} OPTIONAL, + logMeasAvailable-r10 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionReconfigurationComplete-v1130-IEs OPTIONAL +} + +RRCConnectionReconfigurationComplete-v1130-IEs ::= SEQUENCE { + connEstFailInfoAvailable-r11 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionReconfigurationComplete-v1250-IEs OPTIONAL +} + +RRCConnectionReconfigurationComplete-v1250-IEs ::= SEQUENCE { + logMeasAvailableMBSFN-r12 ENUMERATED {true} OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReestablishment ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReestablishment-r8-IEs ::= SEQUENCE { + radioResourceConfigDedicated RadioResourceConfigDedicated, + nextHopChainingCount NextHopChainingCount, + nonCriticalExtension RRCConnectionReestablishment-v8a0-IEs OPTIONAL +} + +RRCConnectionReestablishment-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReestablishmentComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcConnectionReestablishmentComplete-r8 + RRCConnectionReestablishmentComplete-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE { + nonCriticalExtension RRCConnectionReestablishmentComplete-v920-IEs OPTIONAL +} + +RRCConnectionReestablishmentComplete-v920-IEs ::= SEQUENCE { + rlf-InfoAvailable-r9 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionReestablishmentComplete-v8a0-IEs OPTIONAL +} + +RRCConnectionReestablishmentComplete-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCConnectionReestablishmentComplete-v1020-IEs OPTIONAL +} + +RRCConnectionReestablishmentComplete-v1020-IEs ::= SEQUENCE { + logMeasAvailable-r10 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionReestablishmentComplete-v1130-IEs OPTIONAL +} + +RRCConnectionReestablishmentComplete-v1130-IEs ::= SEQUENCE { + connEstFailInfoAvailable-r11 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionReestablishmentComplete-v1250-IEs OPTIONAL +} + +RRCConnectionReestablishmentComplete-v1250-IEs ::= SEQUENCE { + logMeasAvailableMBSFN-r12 ENUMERATED {true} OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReestablishmentReject ::= SEQUENCE { + criticalExtensions CHOICE { + rrcConnectionReestablishmentReject-r8 + RRCConnectionReestablishmentReject-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE { + nonCriticalExtension RRCConnectionReestablishmentReject-v8a0-IEs OPTIONAL +} + +RRCConnectionReestablishmentReject-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReestablishmentRequest ::= SEQUENCE { + criticalExtensions CHOICE { + rrcConnectionReestablishmentRequest-r8 + RRCConnectionReestablishmentRequest-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE { + ue-Identity ReestabUE-Identity, + reestablishmentCause ReestablishmentCause, + spare BIT STRING (SIZE (2)) +} + +ReestabUE-Identity ::= SEQUENCE { + c-RNTI C-RNTI, + physCellId PhysCellId, + shortMAC-I ShortMAC-I +} + +ReestablishmentCause ::= ENUMERATED { + reconfigurationFailure, handoverFailure, + otherFailure, spare1} + + +RRCConnectionReject ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionReject-r8 RRCConnectionReject-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReject-r8-IEs ::= SEQUENCE { + waitTime INTEGER (1..16), + nonCriticalExtension RRCConnectionReject-v8a0-IEs OPTIONAL +} + +RRCConnectionReject-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCConnectionReject-v1020-IEs OPTIONAL +} + +RRCConnectionReject-v1020-IEs ::= SEQUENCE { + extendedWaitTime-r10 INTEGER (1..1800) OPTIONAL, -- Need ON + nonCriticalExtension RRCConnectionReject-v1130-IEs OPTIONAL +} + +RRCConnectionReject-v1130-IEs ::= SEQUENCE { + deprioritisationReq-r11 SEQUENCE { + deprioritisationType-r11 ENUMERATED {frequency, e-utra}, + deprioritisationTimer-r11 ENUMERATED {min5, min10, min15, min30} + } OPTIONAL, -- Need ON + nonCriticalExtension RRCConnectionReject-v1320-IEs OPTIONAL +} + +RRCConnectionReject-v1320-IEs ::= SEQUENCE { + rrc-SuspendIndication-r13 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionRelease ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionRelease-r8-IEs ::= SEQUENCE { + releaseCause ReleaseCause, + redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON + idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP + nonCriticalExtension RRCConnectionRelease-v890-IEs OPTIONAL +} + +RRCConnectionRelease-v890-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING (CONTAINING RRCConnectionRelease-v9e0-IEs) OPTIONAL, + nonCriticalExtension RRCConnectionRelease-v920-IEs OPTIONAL +} + +-- Late non critical extensions +RRCConnectionRelease-v9e0-IEs ::= SEQUENCE { + redirectedCarrierInfo-v9e0 RedirectedCarrierInfo-v9e0 OPTIONAL, -- Cond NoRedirect-r8 + idleModeMobilityControlInfo-v9e0 IdleModeMobilityControlInfo-v9e0 OPTIONAL, -- Cond IdleInfoEUTRA + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- Regular non critical extensions +RRCConnectionRelease-v920-IEs ::= SEQUENCE { + cellInfoList-r9 CHOICE { + geran-r9 CellInfoListGERAN-r9, + utra-FDD-r9 CellInfoListUTRA-FDD-r9, + utra-TDD-r9 CellInfoListUTRA-TDD-r9, + ..., + utra-TDD-r10 CellInfoListUTRA-TDD-r10 + } OPTIONAL, -- Cond Redirection + nonCriticalExtension RRCConnectionRelease-v1020-IEs OPTIONAL +} + +RRCConnectionRelease-v1020-IEs ::= SEQUENCE { + extendedWaitTime-r10 INTEGER (1..1800) OPTIONAL, -- Need ON + nonCriticalExtension RRCConnectionRelease-v1320-IEs OPTIONAL +} + +RRCConnectionRelease-v1320-IEs::= SEQUENCE { + resumeIdentity-r13 ResumeIdentity-r13 OPTIONAL, -- Need OR + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired, + other, cs-FallbackHighPriority-v1020, rrc-Suspend-v1320} + +RedirectedCarrierInfo ::= CHOICE { + eutra ARFCN-ValueEUTRA, + geran CarrierFreqsGERAN, + utra-FDD ARFCN-ValueUTRA, + utra-TDD ARFCN-ValueUTRA, + cdma2000-HRPD CarrierFreqCDMA2000, + cdma2000-1xRTT CarrierFreqCDMA2000, + ..., + utra-TDD-r10 CarrierFreqListUTRA-TDD-r10 +} + +RedirectedCarrierInfo-v9e0 ::= SEQUENCE { + eutra-v9e0 ARFCN-ValueEUTRA-v9e0 +} + +CarrierFreqListUTRA-TDD-r10 ::= SEQUENCE (SIZE (1..maxFreqUTRA-TDD-r10)) OF ARFCN-ValueUTRA + +IdleModeMobilityControlInfo ::= SEQUENCE { + freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON + freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON + freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON + freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON + bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON + bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON + t320 ENUMERATED { + min5, min10, min20, min30, min60, min120, min180, + spare1} OPTIONAL, -- Need OR + ..., + [[ freqPriorityListExtEUTRA-r12 FreqPriorityListExtEUTRA-r12 OPTIONAL -- Need ON + ]], + [[ freqPriorityListEUTRA-v1310 FreqPriorityListEUTRA-v1310 OPTIONAL, -- Need ON + freqPriorityListExtEUTRA-v1310 FreqPriorityListExtEUTRA-v1310 OPTIONAL -- Need ON + ]] +} + +IdleModeMobilityControlInfo-v9e0 ::= SEQUENCE { + freqPriorityListEUTRA-v9e0 SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA-v9e0 +} + +FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA + +FreqPriorityListExtEUTRA-r12 ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA-r12 + +FreqPriorityListEUTRA-v1310 ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA-v1310 + +FreqPriorityListExtEUTRA-v1310 ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA-v1310 + +FreqPriorityEUTRA ::= SEQUENCE { + carrierFreq ARFCN-ValueEUTRA, + cellReselectionPriority CellReselectionPriority +} + +FreqPriorityEUTRA-v9e0 ::= SEQUENCE { + carrierFreq-v9e0 ARFCN-ValueEUTRA-v9e0 OPTIONAL -- Cond EARFCN-max +} + +FreqPriorityEUTRA-r12 ::= SEQUENCE { + carrierFreq-r12 ARFCN-ValueEUTRA-r9, + cellReselectionPriority-r12 CellReselectionPriority +} + +FreqPriorityEUTRA-v1310 ::= SEQUENCE { + cellReselectionSubPriority-r13 CellReselectionSubPriority-r13 OPTIONAL -- Need ON +} + +FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN + +FreqsPriorityGERAN ::= SEQUENCE { + carrierFreqs CarrierFreqsGERAN, + cellReselectionPriority CellReselectionPriority +} + +FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD + +FreqPriorityUTRA-FDD ::= SEQUENCE { + carrierFreq ARFCN-ValueUTRA, + cellReselectionPriority CellReselectionPriority +} + +FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD + +FreqPriorityUTRA-TDD ::= SEQUENCE { + carrierFreq ARFCN-ValueUTRA, + cellReselectionPriority CellReselectionPriority +} + +BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD + +BandClassPriorityHRPD ::= SEQUENCE { + bandClass BandclassCDMA2000, + cellReselectionPriority CellReselectionPriority +} + +BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT + +BandClassPriority1XRTT ::= SEQUENCE { + bandClass BandclassCDMA2000, + cellReselectionPriority CellReselectionPriority +} + +CellInfoListGERAN-r9 ::= SEQUENCE (SIZE (1..maxCellInfoGERAN-r9)) OF CellInfoGERAN-r9 + +CellInfoGERAN-r9 ::= SEQUENCE { + physCellId-r9 PhysCellIdGERAN, + carrierFreq-r9 CarrierFreqGERAN, + systemInformation-r9 SystemInfoListGERAN +} + +CellInfoListUTRA-FDD-r9 ::= SEQUENCE (SIZE (1..maxCellInfoUTRA-r9)) OF CellInfoUTRA-FDD-r9 + +CellInfoUTRA-FDD-r9 ::= SEQUENCE { + physCellId-r9 PhysCellIdUTRA-FDD, + utra-BCCH-Container-r9 OCTET STRING +} + +CellInfoListUTRA-TDD-r9 ::= SEQUENCE (SIZE (1..maxCellInfoUTRA-r9)) OF CellInfoUTRA-TDD-r9 + +CellInfoUTRA-TDD-r9 ::= SEQUENCE { + physCellId-r9 PhysCellIdUTRA-TDD, + utra-BCCH-Container-r9 OCTET STRING +} + +CellInfoListUTRA-TDD-r10 ::= SEQUENCE (SIZE (1..maxCellInfoUTRA-r9)) OF CellInfoUTRA-TDD-r10 + +CellInfoUTRA-TDD-r10 ::= SEQUENCE { + physCellId-r10 PhysCellIdUTRA-TDD, + carrierFreq-r10 ARFCN-ValueUTRA, + utra-BCCH-Container-r10 OCTET STRING +} + + +RRCConnectionRequest ::= SEQUENCE { + criticalExtensions CHOICE { + rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionRequest-r8-IEs ::= SEQUENCE { + ue-Identity InitialUE-Identity, + establishmentCause EstablishmentCause, + spare BIT STRING (SIZE (1)) +} + +InitialUE-Identity ::= CHOICE { + s-TMSI S-TMSI, + randomValue BIT STRING (SIZE (40)) +} + +EstablishmentCause ::= ENUMERATED { + emergency, highPriorityAccess, mt-Access, mo-Signalling, + mo-Data, delayTolerantAccess-v1020, mo-VoiceCall-v1280, spare1} + + +RRCConnectionResume-r13 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionResume-r13 RRCConnectionResume-r13-IEs, + spare3 NULL, + spare2 NULL, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionResume-r13-IEs ::= SEQUENCE { + radioResourceConfigDedicated-r13 RadioResourceConfigDedicated OPTIONAL, -- Need ON + nextHopChainingCount-r13 NextHopChainingCount, + measConfig-r13 MeasConfig OPTIONAL, -- Need ON + antennaInfoDedicatedPCell-r13 AntennaInfoDedicated-v10i0 OPTIONAL, -- Need ON + drb-ContinueROHC-r13 ENUMERATED {true} OPTIONAL, -- Need OP + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionResumeComplete-r13 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcConnectionResumeComplete-r13 RRCConnectionResumeComplete-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionResumeComplete-r13-IEs ::= SEQUENCE { + selectedPLMN-Identity-r13 INTEGER (1..maxPLMN-r11) OPTIONAL, + dedicatedInfoNAS-r13 DedicatedInfoNAS OPTIONAL, + rlf-InfoAvailable-r13 ENUMERATED {true} OPTIONAL, + logMeasAvailable-r13 ENUMERATED {true} OPTIONAL, + connEstFailInfoAvailable-r13 ENUMERATED {true} OPTIONAL, + mobilityState-r13 ENUMERATED {normal, medium, high, spare} OPTIONAL, + mobilityHistoryAvail-r13 ENUMERATED {true} OPTIONAL, + logMeasAvailableMBSFN-r13 ENUMERATED {true} OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionResumeRequest-r13 ::= SEQUENCE { + criticalExtensions CHOICE { + rrcConnectionResumeRequest-r13 RRCConnectionResumeRequest-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionResumeRequest-r13-IEs ::= SEQUENCE { + resumeIdentity-r13 CHOICE { + resumeID-r13 ResumeIdentity-r13, + truncatedResumeID-r13 BIT STRING (SIZE (24)) + }, + shortResumeMAC-I-r13 BIT STRING (SIZE (16)), + resumeCause-r13 ResumeCause, + spare BIT STRING (SIZE (1)) +} + +ResumeCause ::= ENUMERATED { + emergency, highPriorityAccess, mt-Access, mo-Signalling, + mo-Data, delayTolerantAccess-v1020, mo-VoiceCall-v1280, spare1} + + + +RRCConnectionSetup ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionSetup-r8-IEs ::= SEQUENCE { + radioResourceConfigDedicated RadioResourceConfigDedicated, + nonCriticalExtension RRCConnectionSetup-v8a0-IEs OPTIONAL +} + +RRCConnectionSetup-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionSetupComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE { + selectedPLMN-Identity INTEGER (1..maxPLMN-r11), + registeredMME RegisteredMME OPTIONAL, + dedicatedInfoNAS DedicatedInfoNAS, + nonCriticalExtension RRCConnectionSetupComplete-v8a0-IEs OPTIONAL +} + +RRCConnectionSetupComplete-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCConnectionSetupComplete-v1020-IEs OPTIONAL +} + +RRCConnectionSetupComplete-v1020-IEs ::= SEQUENCE { + gummei-Type-r10 ENUMERATED {native, mapped} OPTIONAL, + rlf-InfoAvailable-r10 ENUMERATED {true} OPTIONAL, + logMeasAvailable-r10 ENUMERATED {true} OPTIONAL, + rn-SubframeConfigReq-r10 ENUMERATED {required, notRequired} OPTIONAL, + nonCriticalExtension RRCConnectionSetupComplete-v1130-IEs OPTIONAL +} + +RRCConnectionSetupComplete-v1130-IEs ::= SEQUENCE { + connEstFailInfoAvailable-r11 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionSetupComplete-v1250-IEs OPTIONAL +} + +RRCConnectionSetupComplete-v1250-IEs ::= SEQUENCE { + mobilityState-r12 ENUMERATED {normal, medium, high, spare} OPTIONAL, + mobilityHistoryAvail-r12 ENUMERATED {true} OPTIONAL, + logMeasAvailableMBSFN-r12 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionSetupComplete-v1320-IEs OPTIONAL +} + +RRCConnectionSetupComplete-v1320-IEs ::= SEQUENCE { + ce-ModeB-r13 ENUMERATED {supported} OPTIONAL, + s-TMSI-r13 S-TMSI OPTIONAL, + attachWithoutPDN-Connectivity-r13 ENUMERATED {true} OPTIONAL, + up-CIoT-EPS-Optimisation-r13 ENUMERATED {true} OPTIONAL, + cp-CIoT-EPS-Optimisation-r13 ENUMERATED {true} OPTIONAL, + nonCriticalExtension RRCConnectionSetupComplete-v1330-IEs OPTIONAL +} + +RRCConnectionSetupComplete-v1330-IEs ::= SEQUENCE { + ue-CE-NeedULGaps-r13 ENUMERATED {true} OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +RegisteredMME ::= SEQUENCE { + plmn-Identity PLMN-Identity OPTIONAL, + mmegi BIT STRING (SIZE (16)), + mmec MMEC +} + + +SCGFailureInformation-r12 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + scgFailureInformation-r12 SCGFailureInformation-r12-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +SCGFailureInformation-r12-IEs ::= SEQUENCE { + failureReportSCG-r12 FailureReportSCG-r12 OPTIONAL, + nonCriticalExtension SCGFailureInformation-v1310-IEs OPTIONAL +} + +SCGFailureInformation-v1310-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +FailureReportSCG-r12 ::= SEQUENCE { + failureType-r12 ENUMERATED {t313-Expiry, randomAccessProblem, + rlc-MaxNumRetx, scg-ChangeFailure }, + measResultServFreqList-r12 MeasResultServFreqList-r10 OPTIONAL, + measResultNeighCells-r12 MeasResultList2EUTRA-r9 OPTIONAL, + ..., + [[ failureType-v1290 ENUMERATED {maxUL-TimingDiff-v1290} OPTIONAL + ]], + [[ measResultServFreqListExt-r13 MeasResultServFreqListExt-r13 OPTIONAL + ]] +} + + +SCPTMConfiguration-r13 ::= SEQUENCE { + sc-mtch-InfoList-r13 SC-MTCH-InfoList-r13, + scptm-NeighbourCellList-r13 SCPTM-NeighbourCellList-r13 OPTIONAL, -- Need OP + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SCPTMConfiguration-v1340 OPTIONAL +} + +SCPTMConfiguration-v1340 ::= SEQUENCE { + p-b-r13 INTEGER (0..3) OPTIONAL, -- Need ON + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SecurityModeCommand ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + securityModeCommand-r8 SecurityModeCommand-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +SecurityModeCommand-r8-IEs ::= SEQUENCE { + securityConfigSMC SecurityConfigSMC, + nonCriticalExtension SecurityModeCommand-v8a0-IEs OPTIONAL +} + +SecurityModeCommand-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +SecurityConfigSMC ::= SEQUENCE { + securityAlgorithmConfig SecurityAlgorithmConfig, + ... +} + + +SecurityModeComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + securityModeComplete-r8 SecurityModeComplete-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SecurityModeComplete-r8-IEs ::= SEQUENCE { + nonCriticalExtension SecurityModeComplete-v8a0-IEs OPTIONAL +} + +SecurityModeComplete-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SecurityModeFailure ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + securityModeFailure-r8 SecurityModeFailure-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SecurityModeFailure-r8-IEs ::= SEQUENCE { + nonCriticalExtension SecurityModeFailure-v8a0-IEs OPTIONAL +} + +SecurityModeFailure-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SidelinkUEInformation-r12 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + sidelinkUEInformation-r12 SidelinkUEInformation-r12-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +SidelinkUEInformation-r12-IEs ::= SEQUENCE { + commRxInterestedFreq-r12 ARFCN-ValueEUTRA-r9 OPTIONAL, + commTxResourceReq-r12 SL-CommTxResourceReq-r12 OPTIONAL, + discRxInterest-r12 ENUMERATED {true} OPTIONAL, + discTxResourceReq-r12 INTEGER (1..63) OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SidelinkUEInformation-v1310-IEs OPTIONAL +} + +SidelinkUEInformation-v1310-IEs ::= SEQUENCE { + commTxResourceReqUC-r13 SL-CommTxResourceReq-r12 OPTIONAL, + commTxResourceInfoReqRelay-r13 SEQUENCE { + commTxResourceReqRelay-r13 SL-CommTxResourceReq-r12 OPTIONAL, + commTxResourceReqRelayUC-r13 SL-CommTxResourceReq-r12 OPTIONAL, + ue-Type-r13 ENUMERATED {relayUE, remoteUE} + } OPTIONAL, + discTxResourceReq-v1310 SEQUENCE { + carrierFreqDiscTx-r13 INTEGER (1..maxFreq) OPTIONAL, + discTxResourceReqAddFreq-r13 SL-DiscTxResourceReqPerFreqList-r13 OPTIONAL + } OPTIONAL, + discTxResourceReqPS-r13 SL-DiscTxResourceReq-r13 OPTIONAL, + discRxGapReq-r13 SL-GapRequest-r13 OPTIONAL, + discTxGapReq-r13 SL-GapRequest-r13 OPTIONAL, + discSysInfoReportFreqList-r13 SL-DiscSysInfoReportFreqList-r13 OPTIONAL, + nonCriticalExtension SidelinkUEInformation-v14x0-IEs OPTIONAL +} + +SidelinkUEInformation-v14x0-IEs ::= SEQUENCE { + v2x-CommRxInterestedFreq-r14 INTEGER (0..maxFreq) OPTIONAL, + v2x-CommTxResourceReq-r14 V2X-CommTxResourceReq-r14 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +SL-CommTxResourceReq-r12 ::= SEQUENCE { + carrierFreq-r12 ARFCN-ValueEUTRA-r9 OPTIONAL, + destinationInfoList-r12 SL-DestinationInfoList-r12 +} + +V2X-CommTxResourceReq-r14 ::= SEQUENCE { + v2x-CommTxFreq-r14 INTEGER (0..maxFreq) OPTIONAL, + v2x-DestinationInfoList-r14 SL-DestinationInfoList-r12 OPTIONAL +} + +SL-DiscTxResourceReqPerFreqList-r13 ::= SEQUENCE (SIZE (1..maxFreq)) OF SL-DiscTxResourceReq-r13 + +SL-DiscTxResourceReq-r13 ::= SEQUENCE { + carrierFreqDiscTx-r13 INTEGER (1..maxFreq) OPTIONAL, + discTxResourceReq-r13 INTEGER (1..63) +} + +SL-DestinationInfoList-r12 ::= SEQUENCE (SIZE (1..maxSL-Dest-r12)) OF SL-DestinationIdentity-r12 + +SL-DestinationIdentity-r12 ::= BIT STRING (SIZE (24)) + +SL-DiscSysInfoReportFreqList-r13 ::= SEQUENCE (SIZE (1.. maxSL-DiscSysInfoReportFreq-r13)) OF SL-DiscSysInfoReport-r13 + + +SystemInformation-BR-r13 ::= SystemInformation + +SystemInformation ::= SEQUENCE { + criticalExtensions CHOICE { + systemInformation-r8 SystemInformation-r8-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} +SystemInformation-r8-IEs ::= SEQUENCE { + sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE { + sib2 SystemInformationBlockType2, + sib3 SystemInformationBlockType3, + sib4 SystemInformationBlockType4, + sib5 SystemInformationBlockType5, + sib6 SystemInformationBlockType6, + sib7 SystemInformationBlockType7, + sib8 SystemInformationBlockType8, + sib9 SystemInformationBlockType9, + sib10 SystemInformationBlockType10, + sib11 SystemInformationBlockType11, + ..., + sib12-v920 SystemInformationBlockType12-r9, + sib13-v920 SystemInformationBlockType13-r9, + sib14-v1130 SystemInformationBlockType14-r11, + sib15-v1130 SystemInformationBlockType15-r11, + sib16-v1130 SystemInformationBlockType16-r11, + sib17-v1250 SystemInformationBlockType17-r12, + sib18-v1250 SystemInformationBlockType18-r12, + sib19-v1250 SystemInformationBlockType19-r12, + sib20-v1310 SystemInformationBlockType20-r13, + sib21-v14x0 SystemInformationBlockType21-r14 + }, + nonCriticalExtension SystemInformation-v8a0-IEs OPTIONAL +} + +SystemInformation-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SystemInformationBlockType1-BR-r13 ::= SystemInformationBlockType1 + +SystemInformationBlockType1 ::= SEQUENCE { + cellAccessRelatedInfo SEQUENCE { + plmn-IdentityList PLMN-IdentityList, + trackingAreaCode TrackingAreaCode, + cellIdentity CellIdentity, + cellBarred ENUMERATED {barred, notBarred}, + intraFreqReselection ENUMERATED {allowed, notAllowed}, + csg-Indication BOOLEAN, + csg-Identity CSG-Identity OPTIONAL -- Need OR + }, + cellSelectionInfo SEQUENCE { + q-RxLevMin Q-RxLevMin, + q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP + }, + p-Max P-Max OPTIONAL, -- Need OP + freqBandIndicator FreqBandIndicator, + schedulingInfoList SchedulingInfoList, + tdd-Config TDD-Config OPTIONAL, -- Cond TDD + si-WindowLength ENUMERATED { + ms1, ms2, ms5, ms10, ms15, ms20, + ms40}, + systemInfoValueTag INTEGER (0..31), + nonCriticalExtension SystemInformationBlockType1-v890-IEs OPTIONAL +} + +SystemInformationBlockType1-v890-IEs::= SEQUENCE { + lateNonCriticalExtension OCTET STRING (CONTAINING SystemInformationBlockType1-v8h0-IEs) OPTIONAL, + nonCriticalExtension SystemInformationBlockType1-v920-IEs OPTIONAL +} + +-- Late non critical extensions +SystemInformationBlockType1-v8h0-IEs ::= SEQUENCE { + multiBandInfoList MultiBandInfoList OPTIONAL, -- Need OR + nonCriticalExtension SystemInformationBlockType1-v9e0-IEs OPTIONAL +} + +SystemInformationBlockType1-v9e0-IEs ::= SEQUENCE { + freqBandIndicator-v9e0 FreqBandIndicator-v9e0 OPTIONAL, -- Cond FBI-max + multiBandInfoList-v9e0 MultiBandInfoList-v9e0 OPTIONAL, -- Cond mFBI-max + nonCriticalExtension SystemInformationBlockType1-v10j0-IEs OPTIONAL +} + +SystemInformationBlockType1-v10j0-IEs ::= SEQUENCE { + freqBandInfo-r10 NS-PmaxList-r10 OPTIONAL, -- Need OR + multiBandInfoList-v10j0 MultiBandInfoList-v10j0 OPTIONAL, -- Need OR + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- Regular non critical extensions +SystemInformationBlockType1-v920-IEs ::= SEQUENCE { + ims-EmergencySupport-r9 ENUMERATED {true} OPTIONAL, -- Need OR + cellSelectionInfo-v920 CellSelectionInfo-v920 OPTIONAL, -- Cond RSRQ + nonCriticalExtension SystemInformationBlockType1-v1130-IEs OPTIONAL +} + +SystemInformationBlockType1-v1130-IEs ::= SEQUENCE { + tdd-Config-v1130 TDD-Config-v1130 OPTIONAL, -- Cond TDD-OR + cellSelectionInfo-v1130 CellSelectionInfo-v1130 OPTIONAL, -- Cond WB-RSRQ + nonCriticalExtension SystemInformationBlockType1-v1250-IEs OPTIONAL +} + +SystemInformationBlockType1-v1250-IEs ::= SEQUENCE { + cellAccessRelatedInfo-v1250 SEQUENCE { + category0Allowed-r12 ENUMERATED {true} OPTIONAL -- Need OP + }, + cellSelectionInfo-v1250 CellSelectionInfo-v1250 OPTIONAL, -- Cond RSRQ2 + freqBandIndicatorPriority-r12 ENUMERATED {true} OPTIONAL, -- Cond mFBI + nonCriticalExtension SystemInformationBlockType1-v1310-IEs OPTIONAL +} + +SystemInformationBlockType1-v1310-IEs ::= SEQUENCE { + hyperSFN-r13 BIT STRING (SIZE (10)) OPTIONAL, -- Need OR + eDRX-Allowed-r13 ENUMERATED {true} OPTIONAL, -- Need OR + cellSelectionInfoCE-r13 CellSelectionInfoCE-r13 OPTIONAL, -- Need OP + bandwidthReducedAccessRelatedInfo-r13 SEQUENCE { + si-WindowLength-BR-r13 ENUMERATED { + ms20, ms40, ms60, ms80, ms120, + ms160, ms200, spare}, + si-RepetitionPattern-r13 ENUMERATED {everyRF, every2ndRF, every4thRF, + every8thRF}, + schedulingInfoList-BR-r13 SchedulingInfoList-BR-r13 OPTIONAL, -- Need OR + fdd-DownlinkOrTddSubframeBitmapBR-r13 CHOICE { + subframePattern10-r13 BIT STRING (SIZE (10)), + subframePattern40-r13 BIT STRING (SIZE (40)) + } OPTIONAL, -- Need OP + fdd-UplinkSubframeBitmapBR-r13 BIT STRING (SIZE (10)) OPTIONAL, -- Need OP + startSymbolBR-r13 INTEGER (1..4), + si-HoppingConfigCommon-r13 ENUMERATED {on,off}, + si-ValidityTime-r13 ENUMERATED {true} OPTIONAL, -- Need OP + systemInfoValueTagList-r13 SystemInfoValueTagList-r13 OPTIONAL -- Need OR + } OPTIONAL, -- Cond BW-reduced + nonCriticalExtension SystemInformationBlockType1-v1320-IEs OPTIONAL +} + +SystemInformationBlockType1-v1320-IEs ::= SEQUENCE { + freqHoppingParametersDL-r13 SEQUENCE { + mpdcch-pdsch-HoppingNB-r13 ENUMERATED {nb2, nb4} OPTIONAL, -- Need OR + interval-DLHoppingConfigCommonModeA-r13 CHOICE { + interval-FDD-r13 ENUMERATED {int1, int2, int4, int8}, + interval-TDD-r13 ENUMERATED {int1, int5, int10, int20} + } OPTIONAL, -- Need OR + interval-DLHoppingConfigCommonModeB-r13 CHOICE { + interval-FDD-r13 ENUMERATED {int2, int4, int8, int16}, + interval-TDD-r13 ENUMERATED { int5, int10, int20, int40} + } OPTIONAL, -- Need OR + mpdcch-pdsch-HoppingOffset-r13 INTEGER (1..maxAvailNarrowBands-r13) OPTIONAL -- Need OR + } OPTIONAL, -- Cond Hopping + nonCriticalExtension SystemInformationBlockType1-v14xy-IEs OPTIONAL +} + +SystemInformationBlockType1-v14xy-IEs ::= SEQUENCE { + eCallOverIMS-Support-r14 ENUMERATED {true} OPTIONAL, -- Need OR + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +PLMN-IdentityList ::= SEQUENCE (SIZE (1..maxPLMN-r11)) OF PLMN-IdentityInfo + +PLMN-IdentityInfo ::= SEQUENCE { + plmn-Identity PLMN-Identity, + cellReservedForOperatorUse ENUMERATED {reserved, notReserved} +} + +SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo + +SchedulingInfo ::= SEQUENCE { + si-Periodicity ENUMERATED { + rf8, rf16, rf32, rf64, rf128, rf256, rf512}, + sib-MappingInfo SIB-MappingInfo +} + +SchedulingInfoList-BR-r13 ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo-BR-r13 + +SchedulingInfo-BR-r13 ::= SEQUENCE { + si-Narrowband-r13 INTEGER (1..maxAvailNarrowBands-r13), + si-TBS-r13 ENUMERATED {b152, b208, b256, b328, b408, b504, b600, b712, + b808, b936} +} + +SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type + +SIB-Type ::= ENUMERATED { + sibType3, sibType4, sibType5, sibType6, + sibType7, sibType8, sibType9, sibType10, + sibType11, sibType12-v920, sibType13-v920, + sibType14-v1130, sibType15-v1130, + sibType16-v1130, sibType17-v1250, sibType18-v1250, + ..., sibType19-v1250, sibType20-v1310, sibType21-v14x0} + +SystemInfoValueTagList-r13 ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SystemInfoValueTagSI-r13 + +SystemInfoValueTagSI-r13 ::= INTEGER (0..3) + +CellSelectionInfo-v920 ::= SEQUENCE { + q-QualMin-r9 Q-QualMin-r9, + q-QualMinOffset-r9 INTEGER (1..8) OPTIONAL -- Need OP +} + +CellSelectionInfo-v1130 ::= SEQUENCE { + q-QualMinWB-r11 Q-QualMin-r9 +} + +CellSelectionInfo-v1250 ::= SEQUENCE { + q-QualMinRSRQ-OnAllSymbols-r12 Q-QualMin-r9 +} + + +UEAssistanceInformation-r11 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + ueAssistanceInformation-r11 UEAssistanceInformation-r11-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEAssistanceInformation-r11-IEs ::= SEQUENCE { + powerPrefIndication-r11 ENUMERATED {normal, lowPowerConsumption} OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UECapabilityEnquiry ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UECapabilityEnquiry-r8-IEs ::= SEQUENCE { + ue-CapabilityRequest UE-CapabilityRequest, + nonCriticalExtension UECapabilityEnquiry-v8a0-IEs OPTIONAL +} + +UECapabilityEnquiry-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UECapabilityEnquiry-v1180-IEs OPTIONAL +} + +UECapabilityEnquiry-v1180-IEs ::= SEQUENCE { + requestedFrequencyBands-r11 SEQUENCE (SIZE (1..16)) OF FreqBandIndicator-r11 OPTIONAL, + nonCriticalExtension UECapabilityEnquiry-v1310-IEs OPTIONAL +} + +UECapabilityEnquiry-v1310-IEs ::= SEQUENCE { + requestReducedFormat-r13 ENUMERATED {true} OPTIONAL, -- Need ON + requestSkipFallbackComb-r13 ENUMERATED {true} OPTIONAL, -- Need ON + requestedMaxCCsDL-r13 INTEGER (2..32) OPTIONAL, -- Need ON + requestedMaxCCsUL-r13 INTEGER (2..32) OPTIONAL, -- Need ON + requestReducedIntNonContComb-r13 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type + + +UECapabilityInformation ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UECapabilityInformation-r8-IEs ::= SEQUENCE { + ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList, + nonCriticalExtension UECapabilityInformation-v8a0-IEs OPTIONAL +} + +UECapabilityInformation-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UECapabilityInformation-v1250-IEs OPTIONAL +} + +UECapabilityInformation-v1250-IEs ::= SEQUENCE { + ue-RadioPagingInfo-r12 UE-RadioPagingInfo-r12 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UEInformationRequest-r9 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + ueInformationRequest-r9 UEInformationRequest-r9-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEInformationRequest-r9-IEs ::= SEQUENCE { + rach-ReportReq-r9 BOOLEAN, + rlf-ReportReq-r9 BOOLEAN, + nonCriticalExtension UEInformationRequest-v930-IEs OPTIONAL +} + +UEInformationRequest-v930-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UEInformationRequest-v1020-IEs OPTIONAL +} + +UEInformationRequest-v1020-IEs ::= SEQUENCE { + logMeasReportReq-r10 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension UEInformationRequest-v1130-IEs OPTIONAL +} + +UEInformationRequest-v1130-IEs ::= SEQUENCE { + connEstFailReportReq-r11 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension UEInformationRequest-v1250-IEs OPTIONAL +} + +UEInformationRequest-v1250-IEs ::= SEQUENCE { + mobilityHistoryReportReq-r12 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UEInformationResponse-r9 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + ueInformationResponse-r9 UEInformationResponse-r9-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEInformationResponse-r9-IEs ::= SEQUENCE { + rach-Report-r9 SEQUENCE { + numberOfPreamblesSent-r9 NumberOfPreamblesSent-r11, + contentionDetected-r9 BOOLEAN + } OPTIONAL, + rlf-Report-r9 RLF-Report-r9 OPTIONAL, + nonCriticalExtension UEInformationResponse-v930-IEs OPTIONAL +} + +-- Late non critical extensions +UEInformationResponse-v9e0-IEs ::= SEQUENCE { + rlf-Report-v9e0 RLF-Report-v9e0 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- Regular non critical extensions +UEInformationResponse-v930-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING (CONTAINING UEInformationResponse-v9e0-IEs) OPTIONAL, + nonCriticalExtension UEInformationResponse-v1020-IEs OPTIONAL +} + +UEInformationResponse-v1020-IEs ::= SEQUENCE { + logMeasReport-r10 LogMeasReport-r10 OPTIONAL, + nonCriticalExtension UEInformationResponse-v1130-IEs OPTIONAL +} + +UEInformationResponse-v1130-IEs ::= SEQUENCE { + connEstFailReport-r11 ConnEstFailReport-r11 OPTIONAL, + nonCriticalExtension UEInformationResponse-v1250-IEs OPTIONAL +} + +UEInformationResponse-v1250-IEs ::= SEQUENCE { + mobilityHistoryReport-r12 MobilityHistoryReport-r12 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +RLF-Report-r9 ::= SEQUENCE { + measResultLastServCell-r9 SEQUENCE { + rsrpResult-r9 RSRP-Range, + rsrqResult-r9 RSRQ-Range OPTIONAL + }, + measResultNeighCells-r9 SEQUENCE { + measResultListEUTRA-r9 MeasResultList2EUTRA-r9 OPTIONAL, + measResultListUTRA-r9 MeasResultList2UTRA-r9 OPTIONAL, + measResultListGERAN-r9 MeasResultListGERAN OPTIONAL, + measResultsCDMA2000-r9 MeasResultList2CDMA2000-r9 OPTIONAL + } OPTIONAL, + ..., + [[ locationInfo-r10 LocationInfo-r10 OPTIONAL, + failedPCellId-r10 CHOICE { + cellGlobalId-r10 CellGlobalIdEUTRA, + pci-arfcn-r10 SEQUENCE { + physCellId-r10 PhysCellId, + carrierFreq-r10 ARFCN-ValueEUTRA + } + } OPTIONAL, + reestablishmentCellId-r10 CellGlobalIdEUTRA OPTIONAL, + timeConnFailure-r10 INTEGER (0..1023) OPTIONAL, + connectionFailureType-r10 ENUMERATED {rlf, hof} OPTIONAL, + previousPCellId-r10 CellGlobalIdEUTRA OPTIONAL + ]], + [[ failedPCellId-v1090 SEQUENCE { + carrierFreq-v1090 ARFCN-ValueEUTRA-v9e0 + } OPTIONAL + ]], + [[ basicFields-r11 SEQUENCE { + c-RNTI-r11 C-RNTI, + rlf-Cause-r11 ENUMERATED { + t310-Expiry, randomAccessProblem, + rlc-MaxNumRetx, t312-Expiry-r12}, + timeSinceFailure-r11 TimeSinceFailure-r11 + } OPTIONAL, + previousUTRA-CellId-r11 SEQUENCE { + carrierFreq-r11 ARFCN-ValueUTRA, + physCellId-r11 CHOICE { + fdd-r11 PhysCellIdUTRA-FDD, + tdd-r11 PhysCellIdUTRA-TDD + }, + cellGlobalId-r11 CellGlobalIdUTRA OPTIONAL + } OPTIONAL, + selectedUTRA-CellId-r11 SEQUENCE { + carrierFreq-r11 ARFCN-ValueUTRA, + physCellId-r11 CHOICE { + fdd-r11 PhysCellIdUTRA-FDD, + tdd-r11 PhysCellIdUTRA-TDD + } + } OPTIONAL + ]], + [[ failedPCellId-v1250 SEQUENCE { + tac-FailedPCell-r12 TrackingAreaCode + } OPTIONAL, + measResultLastServCell-v1250 RSRQ-Range-v1250 OPTIONAL, + lastServCellRSRQ-Type-r12 RSRQ-Type-r12 OPTIONAL, + measResultListEUTRA-v1250 MeasResultList2EUTRA-v1250 OPTIONAL + ]], + [[ drb-EstablishedWithQCI-1-r13 ENUMERATED {qci1} OPTIONAL + ]] +} + +RLF-Report-v9e0 ::= SEQUENCE { + measResultListEUTRA-v9e0 MeasResultList2EUTRA-v9e0 +} + +MeasResultList2EUTRA-r9 ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2EUTRA-r9 + +MeasResultList2EUTRA-v9e0 ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2EUTRA-v9e0 + +MeasResultList2EUTRA-v1250 ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2EUTRA-v1250 + +MeasResult2EUTRA-r9 ::= SEQUENCE { + carrierFreq-r9 ARFCN-ValueEUTRA, + measResultList-r9 MeasResultListEUTRA +} + +MeasResult2EUTRA-v9e0 ::= SEQUENCE { + carrierFreq-v9e0 ARFCN-ValueEUTRA-v9e0 OPTIONAL +} + +MeasResult2EUTRA-v1250 ::= SEQUENCE { + rsrq-Type-r12 RSRQ-Type-r12 OPTIONAL +} + +MeasResultList2UTRA-r9 ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2UTRA-r9 + +MeasResult2UTRA-r9 ::= SEQUENCE { + carrierFreq-r9 ARFCN-ValueUTRA, + measResultList-r9 MeasResultListUTRA +} + +MeasResultList2CDMA2000-r9 ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2CDMA2000-r9 + +MeasResult2CDMA2000-r9 ::= SEQUENCE { + carrierFreq-r9 CarrierFreqCDMA2000, + measResultList-r9 MeasResultsCDMA2000 +} + +LogMeasReport-r10 ::= SEQUENCE { + absoluteTimeStamp-r10 AbsoluteTimeInfo-r10, + traceReference-r10 TraceReference-r10, + traceRecordingSessionRef-r10 OCTET STRING (SIZE (2)), + tce-Id-r10 OCTET STRING (SIZE (1)), + logMeasInfoList-r10 LogMeasInfoList-r10, + logMeasAvailable-r10 ENUMERATED {true} OPTIONAL, + ... +} + +LogMeasInfoList-r10 ::= SEQUENCE (SIZE (1..maxLogMeasReport-r10)) OF LogMeasInfo-r10 + +LogMeasInfo-r10 ::= SEQUENCE { + locationInfo-r10 LocationInfo-r10 OPTIONAL, + relativeTimeStamp-r10 INTEGER (0..7200), + servCellIdentity-r10 CellGlobalIdEUTRA, + measResultServCell-r10 SEQUENCE { + rsrpResult-r10 RSRP-Range, + rsrqResult-r10 RSRQ-Range + }, + measResultNeighCells-r10 SEQUENCE { + measResultListEUTRA-r10 MeasResultList2EUTRA-r9 OPTIONAL, + measResultListUTRA-r10 MeasResultList2UTRA-r9 OPTIONAL, + measResultListGERAN-r10 MeasResultList2GERAN-r10 OPTIONAL, + measResultListCDMA2000-r10 MeasResultList2CDMA2000-r9 OPTIONAL + } OPTIONAL, + ..., + [[ measResultListEUTRA-v1090 MeasResultList2EUTRA-v9e0 OPTIONAL + ]], + [[ measResultListMBSFN-r12 MeasResultListMBSFN-r12 OPTIONAL, + measResultServCell-v1250 RSRQ-Range-v1250 OPTIONAL, + servCellRSRQ-Type-r12 RSRQ-Type-r12 OPTIONAL, + measResultListEUTRA-v1250 MeasResultList2EUTRA-v1250 OPTIONAL + ]], + [[ inDeviceCoexDetected-r13 ENUMERATED {true} OPTIONAL + ]] +} + +MeasResultListMBSFN-r12 ::= SEQUENCE (SIZE (1..maxMBSFN-Area)) OF MeasResultMBSFN-r12 + +MeasResultMBSFN-r12 ::= SEQUENCE { + mbsfn-Area-r12 SEQUENCE { + mbsfn-AreaId-r12 MBSFN-AreaId-r12, + carrierFreq-r12 ARFCN-ValueEUTRA-r9 + }, + rsrpResultMBSFN-r12 RSRP-Range, + rsrqResultMBSFN-r12 MBSFN-RSRQ-Range-r12, + signallingBLER-Result-r12 BLER-Result-r12 OPTIONAL, + dataBLER-MCH-ResultList-r12 DataBLER-MCH-ResultList-r12 OPTIONAL, + ... +} + +DataBLER-MCH-ResultList-r12 ::= SEQUENCE (SIZE (1.. maxPMCH-PerMBSFN)) OF DataBLER-MCH-Result-r12 + +DataBLER-MCH-Result-r12 ::= SEQUENCE { + mch-Index-r12 INTEGER (1..maxPMCH-PerMBSFN), + dataBLER-Result-r12 BLER-Result-r12 +} + +BLER-Result-r12 ::= SEQUENCE { + bler-r12 BLER-Range-r12, + blocksReceived-r12 SEQUENCE { + n-r12 BIT STRING (SIZE (3)), + m-r12 BIT STRING (SIZE (8)) + } +} + +BLER-Range-r12 ::= INTEGER(0..31) + +MeasResultList2GERAN-r10 ::= SEQUENCE (SIZE (1..maxCellListGERAN)) OF MeasResultListGERAN + +ConnEstFailReport-r11 ::= SEQUENCE { + failedCellId-r11 CellGlobalIdEUTRA, + locationInfo-r11 LocationInfo-r10 OPTIONAL, + measResultFailedCell-r11 SEQUENCE { + rsrpResult-r11 RSRP-Range, + rsrqResult-r11 RSRQ-Range OPTIONAL + }, + measResultNeighCells-r11 SEQUENCE { + measResultListEUTRA-r11 MeasResultList2EUTRA-r9 OPTIONAL, + measResultListUTRA-r11 MeasResultList2UTRA-r9 OPTIONAL, + measResultListGERAN-r11 MeasResultListGERAN OPTIONAL, + measResultsCDMA2000-r11 MeasResultList2CDMA2000-r9 OPTIONAL + } OPTIONAL, + numberOfPreamblesSent-r11 NumberOfPreamblesSent-r11, + contentionDetected-r11 BOOLEAN, + maxTxPowerReached-r11 BOOLEAN, + timeSinceFailure-r11 TimeSinceFailure-r11, + measResultListEUTRA-v1130 MeasResultList2EUTRA-v9e0 OPTIONAL, + ..., + [[ measResultFailedCell-v1250 RSRQ-Range-v1250 OPTIONAL, + failedCellRSRQ-Type-r12 RSRQ-Type-r12 OPTIONAL, + measResultListEUTRA-v1250 MeasResultList2EUTRA-v1250 OPTIONAL + ]] +} + +NumberOfPreamblesSent-r11::= INTEGER (1..200) + +TimeSinceFailure-r11 ::= INTEGER (0..172800) + +MobilityHistoryReport-r12 ::= VisitedCellInfoList-r12 + + +ULHandoverPreparationTransfer ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE { + cdma2000-Type CDMA2000-Type, + meid BIT STRING (SIZE (56)) OPTIONAL, + dedicatedInfo DedicatedInfoCDMA2000, + nonCriticalExtension ULHandoverPreparationTransfer-v8a0-IEs OPTIONAL +} + +ULHandoverPreparationTransfer-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +ULInformationTransfer ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + ulInformationTransfer-r8 ULInformationTransfer-r8-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +ULInformationTransfer-r8-IEs ::= SEQUENCE { + dedicatedInfoType CHOICE { + dedicatedInfoNAS DedicatedInfoNAS, + dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000, + dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000 + }, + nonCriticalExtension ULInformationTransfer-v8a0-IEs OPTIONAL +} + +ULInformationTransfer-v8a0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +WLANConnectionStatusReport-r13 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + wlanConnectionStatusReport-r13 WLANConnectionStatusReport-r13-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +WLANConnectionStatusReport-r13-IEs ::= SEQUENCE { + wlan-Status-r13 WLAN-Status-r13, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SystemInformationBlockType2 ::= SEQUENCE { + ac-BarringInfo SEQUENCE { + ac-BarringForEmergency BOOLEAN, + ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP + ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP + } OPTIONAL, -- Need OP + radioResourceConfigCommon RadioResourceConfigCommonSIB, + ue-TimersAndConstants UE-TimersAndConstants, + freqInfo SEQUENCE { + ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP + ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100} + OPTIONAL, -- Need OP + additionalSpectrumEmission AdditionalSpectrumEmission + }, + mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR + timeAlignmentTimerCommon TimeAlignmentTimer, + ..., + lateNonCriticalExtension OCTET STRING (CONTAINING SystemInformationBlockType2-v8h0-IEs) OPTIONAL, + [[ ssac-BarringForMMTEL-Voice-r9 AC-BarringConfig OPTIONAL, -- Need OP + ssac-BarringForMMTEL-Video-r9 AC-BarringConfig OPTIONAL -- Need OP + ]], + [[ ac-BarringForCSFB-r10 AC-BarringConfig OPTIONAL -- Need OP + ]], + [[ ac-BarringSkipForMMTELVoice-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ac-BarringSkipForMMTELVideo-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ac-BarringSkipForSMS-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ac-BarringPerPLMN-List-r12 AC-BarringPerPLMN-List-r12 OPTIONAL -- Need OP + ]], + [[ voiceServiceCauseIndication-r12 ENUMERATED {true} OPTIONAL -- Need OP + ]], + [[ acdc-BarringForCommon-r13 ACDC-BarringForCommon-r13 OPTIONAL, -- Need OP + acdc-BarringPerPLMN-List-r13 ACDC-BarringPerPLMN-List-r13 OPTIONAL -- Need OP + ]], + [[ + udt-RestrictingForCommon-r13 UDT-Restricting-r13 OPTIONAL, -- Need OR + udt-RestrictingPerPLMN-List-r13 UDT-RestrictingPerPLMN-List-r13 OPTIONAL, -- Need OR + cIoT-EPS-OptimisationInfo-r13 CIOT-EPS-OptimisationInfo-r13 OPTIONAL, -- Need OP + useFullResumeID-r13 ENUMERATED {true} OPTIONAL -- Need OP + ]] + +} + +SystemInformationBlockType2-v8h0-IEs ::= SEQUENCE { + multiBandInfoList SEQUENCE (SIZE (1..maxMultiBands)) OF AdditionalSpectrumEmission OPTIONAL, -- Need OR + nonCriticalExtension SystemInformationBlockType2-v9e0-IEs OPTIONAL +} + +SystemInformationBlockType2-v9e0-IEs ::= SEQUENCE { + ul-CarrierFreq-v9e0 ARFCN-ValueEUTRA-v9e0 OPTIONAL, -- Cond ul-FreqMax + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +AC-BarringConfig ::= SEQUENCE { + ac-BarringFactor ENUMERATED { + p00, p05, p10, p15, p20, p25, p30, p40, + p50, p60, p70, p75, p80, p85, p90, p95}, + ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512}, + ac-BarringForSpecialAC BIT STRING (SIZE(5)) +} + +MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig + +AC-BarringPerPLMN-List-r12 ::= SEQUENCE (SIZE (1.. maxPLMN-r11)) OF AC-BarringPerPLMN-r12 + +AC-BarringPerPLMN-r12 ::= SEQUENCE { + plmn-IdentityIndex-r12 INTEGER (1..maxPLMN-r11), + ac-BarringInfo-r12 SEQUENCE { + ac-BarringForEmergency-r12 BOOLEAN, + ac-BarringForMO-Signalling-r12 AC-BarringConfig OPTIONAL, -- Need OP + ac-BarringForMO-Data-r12 AC-BarringConfig OPTIONAL -- Need OP + } OPTIONAL, -- Need OP + ac-BarringSkipForMMTELVoice-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ac-BarringSkipForMMTELVideo-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ac-BarringSkipForSMS-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ac-BarringForCSFB-r12 AC-BarringConfig OPTIONAL, -- Need OP + ssac-BarringForMMTEL-Voice-r12 AC-BarringConfig OPTIONAL, -- Need OP + ssac-BarringForMMTEL-Video-r12 AC-BarringConfig OPTIONAL -- Need OP +} + +ACDC-BarringForCommon-r13 ::= SEQUENCE { + acdc-HPLMNonly-r13 BOOLEAN, + barringPerACDC-CategoryList-r13 BarringPerACDC-CategoryList-r13 +} + +ACDC-BarringPerPLMN-List-r13 ::= SEQUENCE (SIZE (1.. maxPLMN-r11)) OF ACDC-BarringPerPLMN-r13 + +ACDC-BarringPerPLMN-r13 ::= SEQUENCE { + plmn-IdentityIndex-r13 INTEGER (1..maxPLMN-r11), + acdc-OnlyForHPLMN-r13 BOOLEAN, + barringPerACDC-CategoryList-r13 BarringPerACDC-CategoryList-r13 +} + +BarringPerACDC-CategoryList-r13 ::= SEQUENCE (SIZE (1..maxACDC-Cat-r13)) OF BarringPerACDC-Category-r13 + +BarringPerACDC-Category-r13 ::= SEQUENCE { + acdc-Category-r13 INTEGER (1..maxACDC-Cat-r13), + acdc-BarringConfig-r13 SEQUENCE { + ac-BarringFactor-r13 ENUMERATED { + p00, p05, p10, p15, p20, p25, p30, p40, + p50, p60, p70, p75, p80, p85, p90, p95}, + ac-BarringTime-r13 ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512} + } OPTIONAL -- Need OP +} + +UDT-Restricting-r13 ::= SEQUENCE { + udt-Restricting-r13 ENUMERATED {true} OPTIONAL, --Need OR + udt-RestrictingTime-r13 ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512} OPTIONAL --Need OR +} + +UDT-RestrictingPerPLMN-List-r13 ::= SEQUENCE (SIZE (1..maxPLMN-r11)) OF UDT-RestrictingPerPLMN-r13 + +UDT-RestrictingPerPLMN-r13 ::= SEQUENCE { + plmn-IdentityIndex-r13 INTEGER (1..maxPLMN-r11), + udt-Restricting-r13 UDT-Restricting-r13 OPTIONAL --Need OR +} + +CIOT-EPS-OptimisationInfo-r13 ::= SEQUENCE (SIZE (1.. maxPLMN-r11)) OF CIOT-OptimisationPLMN-r13 + +CIOT-OptimisationPLMN-r13::= SEQUENCE { + up-CIoT-EPS-Optimisation-r13 ENUMERATED {true} OPTIONAL, -- Need OP + cp-CIoT-EPS-Optimisation-r13 ENUMERATED {true} OPTIONAL, -- Need OP + attachWithoutPDN-Connectivity-r13 ENUMERATED {true} OPTIONAL -- Need OP +} + + +SystemInformationBlockType3 ::= SEQUENCE { + cellReselectionInfoCommon SEQUENCE { + q-Hyst ENUMERATED { + dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10, + dB12, dB14, dB16, dB18, dB20, dB22, dB24}, + speedStateReselectionPars SEQUENCE { + mobilityStateParameters MobilityStateParameters, + q-HystSF SEQUENCE { + sf-Medium ENUMERATED { + dB-6, dB-4, dB-2, dB0}, + sf-High ENUMERATED { + dB-6, dB-4, dB-2, dB0} + } + } OPTIONAL -- Need OP + }, + cellReselectionServingFreqInfo SEQUENCE { + s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP + threshServingLow ReselectionThreshold, + cellReselectionPriority CellReselectionPriority + }, + intraFreqCellReselectionInfo SEQUENCE { + q-RxLevMin Q-RxLevMin, + p-Max P-Max OPTIONAL, -- Need OP + s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP + allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP + presenceAntennaPort1 PresenceAntennaPort1, + neighCellConfig NeighCellConfig, + t-ReselectionEUTRA T-Reselection, + t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP + }, + ..., + lateNonCriticalExtension OCTET STRING (CONTAINING SystemInformationBlockType3-v10j0-IEs) OPTIONAL, + [[ s-IntraSearch-v920 SEQUENCE { + s-IntraSearchP-r9 ReselectionThreshold, + s-IntraSearchQ-r9 ReselectionThresholdQ-r9 + } OPTIONAL, -- Need OP + s-NonIntraSearch-v920 SEQUENCE { + s-NonIntraSearchP-r9 ReselectionThreshold, + s-NonIntraSearchQ-r9 ReselectionThresholdQ-r9 + } OPTIONAL, -- Need OP + q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP + threshServingLowQ-r9 ReselectionThresholdQ-r9 OPTIONAL -- Need OP + ]], + [[ q-QualMinWB-r11 Q-QualMin-r9 OPTIONAL -- Cond WB-RSRQ + ]], + [[ q-QualMinRSRQ-OnAllSymbols-r12 Q-QualMin-r9 OPTIONAL -- Cond RSRQ + ]], + [[ cellReselectionServingFreqInfo-v1310 CellReselectionServingFreqInfo-v1310 OPTIONAL, -- Need OP + redistributionServingInfo-r13 RedistributionServingInfo-r13 OPTIONAL, --Need OR + cellSelectionInfoCE-r13 CellSelectionInfoCE-r13 OPTIONAL, -- Need OP + t-ReselectionEUTRA-CE-r13 T-ReselectionEUTRA-CE-r13 OPTIONAL -- Need OP + ]] +} + +RedistributionServingInfo-r13 ::= SEQUENCE { + redistributionFactorServing-r13 INTEGER(0..10), + redistributionFactorCell-r13 ENUMERATED{true} OPTIONAL, --Need OP + t360-r13 ENUMERATED {min4, min8, min16, min32,infinity, + spare3,spare2,spare1}, + redistrOnPagingOnly-r13 ENUMERATED {true} OPTIONAL --Need OP +} + +CellReselectionServingFreqInfo-v1310 ::= SEQUENCE { + cellReselectionSubPriority-r13 CellReselectionSubPriority-r13 +} + +-- Late non critical extensions +SystemInformationBlockType3-v10j0-IEs ::= SEQUENCE { + freqBandInfo-r10 NS-PmaxList-r10 OPTIONAL, -- Need OR + multiBandInfoList-v10j0 MultiBandInfoList-v10j0 OPTIONAL, -- Need OR + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SystemInformationBlockType4 ::= SEQUENCE { + intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR + intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR + csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG + ..., + lateNonCriticalExtension OCTET STRING OPTIONAL +} + +IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo + +IntraFreqNeighCellInfo ::= SEQUENCE { + physCellId PhysCellId, + q-OffsetCell Q-OffsetRange, + ... +} + +IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange + + +SystemInformationBlockType5 ::= SEQUENCE { + interFreqCarrierFreqList InterFreqCarrierFreqList, + ..., + lateNonCriticalExtension OCTET STRING (CONTAINING SystemInformationBlockType5-v8h0-IEs) OPTIONAL, + [[ interFreqCarrierFreqList-v1250 InterFreqCarrierFreqList-v1250 OPTIONAL, -- Need OR + interFreqCarrierFreqListExt-r12 InterFreqCarrierFreqListExt-r12 OPTIONAL -- Need OR + ]], + [[ interFreqCarrierFreqListExt-v1280 InterFreqCarrierFreqListExt-v1280 OPTIONAL -- Need OR + ]], + [[ interFreqCarrierFreqList-v1310 InterFreqCarrierFreqList-v1310 OPTIONAL, -- Need OR + interFreqCarrierFreqListExt-v1310 InterFreqCarrierFreqListExt-v1310 OPTIONAL -- Need OR + ]] +} + +SystemInformationBlockType5-v8h0-IEs ::= SEQUENCE { + interFreqCarrierFreqList-v8h0 SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo-v8h0 OPTIONAL, -- Need OP + nonCriticalExtension SystemInformationBlockType5-v9e0-IEs OPTIONAL +} + +SystemInformationBlockType5-v9e0-IEs ::= SEQUENCE { + interFreqCarrierFreqList-v9e0 SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo-v9e0 OPTIONAL, -- Need OR + nonCriticalExtension SystemInformationBlockType5-v10j0-IEs OPTIONAL +} + +SystemInformationBlockType5-v10j0-IEs ::= SEQUENCE { + interFreqCarrierFreqList-v10j0 SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo-v10j0 OPTIONAL, -- Need OR + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo + +InterFreqCarrierFreqList-v1250 ::= SEQUENCE (SIZE (1.. maxFreq)) OF InterFreqCarrierFreqInfo-v1250 + +InterFreqCarrierFreqListExt-r12 ::= SEQUENCE (SIZE (1.. maxFreq)) OF InterFreqCarrierFreqInfo-r12 + +InterFreqCarrierFreqListExt-v1280 ::= SEQUENCE (SIZE (1.. maxFreq)) OF InterFreqCarrierFreqInfo-v10j0 + +InterFreqCarrierFreqList-v1310 ::= SEQUENCE (SIZE (1.. maxFreq)) OF InterFreqCarrierFreqInfo-v1310 + +InterFreqCarrierFreqListExt-v1310 ::= SEQUENCE (SIZE (1.. maxFreq)) OF InterFreqCarrierFreqInfo-v1310 + +InterFreqCarrierFreqInfo ::= SEQUENCE { + dl-CarrierFreq ARFCN-ValueEUTRA, + q-RxLevMin Q-RxLevMin, + p-Max P-Max OPTIONAL, -- Need OP + t-ReselectionEUTRA T-Reselection, + t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP + threshX-High ReselectionThreshold, + threshX-Low ReselectionThreshold, + allowedMeasBandwidth AllowedMeasBandwidth, + presenceAntennaPort1 PresenceAntennaPort1, + cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP + neighCellConfig NeighCellConfig, + q-OffsetFreq Q-OffsetRange DEFAULT dB0, + interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR + interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR + ..., + [[ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP + threshX-Q-r9 SEQUENCE { + threshX-HighQ-r9 ReselectionThresholdQ-r9, + threshX-LowQ-r9 ReselectionThresholdQ-r9 + } OPTIONAL -- Cond RSRQ + ]], + [[ q-QualMinWB-r11 Q-QualMin-r9 OPTIONAL -- Cond WB-RSRQ + ]] +} + +InterFreqCarrierFreqInfo-v8h0 ::= SEQUENCE { + multiBandInfoList MultiBandInfoList OPTIONAL -- Need OR +} + +InterFreqCarrierFreqInfo-v9e0 ::= SEQUENCE { + dl-CarrierFreq-v9e0 ARFCN-ValueEUTRA-v9e0 OPTIONAL, -- Cond dl-FreqMax + multiBandInfoList-v9e0 MultiBandInfoList-v9e0 OPTIONAL -- Need OR +} + +InterFreqCarrierFreqInfo-v10j0 ::= SEQUENCE { + freqBandInfo-r10 NS-PmaxList-r10 OPTIONAL, -- Need OR + multiBandInfoList-v10j0 MultiBandInfoList-v10j0 OPTIONAL -- Need OR +} + +InterFreqCarrierFreqInfo-v1250 ::= SEQUENCE { + reducedMeasPerformance-r12 ENUMERATED {true} OPTIONAL, -- Need OP + q-QualMinRSRQ-OnAllSymbols-r12 Q-QualMin-r9 OPTIONAL -- Cond RSRQ2 +} + +InterFreqCarrierFreqInfo-r12 ::= SEQUENCE { + dl-CarrierFreq-r12 ARFCN-ValueEUTRA-r9, + q-RxLevMin-r12 Q-RxLevMin, + p-Max-r12 P-Max OPTIONAL, -- Need OP + t-ReselectionEUTRA-r12 T-Reselection, + t-ReselectionEUTRA-SF-r12 SpeedStateScaleFactors OPTIONAL, -- Need OP + threshX-High-r12 ReselectionThreshold, + threshX-Low-r12 ReselectionThreshold, + allowedMeasBandwidth-r12 AllowedMeasBandwidth, + presenceAntennaPort1-r12 PresenceAntennaPort1, + cellReselectionPriority-r12 CellReselectionPriority OPTIONAL, -- Need OP + neighCellConfig-r12 NeighCellConfig, + q-OffsetFreq-r12 Q-OffsetRange DEFAULT dB0, + interFreqNeighCellList-r12 InterFreqNeighCellList OPTIONAL, -- Need OR + interFreqBlackCellList-r12 InterFreqBlackCellList OPTIONAL, -- Need OR + q-QualMin-r12 Q-QualMin-r9 OPTIONAL, -- Need OP + threshX-Q-r12 SEQUENCE { + threshX-HighQ-r12 ReselectionThresholdQ-r9, + threshX-LowQ-r12 ReselectionThresholdQ-r9 + } OPTIONAL, -- Cond RSRQ + q-QualMinWB-r12 Q-QualMin-r9 OPTIONAL, -- Cond WB-RSRQ + multiBandInfoList-r12 MultiBandInfoList-r11 OPTIONAL, -- Need OR + reducedMeasPerformance-r12 ENUMERATED {true} OPTIONAL, -- Need OP + q-QualMinRSRQ-OnAllSymbols-r12 Q-QualMin-r9 OPTIONAL, -- Cond RSRQ2 +... +} + +InterFreqCarrierFreqInfo-v1310 ::= SEQUENCE { + cellReselectionSubPriority-r13 CellReselectionSubPriority-r13 OPTIONAL, -- Need OP + redistributionInterFreqInfo-r13 RedistributionInterFreqInfo-r13 OPTIONAL, --Need OP + cellSelectionInfoCE-r13 CellSelectionInfoCE-r13 OPTIONAL, -- Need OP + t-ReselectionEUTRA-CE-r13 T-ReselectionEUTRA-CE-r13 OPTIONAL -- Need OP +} + +InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo + +InterFreqNeighCellInfo ::= SEQUENCE { + physCellId PhysCellId, + q-OffsetCell Q-OffsetRange +} + +InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange + +RedistributionInterFreqInfo-r13 ::= SEQUENCE { + redistributionFactorFreq-r13 RedistributionFactor-r13 OPTIONAL, --Need OP + redistributionNeighCellList-r13 RedistributionNeighCellList-r13 OPTIONAL --Need OP +} + +RedistributionNeighCellList-r13 ::= SEQUENCE (SIZE (1..maxCellInter)) OF RedistributionNeighCell-r13 + +RedistributionNeighCell-r13 ::= SEQUENCE { + physCellId-r13 PhysCellId, + redistributionFactorCell-r13 RedistributionFactor-r13 +} + +RedistributionFactor-r13 ::= INTEGER(1..10) + + +SystemInformationBlockType6 ::= SEQUENCE { + carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR + carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR + t-ReselectionUTRA T-Reselection, + t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP + ..., + lateNonCriticalExtension OCTET STRING (CONTAINING SystemInformationBlockType6-v8h0-IEs) OPTIONAL, + [[ carrierFreqListUTRA-FDD-v1250 SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF + CarrierFreqInfoUTRA-v1250 OPTIONAL, -- Cond UTRA-FDD + carrierFreqListUTRA-TDD-v1250 SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF + CarrierFreqInfoUTRA-v1250 OPTIONAL, -- Cond UTRA-TDD + carrierFreqListUTRA-FDD-Ext-r12 CarrierFreqListUTRA-FDD-Ext-r12 OPTIONAL, -- Cond UTRA-FDD + carrierFreqListUTRA-TDD-Ext-r12 CarrierFreqListUTRA-TDD-Ext-r12 OPTIONAL -- Cond UTRA-TDD + ]] +} + +SystemInformationBlockType6-v8h0-IEs ::= SEQUENCE { + carrierFreqListUTRA-FDD-v8h0 SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqInfoUTRA-FDD-v8h0 OPTIONAL, -- Cond UTRA-FDD + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +CarrierFreqInfoUTRA-v1250 ::= SEQUENCE { + reducedMeasPerformance-r12 ENUMERATED {true} OPTIONAL -- Need OP +} + +CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD + +CarrierFreqUTRA-FDD ::= SEQUENCE { + carrierFreq ARFCN-ValueUTRA, + cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP + threshX-High ReselectionThreshold, + threshX-Low ReselectionThreshold, + q-RxLevMin INTEGER (-60..-13), + p-MaxUTRA INTEGER (-50..33), + q-QualMin INTEGER (-24..0), + ..., + [[ threshX-Q-r9 SEQUENCE { + threshX-HighQ-r9 ReselectionThresholdQ-r9, + threshX-LowQ-r9 ReselectionThresholdQ-r9 + } OPTIONAL -- Cond RSRQ + ]] +} + +CarrierFreqInfoUTRA-FDD-v8h0 ::= SEQUENCE { + multiBandInfoList SEQUENCE (SIZE (1..maxMultiBands)) OF FreqBandIndicator-UTRA-FDD OPTIONAL -- Need OR +} + +CarrierFreqListUTRA-FDD-Ext-r12 ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF + CarrierFreqUTRA-FDD-Ext-r12 + +CarrierFreqUTRA-FDD-Ext-r12 ::= SEQUENCE { + carrierFreq-r12 ARFCN-ValueUTRA, + cellReselectionPriority-r12 CellReselectionPriority OPTIONAL, -- Need OP + threshX-High-r12 ReselectionThreshold, + threshX-Low-r12 ReselectionThreshold, + q-RxLevMin-r12 INTEGER (-60..-13), + p-MaxUTRA-r12 INTEGER (-50..33), + q-QualMin-r12 INTEGER (-24..0), + threshX-Q-r12 SEQUENCE { + threshX-HighQ-r12 ReselectionThresholdQ-r9, + threshX-LowQ-r12 ReselectionThresholdQ-r9 + } OPTIONAL, -- Cond RSRQ + multiBandInfoList-r12 SEQUENCE (SIZE (1..maxMultiBands)) OF FreqBandIndicator-UTRA-FDD OPTIONAL, -- Need OR + reducedMeasPerformance-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ... +} + +CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD + +CarrierFreqUTRA-TDD ::= SEQUENCE { + carrierFreq ARFCN-ValueUTRA, + cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP + threshX-High ReselectionThreshold, + threshX-Low ReselectionThreshold, + q-RxLevMin INTEGER (-60..-13), + p-MaxUTRA INTEGER (-50..33), + ... +} + +CarrierFreqListUTRA-TDD-Ext-r12 ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF + CarrierFreqUTRA-TDD-r12 + +CarrierFreqUTRA-TDD-r12 ::= SEQUENCE { + carrierFreq-r12 ARFCN-ValueUTRA, + cellReselectionPriority-r12 CellReselectionPriority OPTIONAL, -- Need OP + threshX-High-r12 ReselectionThreshold, + threshX-Low-r12 ReselectionThreshold, + q-RxLevMin-r12 INTEGER (-60..-13), + p-MaxUTRA-r12 INTEGER (-50..33), + reducedMeasPerformance-r12 ENUMERATED {true} OPTIONAL, -- Need OP + ... +} + +FreqBandIndicator-UTRA-FDD ::= INTEGER (1..86) + + +SystemInformationBlockType7 ::= SEQUENCE { + t-ReselectionGERAN T-Reselection, + t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR + carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR + ..., + lateNonCriticalExtension OCTET STRING OPTIONAL +} + +CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN + +CarrierFreqsInfoGERAN ::= SEQUENCE { + carrierFreqs CarrierFreqsGERAN, + commonInfo SEQUENCE { + cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP + ncc-Permitted BIT STRING (SIZE (8)), + q-RxLevMin INTEGER (0..45), + p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP + threshX-High ReselectionThreshold, + threshX-Low ReselectionThreshold + }, + ... +} + + +SystemInformationBlockType8 ::= SEQUENCE { + systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR + searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR + parametersHRPD SEQUENCE { + preRegistrationInfoHRPD PreRegistrationInfoHRPD, + cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + parameters1XRTT SEQUENCE { + csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP + longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR + cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + ..., + lateNonCriticalExtension OCTET STRING OPTIONAL, + [[ csfb-SupportForDualRxUEs-r9 BOOLEAN OPTIONAL, -- Need OR + cellReselectionParametersHRPD-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-HRPD + cellReselectionParameters1XRTT-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-1XRTT + csfb-RegistrationParam1XRTT-v920 CSFB-RegistrationParam1XRTT-v920 OPTIONAL, -- Cond REG-1XRTT + ac-BarringConfig1XRTT-r9 AC-BarringConfig1XRTT-r9 OPTIONAL -- Cond REG-1XRTT + ]], + [[ csfb-DualRxTxSupport-r10 ENUMERATED {true} OPTIONAL -- Cond REG-1XRTT + ]], + [[ sib8-PerPLMN-List-r11 SIB8-PerPLMN-List-r11 OPTIONAL -- Need OR + ]] +} + +CellReselectionParametersCDMA2000 ::= SEQUENCE { + bandClassList BandClassListCDMA2000, + neighCellList NeighCellListCDMA2000, + t-ReselectionCDMA2000 T-Reselection, + t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP +} + +CellReselectionParametersCDMA2000-r11 ::= SEQUENCE { + bandClassList BandClassListCDMA2000, + neighCellList-r11 SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-r11, + t-ReselectionCDMA2000 T-Reselection, + t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP +} + +CellReselectionParametersCDMA2000-v920 ::= SEQUENCE { + neighCellList-v920 NeighCellListCDMA2000-v920 +} + +NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000 + +NeighCellCDMA2000 ::= SEQUENCE { + bandClass BandclassCDMA2000, + neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000 +} + +NeighCellCDMA2000-r11 ::= SEQUENCE { + bandClass BandclassCDMA2000, + neighFreqInfoList-r11 SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000-r11 +} + +NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000 + +NeighCellsPerBandclassCDMA2000 ::= SEQUENCE { + arfcn ARFCN-ValueCDMA2000, + physCellIdList PhysCellIdListCDMA2000 +} + +NeighCellsPerBandclassCDMA2000-r11 ::= SEQUENCE { + arfcn ARFCN-ValueCDMA2000, + physCellIdList-r11 SEQUENCE (SIZE (1..40)) OF PhysCellIdCDMA2000 +} + +NeighCellListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-v920 + +NeighCellCDMA2000-v920 ::= SEQUENCE { + neighCellsPerFreqList-v920 NeighCellsPerBandclassListCDMA2000-v920 +} + +NeighCellsPerBandclassListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000-v920 + +NeighCellsPerBandclassCDMA2000-v920 ::= SEQUENCE { + physCellIdList-v920 PhysCellIdListCDMA2000-v920 +} + +PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000 + +PhysCellIdListCDMA2000-v920 ::= SEQUENCE (SIZE (0..24)) OF PhysCellIdCDMA2000 + +BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000 + +BandClassInfoCDMA2000 ::= SEQUENCE { + bandClass BandclassCDMA2000, + cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP + threshX-High INTEGER (0..63), + threshX-Low INTEGER (0..63), + ... +} + +AC-BarringConfig1XRTT-r9 ::= SEQUENCE { + ac-Barring0to9-r9 INTEGER (0..63), + ac-Barring10-r9 INTEGER (0..7), + ac-Barring11-r9 INTEGER (0..7), + ac-Barring12-r9 INTEGER (0..7), + ac-Barring13-r9 INTEGER (0..7), + ac-Barring14-r9 INTEGER (0..7), + ac-Barring15-r9 INTEGER (0..7), + ac-BarringMsg-r9 INTEGER (0..7), + ac-BarringReg-r9 INTEGER (0..7), + ac-BarringEmg-r9 INTEGER (0..7) +} + +SIB8-PerPLMN-List-r11 ::= SEQUENCE (SIZE (1..maxPLMN-r11)) OF SIB8-PerPLMN-r11 + +SIB8-PerPLMN-r11 ::= SEQUENCE { + plmn-Identity-r11 INTEGER (1..maxPLMN-r11), + parametersCDMA2000-r11 CHOICE { + explicitValue ParametersCDMA2000-r11, + defaultValue NULL + } +} + +ParametersCDMA2000-r11 ::= SEQUENCE { + systemTimeInfo-r11 CHOICE { + explicitValue SystemTimeInfoCDMA2000, + defaultValue NULL + } OPTIONAL, -- Need OR + searchWindowSize-r11 INTEGER (0..15), + parametersHRPD-r11 SEQUENCE { + preRegistrationInfoHRPD-r11 PreRegistrationInfoHRPD, + cellReselectionParametersHRPD-r11 CellReselectionParametersCDMA2000-r11 OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + parameters1XRTT-r11 SEQUENCE { + csfb-RegistrationParam1XRTT-r11 CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP + csfb-RegistrationParam1XRTT-Ext-r11 CSFB-RegistrationParam1XRTT-v920 OPTIONAL, -- Cond REG-1XRTT-PerPLMN + longCodeState1XRTT-r11 BIT STRING (SIZE (42)) OPTIONAL, -- Cond PerPLMN-LC + cellReselectionParameters1XRTT-r11 CellReselectionParametersCDMA2000-r11 OPTIONAL, -- Need OR + ac-BarringConfig1XRTT-r11 AC-BarringConfig1XRTT-r9 OPTIONAL, -- Cond REG-1XRTT-PerPLMN + csfb-SupportForDualRxUEs-r11 BOOLEAN OPTIONAL, -- Need OR + csfb-DualRxTxSupport-r11 ENUMERATED {true} OPTIONAL -- Cond REG-1XRTT-PerPLMN + } OPTIONAL, -- Need OR + ... +} + + +SystemInformationBlockType9 ::= SEQUENCE { + hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR + ..., + lateNonCriticalExtension OCTET STRING OPTIONAL +} + + +SystemInformationBlockType10 ::= SEQUENCE { + messageIdentifier BIT STRING (SIZE (16)), + serialNumber BIT STRING (SIZE (16)), + warningType OCTET STRING (SIZE (2)), + dummy OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP + ..., + lateNonCriticalExtension OCTET STRING OPTIONAL +} + + +SystemInformationBlockType11 ::= SEQUENCE { + messageIdentifier BIT STRING (SIZE (16)), + serialNumber BIT STRING (SIZE (16)), + warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment}, + warningMessageSegmentNumber INTEGER (0..63), + warningMessageSegment OCTET STRING, + dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1 + ..., + lateNonCriticalExtension OCTET STRING OPTIONAL +} + + +SystemInformationBlockType12-r9 ::= SEQUENCE { + messageIdentifier-r9 BIT STRING (SIZE (16)), + serialNumber-r9 BIT STRING (SIZE (16)), + warningMessageSegmentType-r9 ENUMERATED {notLastSegment, lastSegment}, + warningMessageSegmentNumber-r9 INTEGER (0..63), + warningMessageSegment-r9 OCTET STRING, + dataCodingScheme-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1 + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + +SystemInformationBlockType13-r9 ::= SEQUENCE { + mbsfn-AreaInfoList-r9 MBSFN-AreaInfoList-r9, + notificationConfig-r9 MBMS-NotificationConfig-r9, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + +SystemInformationBlockType14-r11 ::= SEQUENCE { + eab-Param-r11 CHOICE { + eab-Common-r11 EAB-Config-r11, + eab-PerPLMN-List-r11 SEQUENCE (SIZE (1..maxPLMN-r11)) OF EAB-ConfigPLMN-r11 + } OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +EAB-ConfigPLMN-r11 ::= SEQUENCE { + eab-Config-r11 EAB-Config-r11 OPTIONAL -- Need OR +} + +EAB-Config-r11 ::= SEQUENCE { + eab-Category-r11 ENUMERATED {a, b, c}, + eab-BarringBitmap-r11 BIT STRING (SIZE (10)) +} + + +SystemInformationBlockType15-r11 ::= SEQUENCE { + mbms-SAI-IntraFreq-r11 MBMS-SAI-List-r11 OPTIONAL, -- Need OR + mbms-SAI-InterFreqList-r11 MBMS-SAI-InterFreqList-r11 OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ..., + [[ mbms-SAI-InterFreqList-v1140 MBMS-SAI-InterFreqList-v1140 OPTIONAL -- Cond InterFreq + ]] +} + +MBMS-SAI-List-r11 ::= SEQUENCE (SIZE (1..maxSAI-MBMS-r11)) OF MBMS-SAI-r11 + +MBMS-SAI-r11 ::= INTEGER (0..65535) + +MBMS-SAI-InterFreqList-r11 ::= SEQUENCE (SIZE (1..maxFreq)) OF MBMS-SAI-InterFreq-r11 + +MBMS-SAI-InterFreqList-v1140 ::= SEQUENCE (SIZE (1..maxFreq)) OF MBMS-SAI-InterFreq-v1140 + +MBMS-SAI-InterFreq-r11 ::= SEQUENCE { + dl-CarrierFreq-r11 ARFCN-ValueEUTRA-r9, + mbms-SAI-List-r11 MBMS-SAI-List-r11 +} + +MBMS-SAI-InterFreq-v1140 ::= SEQUENCE { + multiBandInfoList-r11 MultiBandInfoList-r11 OPTIONAL -- Need OR +} + + + +SystemInformationBlockType16-r11 ::= SEQUENCE { + timeInfo-r11 SEQUENCE { + timeInfoUTC-r11 INTEGER (0..549755813887), + dayLightSavingTime-r11 BIT STRING (SIZE (2)) OPTIONAL, -- Need OR + leapSeconds-r11 INTEGER (-127..128) OPTIONAL, -- Need OR + localTimeOffset-r11 INTEGER (-63..64) OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + +SystemInformationBlockType17-r12 ::= SEQUENCE { + wlan-OffloadInfoPerPLMN-List-r12 SEQUENCE (SIZE (1..maxPLMN-r11)) OF + WLAN-OffloadInfoPerPLMN-r12 OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +WLAN-OffloadInfoPerPLMN-r12 ::= SEQUENCE { + wlan-OffloadConfigCommon-r12 WLAN-OffloadConfig-r12 OPTIONAL, -- Need OR + wlan-Id-List-r12 WLAN-Id-List-r12 OPTIONAL, -- Need OR + ... +} + +WLAN-Id-List-r12 ::= SEQUENCE (SIZE (1..maxWLAN-Id-r12)) OF WLAN-Identifiers-r12 + +WLAN-Identifiers-r12 ::= SEQUENCE { + ssid-r12 OCTET STRING (SIZE (1..32)) OPTIONAL, -- Need OR + bssid-r12 OCTET STRING (SIZE (6)) OPTIONAL, -- Need OR + hessid-r12 OCTET STRING (SIZE (6)) OPTIONAL, -- Need OR + ... +} + + +SystemInformationBlockType18-r12 ::= SEQUENCE { + commConfig-r12 SEQUENCE { + commRxPool-r12 SL-CommRxPoolList-r12, + commTxPoolNormalCommon-r12 SL-CommTxPoolList-r12 OPTIONAL, -- Need OR + commTxPoolExceptional-r12 SL-CommTxPoolList-r12 OPTIONAL, -- Need OR + commSyncConfig-r12 SL-SyncConfigList-r12 OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ..., + [[ commTxPoolNormalCommonExt-r13 SL-CommTxPoolListExt-r13 OPTIONAL, -- Need OR + commTxResourceUC-ReqAllowed-r13 ENUMERATED {true} OPTIONAL, -- Need OR + commTxAllowRelayCommon-r13 ENUMERATED {true} OPTIONAL -- Need OR + ]] +} + + +SystemInformationBlockType19-r12 ::= SEQUENCE { + discConfig-r12 SEQUENCE { + discRxPool-r12 SL-DiscRxPoolList-r12, + discTxPoolCommon-r12 SL-DiscTxPoolList-r12 OPTIONAL, -- Need OR + discTxPowerInfo-r12 SL-DiscTxPowerInfoList-r12 OPTIONAL, -- Cond Tx + discSyncConfig-r12 SL-SyncConfigList-r12 OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + discInterFreqList-r12 SL-CarrierFreqInfoList-r12 OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ..., + [[ discConfig-v1310 SEQUENCE { + discInterFreqList-v1310 SL-CarrierFreqInfoList-v1310 OPTIONAL, -- Need OR + gapRequestsAllowedCommon ENUMERATED {true} OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + discConfigRelay-r13 SEQUENCE { + relayUE-Config-r13 SL-DiscConfigRelayUE-r13, + remoteUE-Config-r13 SL-DiscConfigRemoteUE-r13 + } OPTIONAL, -- Need OR + discConfigPS-13 SEQUENCE { + discRxPoolPS-r13 SL-DiscRxPoolList-r12, + discTxPoolPS-Common-r13 SL-DiscTxPoolList-r12 OPTIONAL -- Need OR + } OPTIONAL -- Need OR + ]] +} + +SL-CarrierFreqInfoList-r12 ::= SEQUENCE (SIZE (1..maxFreq)) OF SL-CarrierFreqInfo-r12 + +SL-CarrierFreqInfoList-v1310 ::= SEQUENCE (SIZE (1..maxFreq)) OF SL-CarrierFreqInfo-v1310 + +SL-CarrierFreqInfo-r12::= SEQUENCE { + carrierFreq-r12 ARFCN-ValueEUTRA-r9, + plmn-IdentityList-r12 PLMN-IdentityList4-r12 OPTIONAL -- Need OP +} + +SL-DiscConfigRelayUE-r13 ::= SEQUENCE { + threshHigh-r13 RSRP-RangeSL4-r13 OPTIONAL, -- Need OR + threshLow-r13 RSRP-RangeSL4-r13 OPTIONAL, -- Need OR + hystMax-r13 ENUMERATED {dB0, dB3, dB6, dB9, dB12, dBinf} OPTIONAL, -- Cond ThreshHigh + hystMin-r13 ENUMERATED {dB0, dB3, dB6, dB9, dB12} OPTIONAL -- Cond ThreshLow +} + +SL-DiscConfigRemoteUE-r13 ::= SEQUENCE { + threshHigh-r13 RSRP-RangeSL4-r13 OPTIONAL, -- Need OR + hystMax-r13 ENUMERATED {dB0, dB3, dB6, dB9, dB12} OPTIONAL, -- Cond ThreshHigh + reselectionInfoIC-r13 ReselectionInfoRelay-r13 +} + +ReselectionInfoRelay-r13 ::= SEQUENCE { + q-RxLevMin-r13 Q-RxLevMin, + -- Note that the mapping of invidual values may be different for PC5, but the granularity/ + -- number of values is same as for Uu + filterCoefficient-r13 FilterCoefficient, + minHyst-r13 ENUMERATED {dB0, dB3, + dB6, dB9, dB12, dBinf} OPTIONAL -- Need OR +} + +SL-CarrierFreqInfo-v1310::= SEQUENCE { + discResourcesNonPS-r13 SL-ResourcesInterFreq-r13 OPTIONAL, -- Need OR + discResourcesPS-r13 SL-ResourcesInterFreq-r13 OPTIONAL, -- Need OR + discConfigOther-r13 SL-DiscConfigOtherInterFreq-r13 OPTIONAL, -- Need OR + ... +} + +PLMN-IdentityList4-r12 ::= SEQUENCE (SIZE (1..maxPLMN-r11)) OF PLMN-IdentityInfo2-r12 + +PLMN-IdentityInfo2-r12 ::= CHOICE { + plmn-Index-r12 INTEGER (1..maxPLMN-r11), + plmnIdentity-r12 PLMN-Identity +} + +SL-DiscTxResourcesInterFreq-r13 ::= CHOICE { + acquireSI-FromCarrier-r13 NULL, + discTxPoolCommon-r13 SL-DiscTxPoolList-r12, + requestDedicated-r13 NULL, + noTxOnCarrier-r13 NULL +} + +SL-DiscConfigOtherInterFreq-r13::= SEQUENCE { + txPowerInfo-r13 SL-DiscTxPowerInfoList-r12 OPTIONAL, -- Cond Tx + refCarrierCommon-r13 ENUMERATED {pCell} OPTIONAL, -- Need OR + discSyncConfig-r13 SL-SyncConfigListNFreq-r13 OPTIONAL, -- Need OR + discCellSelectionInfo-r13 CellSelectionInfoNFreq-r13 OPTIONAL -- Need OR +} + +SL-ResourcesInterFreq-r13 ::= SEQUENCE { + discRxResourcesInterFreq-r13 SL-DiscRxPoolList-r12 OPTIONAL, -- Need OR + discTxResourcesInterFreq-r13 SL-DiscTxResourcesInterFreq-r13 OPTIONAL -- Need OR +} + + +SystemInformationBlockType20-r13 ::= SEQUENCE { + sc-mcch-RepetionPeriod-r13 ENUMERATED {rf2, rf4, rf8, rf16, rf32, rf64, rf128, rf256}, + sc-mcch-Offset-r13 INTEGER (0..10), + sc-mcch-FirstSubframe-r13 INTEGER (0..9), + sc-mcch-duration-r13 INTEGER (2..9) OPTIONAL, + sc-mcch-ModificationPeriod-r13 ENUMERATED {rf2, rf4, rf8, rf16, rf32, rf64, rf128, rf256, + rf512, rf1024, r2048, rf4096, rf8192, rf16384, rf32768, rf65536}, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + +SystemInformationBlockType21-r14 ::= SEQUENCE { + sl-V2X-ConfigCommon-r14 SL-V2X-ConfigCommon-r14 OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +SL-V2X-ConfigCommon-r14 ::= SEQUENCE { + v2x-CommRxPool-r14 SL-CommRxPoolListV2X-r14 OPTIONAL, -- Need OR + v2x-CommTxPoolNormalCommon-r14 SL-CommTxPoolListV2X-r14 OPTIONAL, -- Need OR + v2x-CommTxPoolExceptional-r14 SL-CommResourcePoolV2X-r14 OPTIONAL, -- Need OR + v2x-SyncConfig-r14 SL-SyncConfigListV2X-r14 OPTIONAL, -- Need OR + v2x-InterFreqInfoList-r14 SL-InterFreqInfoListV2X-r14 OPTIONAL, -- Need OR + v2x-ResourceSelectionConfig-r14 SL-CommTxPoolSensingConfig-r14 OPTIONAL, -- Need OR + zoneConfig-r14 SL-ZoneConfig-r14 OPTIONAL -- Need OR +} + +SL-CommTxPoolSensingConfig-r14 ::= SEQUENCE { + pssch-TxConfigList-r14 SL-PSSCH-TxConfigList-r14, + thresPSSCH-RSRP-List-r14 SL-ThresPSSCH-RSRP-List-r14, + restrictResourceReservationPeriodList-r14 SL-RestrictResourceReservationPeriodList-r14 OPTIONAL, -- Need OR + probResourceKeep-r14 ENUMERATED {v0, v0dot2, v0dot4, v0dot6, v0dot8, + spare3,spare2, spare1} +} + +AntennaInfoCommon ::= SEQUENCE { + antennaPortsCount ENUMERATED {an1, an2, an4, spare1} +} + +AntennaInfoDedicated ::= SEQUENCE { + transmissionMode ENUMERATED { + tm1, tm2, tm3, tm4, tm5, tm6, + tm7, tm8-v920}, + codebookSubsetRestriction CHOICE { + n2TxAntenna-tm3 BIT STRING (SIZE (2)), + n4TxAntenna-tm3 BIT STRING (SIZE (4)), + n2TxAntenna-tm4 BIT STRING (SIZE (6)), + n4TxAntenna-tm4 BIT STRING (SIZE (64)), + n2TxAntenna-tm5 BIT STRING (SIZE (4)), + n4TxAntenna-tm5 BIT STRING (SIZE (16)), + n2TxAntenna-tm6 BIT STRING (SIZE (4)), + n4TxAntenna-tm6 BIT STRING (SIZE (16)) + } OPTIONAL, -- Cond TM + ue-TransmitAntennaSelection CHOICE{ + release NULL, + setup ENUMERATED {closedLoop, openLoop} + } +} + +AntennaInfoDedicated-v920 ::= SEQUENCE { + codebookSubsetRestriction-v920 CHOICE { + n2TxAntenna-tm8-r9 BIT STRING (SIZE (6)), + n4TxAntenna-tm8-r9 BIT STRING (SIZE (32)) + } OPTIONAL -- Cond TM8 +} + +AntennaInfoDedicated-r10 ::= SEQUENCE { + transmissionMode-r10 ENUMERATED { + tm1, tm2, tm3, tm4, tm5, tm6, tm7, tm8-v920, + tm9-v1020, tm10-v1130, spare6, spare5, spare4, + spare3, spare2, spare1}, + codebookSubsetRestriction-r10 BIT STRING OPTIONAL, -- Cond TMX + ue-TransmitAntennaSelection CHOICE{ + release NULL, + setup ENUMERATED {closedLoop, openLoop} + } +} + +AntennaInfoDedicated-v10i0::= SEQUENCE { + maxLayersMIMO-r10 ENUMERATED {twoLayers, fourLayers, eightLayers} OPTIONAL -- Need OR +} + +AntennaInfoDedicated-v1250 ::= SEQUENCE { + alternativeCodebookEnabledFor4TX-r12 BOOLEAN +} + + +AntennaInfoUL-r10 ::= SEQUENCE { + transmissionModeUL-r10 ENUMERATED {tm1, tm2, spare6, spare5, + spare4, spare3, spare2, spare1} OPTIONAL, -- Need OR + fourAntennaPortActivated-r10 ENUMERATED {setup} OPTIONAL -- Need OR +} + + +CQI-ReportConfig ::= SEQUENCE { + cqi-ReportModeAperiodic CQI-ReportModeAperiodic OPTIONAL, -- Need OR + nomPDSCH-RS-EPRE-Offset INTEGER (-1..6), + cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON +} + +CQI-ReportConfig-v920 ::= SEQUENCE { + cqi-Mask-r9 ENUMERATED {setup} OPTIONAL, -- Cond cqi-Setup + pmi-RI-Report-r9 ENUMERATED {setup} OPTIONAL -- Cond PMIRI +} + +CQI-ReportConfig-r10 ::= SEQUENCE { + cqi-ReportAperiodic-r10 CQI-ReportAperiodic-r10 OPTIONAL, -- Need ON + nomPDSCH-RS-EPRE-Offset INTEGER (-1..6), + cqi-ReportPeriodic-r10 CQI-ReportPeriodic-r10 OPTIONAL, -- Need ON + pmi-RI-Report-r9 ENUMERATED {setup} OPTIONAL, -- Cond PMIRIPCell + csi-SubframePatternConfig-r10 CHOICE { + release NULL, + setup SEQUENCE { + csi-MeasSubframeSet1-r10 MeasSubframePattern-r10, + csi-MeasSubframeSet2-r10 MeasSubframePattern-r10 + } + } OPTIONAL -- Need ON +} + +CQI-ReportConfig-v1130 ::= SEQUENCE { + cqi-ReportPeriodic-v1130 CQI-ReportPeriodic-v1130, + cqi-ReportBoth-r11 CQI-ReportBoth-r11 +} + +CQI-ReportConfig-v1250 ::= SEQUENCE { + csi-SubframePatternConfig-r12 CHOICE { + release NULL, + setup SEQUENCE { + csi-MeasSubframeSets-r12 BIT STRING (SIZE (10)) + } + } OPTIONAL, -- Need ON + cqi-ReportBoth-v1250 CQI-ReportBoth-v1250 OPTIONAL, -- Need ON + cqi-ReportAperiodic-v1250 CQI-ReportAperiodic-v1250 OPTIONAL, -- Need ON + altCQI-Table-r12 ENUMERATED { + allSubframes, csi-SubframeSet1, + csi-SubframeSet2, spare1} OPTIONAL -- Need OP +} + +CQI-ReportConfig-v1310 ::= SEQUENCE { + cqi-ReportBoth-v1310 CQI-ReportBoth-v1310 OPTIONAL, -- Need ON + cqi-ReportAperiodic-v1310 CQI-ReportAperiodic-v1310 OPTIONAL, -- Need ON + cqi-ReportPeriodic-v1310 CQI-ReportPeriodic-v1310 OPTIONAL -- Need ON +} + +CQI-ReportConfig-v1320 ::= SEQUENCE { + cqi-ReportPeriodic-v1320 CQI-ReportPeriodic-v1320 OPTIONAL -- Need ON +} + +CQI-ReportConfigSCell-r10 ::= SEQUENCE { + cqi-ReportModeAperiodic-r10 CQI-ReportModeAperiodic OPTIONAL, -- Need OR + nomPDSCH-RS-EPRE-Offset-r10 INTEGER (-1..6), + cqi-ReportPeriodicSCell-r10 CQI-ReportPeriodic-r10 OPTIONAL, -- Need ON + pmi-RI-Report-r10 ENUMERATED {setup} OPTIONAL -- Cond PMIRISCell +} + +CQI-ReportPeriodic ::= CHOICE { + release NULL, + setup SEQUENCE { + cqi-PUCCH-ResourceIndex INTEGER (0..1185), + cqi-pmi-ConfigIndex INTEGER (0..1023), + cqi-FormatIndicatorPeriodic CHOICE { + widebandCQI NULL, + subbandCQI SEQUENCE { + k INTEGER (1..4) + } + }, + ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR + simultaneousAckNackAndCQI BOOLEAN + } +} + +CQI-ReportPeriodic-r10 ::= CHOICE { + release NULL, + setup SEQUENCE { + cqi-PUCCH-ResourceIndex-r10 INTEGER (0..1184), + cqi-PUCCH-ResourceIndexP1-r10 INTEGER (0..1184) OPTIONAL, -- Need OR + cqi-pmi-ConfigIndex INTEGER (0..1023), + cqi-FormatIndicatorPeriodic-r10 CHOICE { + widebandCQI-r10 SEQUENCE { + csi-ReportMode-r10 ENUMERATED {submode1, submode2} OPTIONAL -- Need OR + }, + subbandCQI-r10 SEQUENCE { + k INTEGER (1..4), + periodicityFactor-r10 ENUMERATED {n2, n4} + } + }, + ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR + simultaneousAckNackAndCQI BOOLEAN, + cqi-Mask-r9 ENUMERATED {setup} OPTIONAL, -- Need OR + csi-ConfigIndex-r10 CHOICE { + release NULL, + setup SEQUENCE { + cqi-pmi-ConfigIndex2-r10 INTEGER (0..1023), + ri-ConfigIndex2-r10 INTEGER (0..1023) OPTIONAL -- Need OR + } + } OPTIONAL -- Need ON + } +} + + +CQI-ReportPeriodic-v1130 ::= SEQUENCE { + simultaneousAckNackAndCQI-Format3-r11 ENUMERATED {setup} OPTIONAL, -- Need OR + cqi-ReportPeriodicProcExtToReleaseList-r11 CQI-ReportPeriodicProcExtToReleaseList-r11 OPTIONAL, -- Need ON + cqi-ReportPeriodicProcExtToAddModList-r11 CQI-ReportPeriodicProcExtToAddModList-r11 OPTIONAL -- Need ON +} + +CQI-ReportPeriodic-v1310 ::= SEQUENCE { + cri-ReportConfig-r13 CRI-ReportConfig-r13 OPTIONAL, -- Need OR + simultaneousAckNackAndCQI-Format4-Format5-r13 ENUMERATED {setup} OPTIONAL-- Need OR +} + +CQI-ReportPeriodic-v1320 ::= SEQUENCE { + periodicityFactorWB-r13 ENUMERATED {n2, n4} OPTIONAL -- Need OR +} + +CQI-ReportPeriodicProcExtToAddModList-r11 ::= SEQUENCE (SIZE (1..maxCQI-ProcExt-r11)) OF CQI-ReportPeriodicProcExt-r11 + +CQI-ReportPeriodicProcExtToReleaseList-r11 ::= SEQUENCE (SIZE (1..maxCQI-ProcExt-r11)) OF CQI-ReportPeriodicProcExtId-r11 + +CQI-ReportPeriodicProcExt-r11 ::= SEQUENCE { + cqi-ReportPeriodicProcExtId-r11 CQI-ReportPeriodicProcExtId-r11, + cqi-pmi-ConfigIndex-r11 INTEGER (0..1023), + cqi-FormatIndicatorPeriodic-r11 CHOICE { + widebandCQI-r11 SEQUENCE { + csi-ReportMode-r11 ENUMERATED {submode1, submode2} OPTIONAL -- Need OR + }, + subbandCQI-r11 SEQUENCE { + k INTEGER (1..4), + periodicityFactor-r11 ENUMERATED {n2, n4} + } + }, + ri-ConfigIndex-r11 INTEGER (0..1023) OPTIONAL, -- Need OR + csi-ConfigIndex-r11 CHOICE { + release NULL, + setup SEQUENCE { + cqi-pmi-ConfigIndex2-r11 INTEGER (0..1023), + ri-ConfigIndex2-r11 INTEGER (0..1023) OPTIONAL -- Need OR + } + } OPTIONAL, -- Need ON + ..., + [[ cri-ReportConfig-r13 CRI-ReportConfig-r13 OPTIONAL -- Need ON + ]], + [[ periodicityFactorWB-r13 ENUMERATED {n2, n4} OPTIONAL -- Need ON + ]] +} + +CQI-ReportAperiodic-r10 ::= CHOICE { + release NULL, + setup SEQUENCE { + cqi-ReportModeAperiodic-r10 CQI-ReportModeAperiodic, + aperiodicCSI-Trigger-r10 SEQUENCE { + trigger1-r10 BIT STRING (SIZE (8)), + trigger2-r10 BIT STRING (SIZE (8)) + } OPTIONAL -- Need OR + } +} + +CQI-ReportAperiodic-v1250 ::= CHOICE { + release NULL, + setup SEQUENCE { + aperiodicCSI-Trigger-v1250 SEQUENCE { + trigger-SubframeSetIndicator-r12 ENUMERATED {s1, s2}, + trigger1-SubframeSetIndicator-r12 BIT STRING (SIZE (8)), + trigger2-SubframeSetIndicator-r12 BIT STRING (SIZE (8)) + } + } +} + +CQI-ReportAperiodic-v1310 ::= CHOICE { + release NULL, + setup SEQUENCE { + aperiodicCSI-Trigger-v1310 SEQUENCE { + trigger1-r13 BIT STRING (SIZE (32)), + trigger2-r13 BIT STRING (SIZE (32)), + trigger3-r13 BIT STRING (SIZE (32)), + trigger4-r13 BIT STRING (SIZE (32)), + trigger5-r13 BIT STRING (SIZE (32)), + trigger6-r13 BIT STRING (SIZE (32)) + } OPTIONAL, -- Need ON + aperiodicCSI-Trigger2-r13 CHOICE { + release NULL, + setup SEQUENCE { + trigger1-SubframeSetIndicator-r13 BIT STRING (SIZE (32)), + trigger2-SubframeSetIndicator-r13 BIT STRING (SIZE (32)), + trigger3-SubframeSetIndicator-r13 BIT STRING (SIZE (32)), + trigger4-SubframeSetIndicator-r13 BIT STRING (SIZE (32)), + trigger5-SubframeSetIndicator-r13 BIT STRING (SIZE (32)), + trigger6-SubframeSetIndicator-r13 BIT STRING (SIZE (32)) + } + } OPTIONAL -- Need ON + } +} + +CQI-ReportAperiodicProc-r11 ::= SEQUENCE { + cqi-ReportModeAperiodic-r11 CQI-ReportModeAperiodic, + trigger01-r11 BOOLEAN, + trigger10-r11 BOOLEAN, + trigger11-r11 BOOLEAN +} + +CQI-ReportAperiodicProc-v1310 ::= SEQUENCE { + trigger001-r13 BOOLEAN, + trigger010-r13 BOOLEAN, + trigger011-r13 BOOLEAN, + trigger100-r13 BOOLEAN, + trigger101-r13 BOOLEAN, + trigger110-r13 BOOLEAN, + trigger111-r13 BOOLEAN +} + +CQI-ReportModeAperiodic ::= ENUMERATED { + rm12, rm20, rm22, rm30, rm31, + rm32-v1250, rm10-v1310, rm11-v1310 +} + +CQI-ReportBoth-r11 ::= SEQUENCE { + csi-IM-ConfigToReleaseList-r11 CSI-IM-ConfigToReleaseList-r11 OPTIONAL, -- Need ON + csi-IM-ConfigToAddModList-r11 CSI-IM-ConfigToAddModList-r11 OPTIONAL, -- Need ON + csi-ProcessToReleaseList-r11 CSI-ProcessToReleaseList-r11 OPTIONAL, -- Need ON + csi-ProcessToAddModList-r11 CSI-ProcessToAddModList-r11 OPTIONAL -- Need ON +} + +CQI-ReportBoth-v1250 ::= SEQUENCE { + csi-IM-ConfigToReleaseListExt-r12 CSI-IM-ConfigId-v1250 OPTIONAL, -- Need ON + csi-IM-ConfigToAddModListExt-r12 CSI-IM-ConfigExt-r12 OPTIONAL -- Need ON +} + +CQI-ReportBoth-v1310 ::= SEQUENCE { + csi-IM-ConfigToReleaseListExt-r13 CSI-IM-ConfigToReleaseListExt-r13 OPTIONAL, -- Need ON + csi-IM-ConfigToAddModListExt-r13 CSI-IM-ConfigToAddModListExt-r13 OPTIONAL -- Need ON +} + +CSI-IM-ConfigToAddModList-r11 ::= SEQUENCE (SIZE (1..maxCSI-IM-r11)) OF CSI-IM-Config-r11 + +CSI-IM-ConfigToAddModListExt-r13 ::= SEQUENCE (SIZE (1..maxCSI-IM-v1310)) OF CSI-IM-ConfigExt-r12 + +CSI-IM-ConfigToReleaseList-r11 ::= SEQUENCE (SIZE (1..maxCSI-IM-r11)) OF CSI-IM-ConfigId-r11 + +CSI-IM-ConfigToReleaseListExt-r13 ::= SEQUENCE (SIZE (1..maxCSI-IM-v1310)) OF CSI-IM-ConfigId-v1310 + +CSI-ProcessToAddModList-r11 ::= SEQUENCE (SIZE (1..maxCSI-Proc-r11)) OF CSI-Process-r11 + +CSI-ProcessToReleaseList-r11 ::= SEQUENCE (SIZE (1..maxCSI-Proc-r11)) OF CSI-ProcessId-r11 + +CQI-ReportBothProc-r11 ::= SEQUENCE { + ri-Ref-CSI-ProcessId-r11 CSI-ProcessId-r11 OPTIONAL, -- Need OR + pmi-RI-Report-r11 ENUMERATED {setup} OPTIONAL -- Need OR +} + +CRI-ReportConfig-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + cri-ConfigIndex-r13 CRI-ConfigIndex-r13, + cri-ConfigIndex2-r13 CRI-ConfigIndex-r13 OPTIONAL -- Need OR + } +} + +CRI-ConfigIndex-r13 ::= INTEGER (0..1023) + + +CQI-ReportPeriodicProcExtId-r11 ::= INTEGER (1..maxCQI-ProcExt-r11) + + +CrossCarrierSchedulingConfig-r10 ::= SEQUENCE { + schedulingCellInfo-r10 CHOICE { + own-r10 SEQUENCE { -- No cross carrier scheduling + cif-Presence-r10 BOOLEAN + }, + other-r10 SEQUENCE { -- Cross carrier scheduling + schedulingCellId-r10 ServCellIndex-r10, + pdsch-Start-r10 INTEGER (1..4) + } + } +} + +CrossCarrierSchedulingConfig-r13 ::= SEQUENCE { + schedulingCellInfo-r13 CHOICE { + own-r13 SEQUENCE { -- No cross carrier scheduling + cif-Presence-r13 BOOLEAN + }, + other-r13 SEQUENCE { -- Cross carrier scheduling + schedulingCellId-r13 ServCellIndex-r13, + pdsch-Start-r13 INTEGER (1..4), + cif-InSchedulingCell-r13 INTEGER (1..7) + } + } +} + +CrossCarrierSchedulingConfigLAA-UL-r14 ::= SEQUENCE { + schedulingCellId-r14 ServCellIndex-r13, + cif-InSchedulingCell-r14 INTEGER (1..7) +} + +CSI-IM-Config-r11 ::= SEQUENCE { + csi-IM-ConfigId-r11 CSI-IM-ConfigId-r11, + resourceConfig-r11 INTEGER (0..31), + subframeConfig-r11 INTEGER (0..154), + ..., + [[ interferenceMeasRestriction-r13 BOOLEAN OPTIONAL -- Need ON + ]] +} + +CSI-IM-ConfigExt-r12 ::= SEQUENCE { + csi-IM-ConfigId-v1250 CSI-IM-ConfigId-v1250, + resourceConfig-r12 INTEGER (0..31), + subframeConfig-r12 INTEGER (0..154), + ..., + [[ interferenceMeasRestriction-r13 BOOLEAN OPTIONAL, -- Need ON + csi-IM-ConfigId-v1310 CSI-IM-ConfigId-v1310 OPTIONAL -- Need ON + ]] +} + + +CSI-IM-ConfigId-r11 ::= INTEGER (1..maxCSI-IM-r11) +CSI-IM-ConfigId-r12 ::= INTEGER (1..maxCSI-IM-r12) +CSI-IM-ConfigId-v1250 ::= INTEGER (maxCSI-IM-r12) +CSI-IM-ConfigId-v1310 ::= INTEGER (minCSI-IM-r13..maxCSI-IM-r13) +CSI-IM-ConfigId-r13 ::= INTEGER (1..maxCSI-IM-r13) + + +CSI-Process-r11 ::= SEQUENCE { + csi-ProcessId-r11 CSI-ProcessId-r11, + csi-RS-ConfigNZPId-r11 CSI-RS-ConfigNZPId-r11, + csi-IM-ConfigId-r11 CSI-IM-ConfigId-r11, + p-C-AndCBSRList-r11 P-C-AndCBSR-Pair-r13a, + cqi-ReportBothProc-r11 CQI-ReportBothProc-r11 OPTIONAL, -- Need OR + cqi-ReportPeriodicProcId-r11 INTEGER (0..maxCQI-ProcExt-r11) OPTIONAL, -- Need OR + cqi-ReportAperiodicProc-r11 CQI-ReportAperiodicProc-r11 OPTIONAL, -- Need OR + ..., + [[ alternativeCodebookEnabledFor4TXProc-r12 ENUMERATED {true} OPTIONAL, -- Need ON + csi-IM-ConfigIdList-r12 CHOICE { + release NULL, + setup SEQUENCE (SIZE (1..2)) OF CSI-IM-ConfigId-r12 + } OPTIONAL, -- Need ON + cqi-ReportAperiodicProc2-r12 CHOICE { + release NULL, + setup CQI-ReportAperiodicProc-r11 + } OPTIONAL -- Need ON + ]], + [[ cqi-ReportAperiodicProc-v1310 CHOICE { + release NULL, + setup CQI-ReportAperiodicProc-v1310 + } OPTIONAL, -- Need ON + cqi-ReportAperiodicProc2-v1310 CHOICE { + release NULL, + setup CQI-ReportAperiodicProc-v1310 + } OPTIONAL, -- Need ON + eMIMO-Type-r13 CSI-RS-ConfigEMIMO-r13 OPTIONAL -- Need ON + ]] +} + + +CSI-ProcessId-r11 ::= INTEGER (1..maxCSI-Proc-r11) + + +CSI-RS-Config-r10 ::= SEQUENCE { + csi-RS-r10 CHOICE { + release NULL, + setup SEQUENCE { + antennaPortsCount-r10 ENUMERATED {an1, an2, an4, an8}, + resourceConfig-r10 INTEGER (0..31), + subframeConfig-r10 INTEGER (0..154), + p-C-r10 INTEGER (-8..15) + } + } OPTIONAL, -- Need ON + zeroTxPowerCSI-RS-r10 ZeroTxPowerCSI-RS-Conf-r12 OPTIONAL -- Need ON +} + +CSI-RS-Config-v1250 ::= SEQUENCE { + zeroTxPowerCSI-RS2-r12 ZeroTxPowerCSI-RS-Conf-r12 OPTIONAL, -- Need ON + ds-ZeroTxPowerCSI-RS-r12 CHOICE { + release NULL, + setup SEQUENCE { + zeroTxPowerCSI-RS-List-r12 SEQUENCE (SIZE (1..maxDS-ZTP-CSI-RS-r12)) OF ZeroTxPowerCSI-RS-r12 + } + } OPTIONAL -- Need ON +} + +CSI-RS-Config-v1310 ::= SEQUENCE { + eMIMO-Type-r13 CSI-RS-ConfigEMIMO-r13 OPTIONAL -- Need ON +} + +ZeroTxPowerCSI-RS-Conf-r12 ::= CHOICE { + release NULL, + setup ZeroTxPowerCSI-RS-r12 +} + +ZeroTxPowerCSI-RS-r12 ::= SEQUENCE { + zeroTxPowerResourceConfigList-r12 BIT STRING (SIZE (16)), + zeroTxPowerSubframeConfig-r12 INTEGER (0..154) +} + + +CSI-RS-ConfigEMIMO-r13 ::= CHOICE { + release NULL, + setup CHOICE { + nonPrecoded-r13 CSI-RS-ConfigNonPrecoded-r13, + beamformed-r13 CSI-RS-ConfigBeamformed-r13 + } +} + +CSI-RS-ConfigNonPrecoded-r13 ::= SEQUENCE { + p-C-AndCBSRList-r13 P-C-AndCBSR-Pair-r13 OPTIONAL, -- Need OR + codebookConfigN1-r13 ENUMERATED {n1, n2, n3, n4, n8}, + codebookConfigN2-r13 ENUMERATED {n1, n2, n3, n4, n8}, + codebookOverSamplingRateConfig-O1-r13 ENUMERATED {n4, n8} OPTIONAL, -- Need OR + codebookOverSamplingRateConfig-O2-r13 ENUMERATED {n4, n8} OPTIONAL, -- Need OR + codebookConfig-r13 INTEGER (1..4), + csi-IM-ConfigIdList-r13 SEQUENCE (SIZE (1..2)) OF CSI-IM-ConfigId-r13 OPTIONAL, -- Need OR + csi-RS-ConfigNZP-EMIMO-r13 CSI-RS-ConfigNZP-EMIMO-r13 OPTIONAL -- Need ON +} + +CSI-RS-ConfigBeamformed-r13 ::= SEQUENCE { + csi-RS-ConfigNZPIdListExt-r13 SEQUENCE (SIZE (1..7)) OF CSI-RS-ConfigNZPId-r13 OPTIONAL, -- Need OR + csi-IM-ConfigIdList-r13 SEQUENCE (SIZE (1..8)) OF CSI-IM-ConfigId-r13 OPTIONAL, -- Need OR + p-C-AndCBSR-PerResourceConfigList-r13 SEQUENCE (SIZE (1..8)) OF P-C-AndCBSR-Pair-r13 OPTIONAL, -- Need OR + ace-For4Tx-PerResourceConfigList-r13 SEQUENCE (SIZE (1..7)) OF BOOLEAN OPTIONAL, -- Need OR + alternativeCodebookEnabledBeamformed-r13 ENUMERATED {true} OPTIONAL, -- Need OR + channelMeasRestriction-r13 ENUMERATED {on} OPTIONAL -- Need OR +} + + +CSI-RS-ConfigNZP-r11 ::= SEQUENCE { + csi-RS-ConfigNZPId-r11 CSI-RS-ConfigNZPId-r11, + antennaPortsCount-r11 ENUMERATED {an1, an2, an4, an8}, + resourceConfig-r11 INTEGER (0..31), + subframeConfig-r11 INTEGER (0..154), + scramblingIdentity-r11 INTEGER (0..503), + qcl-CRS-Info-r11 SEQUENCE { + qcl-ScramblingIdentity-r11 INTEGER (0..503), + crs-PortsCount-r11 ENUMERATED {n1, n2, n4, spare1}, + mbsfn-SubframeConfigList-r11 CHOICE { + release NULL, + setup SEQUENCE { + subframeConfigList MBSFN-SubframeConfigList + } + } OPTIONAL -- Need ON + } OPTIONAL, -- Need OR + ..., + [[ csi-RS-ConfigNZPId-v1310 CSI-RS-ConfigNZPId-v1310 OPTIONAL -- Need ON + ]] +} + +CSI-RS-ConfigNZP-EMIMO-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + nzp-resourceConfigList-r13 SEQUENCE (SIZE (1..2)) OF NZP-ResourceConfig-r13, + cdmType-r13 ENUMERATED {cdm2, cdm4} OPTIONAL -- Need OR + } +} + +NZP-ResourceConfig-r13 ::= SEQUENCE { + resourceConfig-r13 ResourceConfig-r13, + ... +} + +ResourceConfig-r13 ::= INTEGER (0..31) + + +CSI-RS-ConfigNZPId-r11 ::= INTEGER (1..maxCSI-RS-NZP-r11) +CSI-RS-ConfigNZPId-v1310 ::= INTEGER (minCSI-RS-NZP-r13..maxCSI-RS-NZP-r13) +CSI-RS-ConfigNZPId-r13 ::= INTEGER (1..maxCSI-RS-NZP-r13) + + +CSI-RS-ConfigZP-r11 ::= SEQUENCE { + csi-RS-ConfigZPId-r11 CSI-RS-ConfigZPId-r11, + resourceConfigList-r11 BIT STRING (SIZE (16)), + subframeConfig-r11 INTEGER (0..154), + ... +} + + +CSI-RS-ConfigZPId-r11 ::= INTEGER (1..maxCSI-RS-ZP-r11) + + +DMRS-Config-r11 ::= CHOICE { + release NULL, + setup SEQUENCE { + scramblingIdentity-r11 INTEGER (0..503), + scramblingIdentity2-r11 INTEGER (0..503) + } +} +DMRS-Config-v1310 ::= SEQUENCE { + dmrs-tableAlt-r13 ENUMERATED {true} OPTIONAL -- Need OR +} + + +DRB-Identity ::= INTEGER (1..32) + + +EPDCCH-Config-r11 ::= SEQUENCE{ + config-r11 CHOICE { + release NULL, + setup SEQUENCE { + subframePatternConfig-r11 CHOICE { + release NULL, + setup SEQUENCE { + subframePattern-r11 MeasSubframePattern-r10 + } + } OPTIONAL, -- Need ON + startSymbol-r11 INTEGER (1..4) OPTIONAL, -- Need OP + setConfigToReleaseList-r11 EPDCCH-SetConfigToReleaseList-r11 OPTIONAL, -- Need ON + setConfigToAddModList-r11 EPDCCH-SetConfigToAddModList-r11 OPTIONAL -- Need ON + } + } +} + +EPDCCH-SetConfigToAddModList-r11 ::= SEQUENCE (SIZE(1..maxEPDCCH-Set-r11)) OF EPDCCH-SetConfig-r11 + +EPDCCH-SetConfigToReleaseList-r11 ::= SEQUENCE (SIZE(1..maxEPDCCH-Set-r11)) OF EPDCCH-SetConfigId-r11 + +EPDCCH-SetConfig-r11 ::= SEQUENCE { + setConfigId-r11 EPDCCH-SetConfigId-r11, + transmissionType-r11 ENUMERATED {localised, distributed}, + resourceBlockAssignment-r11 SEQUENCE{ + numberPRB-Pairs-r11 ENUMERATED {n2, n4, n8}, + resourceBlockAssignment-r11 BIT STRING (SIZE(4..38)) + }, + dmrs-ScramblingSequenceInt-r11 INTEGER (0..503), + pucch-ResourceStartOffset-r11 INTEGER (0..2047), + re-MappingQCL-ConfigId-r11 PDSCH-RE-MappingQCL-ConfigId-r11 OPTIONAL, -- Need OR + ..., + [[ csi-RS-ConfigZPId2-r12 CHOICE { + release NULL, + setup CSI-RS-ConfigZPId-r11 + } OPTIONAL -- Need ON + ]], + [[ numberPRB-Pairs-v1310 CHOICE { + release NULL, + setup ENUMERATED {n6} + } OPTIONAL, -- Need ON + mpdcch-config-r13 CHOICE { + release NULL, + setup SEQUENCE { + csi-NumRepetitionCE-r13 ENUMERATED {sf1, sf2, sf4, sf8, sf16, sf32}, + mpdcch-pdsch-HoppingConfig-r13 ENUMERATED {on,off}, + mpdcch-StartSF-UESS-r13 CHOICE { + fdd-r13 ENUMERATED {v1, v1dot5, v2, v2dot5, v4, + v5, v8, v10}, tdd-r13 ENUMERATED {v1, v2, v4, v5, v8, v10, + v20, spare1} + }, + mpdcch-NumRepetition-r13 ENUMERATED {r1, r2, r4, r8, r16, + r32, r64, r128, r256}, + mpdcch-Narrowband-r13 INTEGER (1.. maxAvailNarrowBands-r13) + } + } OPTIONAL -- Need ON + ]] +} + +EPDCCH-SetConfigId-r11 ::= INTEGER (0..1) + + +EIMTA-MainConfig-r12 ::= CHOICE { + release NULL, + setup SEQUENCE { + eimta-RNTI-r12 C-RNTI, + eimta-CommandPeriodicity-r12 ENUMERATED {sf10, sf20, sf40, sf80}, + eimta-CommandSubframeSet-r12 BIT STRING (SIZE(10)) + } +} + +EIMTA-MainConfigServCell-r12 ::= CHOICE { + release NULL, + setup SEQUENCE { + eimta-UL-DL-ConfigIndex-r12 INTEGER (1..5), + eimta-HARQ-ReferenceConfig-r12 ENUMERATED {sa2,sa4,sa5}, + mbsfn-SubframeConfigList-v1250 CHOICE { + release NULL, + setup SEQUENCE { + subframeConfigList-r12 MBSFN-SubframeConfigList + } + } + } +} + + +LogicalChannelConfig ::= SEQUENCE { + ul-SpecificParameters SEQUENCE { + priority INTEGER (1..16), + prioritisedBitRate ENUMERATED { + kBps0, kBps8, kBps16, kBps32, kBps64, kBps128, + kBps256, infinity, kBps512-v1020, kBps1024-v1020, + kBps2048-v1020, spare5, spare4, spare3, spare2, + spare1}, + bucketSizeDuration ENUMERATED { + ms50, ms100, ms150, ms300, ms500, ms1000, spare2, + spare1}, + logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR + } OPTIONAL, -- Cond UL + ..., + [[ logicalChannelSR-Mask-r9 ENUMERATED {setup} OPTIONAL -- Cond SRmask + ]], + [[ logicalChannelSR-Prohibit-r12 BOOLEAN OPTIONAL -- Need ON + ]], + [[ laa-Allowed-r14 BOOLEAN OPTIONAL -- Need ON + ]] +} + + +LWA-Configuration-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + lwa-Config-r13 LWA-Config-r13 + } +} + +LWA-Config-r13 ::= SEQUENCE { + lwa-MobilityConfig-r13 WLAN-MobilityConfig-r13 OPTIONAL, -- Need ON + lwa-WT-Counter-r13 INTEGER (0..65535) OPTIONAL, -- Need ON + ... +} + + +LWIP-Configuration-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + lwip-Config-r13 LWIP-Config-r13 + } +} + +LWIP-Config-r13 ::= SEQUENCE { + lwip-MobilityConfig-r13 WLAN-MobilityConfig-r13 OPTIONAL, -- Need ON + tunnelConfigLWIP-r13 TunnelConfigLWIP-r13 OPTIONAL, -- Need ON + ... +} + + +MAC-MainConfig ::= SEQUENCE { + ul-SCH-Config SEQUENCE { + maxHARQ-Tx ENUMERATED { + n1, n2, n3, n4, n5, n6, n7, n8, + n10, n12, n16, n20, n24, n28, + spare2, spare1} OPTIONAL, -- Need ON + periodicBSR-Timer PeriodicBSR-Timer-r12 OPTIONAL, -- Need ON + retxBSR-Timer RetxBSR-Timer-r12, + ttiBundling BOOLEAN + } OPTIONAL, -- Need ON + drx-Config DRX-Config OPTIONAL, -- Need ON + timeAlignmentTimerDedicated TimeAlignmentTimer, + phr-Config CHOICE { + release NULL, + setup SEQUENCE { + periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200, + sf500, sf1000, infinity}, + prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100, + sf200, sf500, sf1000}, + dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity} + } + } OPTIONAL, -- Need ON + ..., + [[ sr-ProhibitTimer-r9 INTEGER (0..7) OPTIONAL -- Need ON + ]], + [[ mac-MainConfig-v1020 SEQUENCE { + sCellDeactivationTimer-r10 ENUMERATED { + rf2, rf4, rf8, rf16, rf32, rf64, rf128, + spare} OPTIONAL, -- Need OP + extendedBSR-Sizes-r10 ENUMERATED {setup} OPTIONAL, -- Need OR + extendedPHR-r10 ENUMERATED {setup} OPTIONAL -- Need OR + } OPTIONAL -- Need ON + ]], + [[ stag-ToReleaseList-r11 STAG-ToReleaseList-r11 OPTIONAL, -- Need ON + stag-ToAddModList-r11 STAG-ToAddModList-r11 OPTIONAL, -- Need ON + drx-Config-v1130 DRX-Config-v1130 OPTIONAL -- Need ON + ]], + [[ e-HARQ-Pattern-r12 BOOLEAN OPTIONAL, -- Need ON + dualConnectivityPHR CHOICE { + release NULL, + setup SEQUENCE { + phr-ModeOtherCG-r12 ENUMERATED {real, virtual} + } + } OPTIONAL, -- Need ON + logicalChannelSR-Config-r12 CHOICE { + release NULL, + setup SEQUENCE { + logicalChannelSR-ProhibitTimer-r12 ENUMERATED {sf20, sf40, sf64, sf128, sf512, sf1024, sf2560, spare1} + } + } OPTIONAL -- Need ON + ]], + [[ drx-Config-v1310 DRX-Config-v1310 OPTIONAL, -- Need ON + extendedPHR2-r13 BOOLEAN OPTIONAL, -- Need ON + eDRX-Config-CycleStartOffset-r13 CHOICE { + release NULL, + setup + CHOICE { + sf5120 INTEGER(0..1), + sf10240 INTEGER(0..3) + } + } OPTIONAL -- Need ON + ]], + [[ drx-Config-r13 CHOICE { + release NULL, + setup DRX-Config-r13 + } OPTIONAL -- Need ON + ]], + [[ skipUplinkTx-r14 CHOICE { + release NULL, + setup SEQUENCE { + skipUplinkTxSPS-r14 ENUMERATED {true} OPTIONAL, -- Need OR + skipUplinkTxDynamic-r14 ENUMERATED {true} OPTIONAL -- Need OR + } + } OPTIONAL -- Need ON + ]] +} + +MAC-MainConfigSCell-r11 ::= SEQUENCE { + stag-Id-r11 STAG-Id-r11 OPTIONAL, -- Need OP + ... +} + +DRX-Config ::= CHOICE { + release NULL, + setup SEQUENCE { + onDurationTimer ENUMERATED { + psf1, psf2, psf3, psf4, psf5, psf6, + psf8, psf10, psf20, psf30, psf40, + psf50, psf60, psf80, psf100, + psf200}, + drx-InactivityTimer ENUMERATED { + psf1, psf2, psf3, psf4, psf5, psf6, + psf8, psf10, psf20, psf30, psf40, + psf50, psf60, psf80, psf100, + psf200, psf300, psf500, psf750, + psf1280, psf1920, psf2560, psf0-v1020, + spare9, spare8, spare7, spare6, + spare5, spare4, spare3, spare2, + spare1}, + drx-RetransmissionTimer ENUMERATED { + psf1, psf2, psf4, psf6, psf8, psf16, + psf24, psf33}, + longDRX-CycleStartOffset CHOICE { + sf10 INTEGER(0..9), + sf20 INTEGER(0..19), + sf32 INTEGER(0..31), + sf40 INTEGER(0..39), + sf64 INTEGER(0..63), + sf80 INTEGER(0..79), + sf128 INTEGER(0..127), + sf160 INTEGER(0..159), + sf256 INTEGER(0..255), + sf320 INTEGER(0..319), + sf512 INTEGER(0..511), + sf640 INTEGER(0..639), + sf1024 INTEGER(0..1023), + sf1280 INTEGER(0..1279), + sf2048 INTEGER(0..2047), + sf2560 INTEGER(0..2559) + }, + shortDRX SEQUENCE { + shortDRX-Cycle ENUMERATED { + sf2, sf5, sf8, sf10, sf16, sf20, + sf32, sf40, sf64, sf80, sf128, sf160, + sf256, sf320, sf512, sf640}, + drxShortCycleTimer INTEGER (1..16) + } OPTIONAL -- Need OR + } +} + +DRX-Config-v1130 ::= SEQUENCE { + drx-RetransmissionTimer-v1130 ENUMERATED {psf0-v1130} OPTIONAL, --Need OR + longDRX-CycleStartOffset-v1130 CHOICE { + sf60-v1130 INTEGER(0..59), + sf70-v1130 INTEGER(0..69) + } OPTIONAL, --Need OR + shortDRX-Cycle-v1130 ENUMERATED {sf4-v1130} OPTIONAL --Need OR +} +DRX-Config-v1310 ::= SEQUENCE { + longDRX-CycleStartOffset-v1310 SEQUENCE { + sf60-v1310 INTEGER(0..59) + } OPTIONAL --Need OR +} + +DRX-Config-r13 ::= SEQUENCE { + onDurationTimer-v1310 ENUMERATED {psf300, psf400, psf500, psf600, + psf800, psf1000, psf1200, psf1600} OPTIONAL, --Need OR + drx-RetransmissionTimer-v1310 ENUMERATED {psf40, psf64, psf80, psf96, psf112, + psf128, psf160, psf320} + OPTIONAL, --Need OR + drx-ULRetransmissionTimer-r13 ENUMERATED {psf0, psf1, psf2, psf4, psf6, psf8, psf16, + psf24, psf33, psf40, psf64, psf80, psf96, + psf112, psf128, psf160, psf320} + OPTIONAL --Need OR +} + +PeriodicBSR-Timer-r12 ::= ENUMERATED { + sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80, + sf128, sf160, sf320, sf640, sf1280, sf2560, + infinity, spare1} + +RetxBSR-Timer-r12 ::= ENUMERATED { + sf320, sf640, sf1280, sf2560, sf5120, + sf10240, spare2, spare1} + +STAG-ToReleaseList-r11 ::= SEQUENCE (SIZE (1..maxSTAG-r11)) OF STAG-Id-r11 + +STAG-ToAddModList-r11 ::= SEQUENCE (SIZE (1..maxSTAG-r11)) OF STAG-ToAddMod-r11 + +STAG-ToAddMod-r11 ::= SEQUENCE { + stag-Id-r11 STAG-Id-r11, + timeAlignmentTimerSTAG-r11 TimeAlignmentTimer, + ... +} + +STAG-Id-r11::= INTEGER (1..maxSTAG-r11) + + +P-C-AndCBSR-r11 ::= SEQUENCE { + p-C-r11 INTEGER (-8..15), + codebookSubsetRestriction-r11 BIT STRING +} + +P-C-AndCBSR-r13 ::= SEQUENCE { + p-C-r13 INTEGER (-8..15), + cbsr-Selection-r13 CHOICE{ + nonPrecoded-r13 SEQUENCE { + codebookSubsetRestriction1-r13 BIT STRING, + codebookSubsetRestriction2-r13 BIT STRING + }, + beamformedK1a-r13 SEQUENCE { + codebookSubsetRestriction3-r13 BIT STRING + }, + beamformedKN-r13 SEQUENCE { + codebookSubsetRestriction-r13 BIT STRING + } + }, + ... +} + +P-C-AndCBSR-Pair-r13a ::= SEQUENCE (SIZE (1..2)) OF P-C-AndCBSR-r11 + +P-C-AndCBSR-Pair-r13 ::= SEQUENCE (SIZE (1..2)) OF P-C-AndCBSR-r13 + + +PDCCH-ConfigSCell-r13 ::= SEQUENCE { + skipMonitoringDCI-format0-1A-r13 ENUMERATED {true} OPTIONAL -- Need OR +} + +PDCCH-ConfigLAA-r14 ::= SEQUENCE { + enableMonitoringDCI-Format0B-r14 CHOICE { + release NULL, + setup SEQUENCE { + maxNumberOfSchedSubframes-Format0B-r14 ENUMERATED {sf2, sf3, sf4} + } + } OPTIONAL, -- Need ON + enableMonitoringDCI-Format4B-r14 CHOICE { + release NULL, + setup SEQUENCE { + maxNumberOfSchedSubframes-Format4B-r14 ENUMERATED {sf2, sf3, sf4} + } + } OPTIONAL, -- Need ON + skipMonitoringDCI-Format0A-r14 ENUMERATED {true} OPTIONAL, -- Need OR + skipMonitoringDCI-Format4A-r14 ENUMERATED {true} OPTIONAL, -- Need OR + pdcch-CandidateReductions-Format0A-r14 + PDCCH-CandidateReductions-r13 OPTIONAL, -- Need ON + pdcch-CandidateReductions-Format4A-r14 + PDCCH-CandidateReductionsLAA-UL-r14 OPTIONAL, -- Need ON + pdcch-CandidateReductions-Format0B-r14 + PDCCH-CandidateReductionsLAA-UL-r14 OPTIONAL, -- Need ON + pdcch-CandidateReductions-Format4B-r14 + PDCCH-CandidateReductionsLAA-UL-r14 OPTIONAL -- Need ON +} + +PDCCH-CandidateReductionValue-r13 ::= ENUMERATED {n0, n33, n66, n100} + +PDCCH-CandidateReductionValue-r14 ::= ENUMERATED {n0, n50, n100, n150} + +PDCCH-CandidateReductions-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + pdcch-candidateReductionAL1-r13 PDCCH-CandidateReductionValue-r13, + pdcch-candidateReductionAL2-r13 PDCCH-CandidateReductionValue-r13, + pdcch-candidateReductionAL3-r13 PDCCH-CandidateReductionValue-r13, + pdcch-candidateReductionAL4-r13 PDCCH-CandidateReductionValue-r13, + pdcch-candidateReductionAL5-r13 PDCCH-CandidateReductionValue-r13 + } +} + +PDCCH-CandidateReductionsLAA-UL-r14 ::= CHOICE { + release NULL, + setup SEQUENCE { + pdcch-candidateReductionAL1-r14 PDCCH-CandidateReductionValue-r13, + pdcch-candidateReductionAL2-r14 PDCCH-CandidateReductionValue-r13, + pdcch-candidateReductionAL3-r14 PDCCH-CandidateReductionValue-r14, + pdcch-candidateReductionAL4-r14 PDCCH-CandidateReductionValue-r14, + pdcch-candidateReductionAL5-r14 PDCCH-CandidateReductionValue-r14 + } +} + + +PDCP-Config ::= SEQUENCE { + discardTimer ENUMERATED { + ms50, ms100, ms150, ms300, ms500, + ms750, ms1500, infinity + } OPTIONAL, -- Cond Setup + rlc-AM SEQUENCE { + statusReportRequired BOOLEAN + } OPTIONAL, -- Cond Rlc-AM + rlc-UM SEQUENCE { + pdcp-SN-Size ENUMERATED {len7bits, len12bits} + } OPTIONAL, -- Cond Rlc-UM + headerCompression CHOICE { + notUsed NULL, + rohc SEQUENCE { + maxCID INTEGER (1..16383) DEFAULT 15, + profiles SEQUENCE { + profile0x0001 BOOLEAN, + profile0x0002 BOOLEAN, + profile0x0003 BOOLEAN, + profile0x0004 BOOLEAN, + profile0x0006 BOOLEAN, + profile0x0101 BOOLEAN, + profile0x0102 BOOLEAN, + profile0x0103 BOOLEAN, + profile0x0104 BOOLEAN + }, + ... + } + }, + ..., + [[ rn-IntegrityProtection-r10 ENUMERATED {enabled} OPTIONAL -- Cond RN + ]], + [[ pdcp-SN-Size-v1130 ENUMERATED {len15bits} OPTIONAL -- Cond Rlc-AM2 + ]], + [[ ul-DataSplitDRB-ViaSCG-r12 BOOLEAN OPTIONAL, -- Need ON + t-Reordering-r12 ENUMERATED { + ms0, ms20, ms40, ms60, ms80, ms100, ms120, ms140, + ms160, ms180, ms200, ms220, ms240, ms260, ms280, ms300, + ms500, ms750, spare14, spare13, spare12, spare11, spare10, + spare9, spare8, spare7, spare6, spare5, spare4, spare3, + spare2, spare1} OPTIONAL -- Cond SetupS + ]], + [[ ul-DataSplitThreshold-r13 CHOICE { + release NULL, + setup ENUMERATED { + b0, b100, b200, b400, b800, b1600, b3200, b6400, b12800, + b25600, b51200, b102400, b204800, b409600, b819200, + spare1} + } OPTIONAL, -- Need ON + pdcp-SN-Size-v1310 ENUMERATED {len18bits} OPTIONAL, -- Cond Rlc-AM3 + statusFeedback-r13 CHOICE { + release NULL, + setup SEQUENCE { + statusPDU-TypeForPolling-r13 ENUMERATED {type1, type2} OPTIONAL, -- Need ON + statusPDU-Periodicity-Type1-r13 ENUMERATED { + ms5, ms10, ms20, ms30, ms40, ms50, ms60, ms70, ms80, ms90, + ms100, ms150, ms200, ms300, ms500, ms1000, ms2000, ms5000, + ms10000, ms20000, ms50000} OPTIONAL, -- Need ON + statusPDU-Periodicity-Type2-r13 ENUMERATED { + ms5, ms10, ms20, ms30, ms40, ms50, ms60, ms70, ms80, ms90, + ms100, ms150, ms200, ms300, ms500, ms1000, ms2000, ms5000, + ms10000, ms20000, ms50000} OPTIONAL, -- Need ON + statusPDU-Periodicity-Offset-r13 ENUMERATED { + ms1, ms2, ms5, ms10, ms25, ms50, ms100, ms250, ms500, + ms2500, ms5000, ms25000} OPTIONAL -- Need ON + } + } OPTIONAL -- Need ON + ]] + +} + + +PDSCH-ConfigCommon ::= SEQUENCE { + referenceSignalPower INTEGER (-60..50), + p-b INTEGER (0..3) +} + +PDSCH-ConfigCommon-v1310 ::= SEQUENCE { + pdsch-maxNumRepetitionCEmodeA-r13 ENUMERATED { + r16, r32 } OPTIONAL, -- Need OR + pdsch-maxNumRepetitionCEmodeB-r13 ENUMERATED { + r192, r256, r384, r512, r768, r1024, + r1536, r2048} OPTIONAL -- Need OR +} + +PDSCH-ConfigDedicated::= SEQUENCE { + p-a ENUMERATED { + dB-6, dB-4dot77, dB-3, dB-1dot77, + dB0, dB1, dB2, dB3} +} + +PDSCH-ConfigDedicated-v1130 ::= SEQUENCE { + dmrs-ConfigPDSCH-r11 DMRS-Config-r11 OPTIONAL, -- Need ON + qcl-Operation ENUMERATED {typeA, typeB} OPTIONAL, -- Need OR + re-MappingQCLConfigToReleaseList-r11 RE-MappingQCLConfigToReleaseList-r11 OPTIONAL, -- Need ON + re-MappingQCLConfigToAddModList-r11 RE-MappingQCLConfigToAddModList-r11 OPTIONAL -- Need ON +} + +PDSCH-ConfigDedicated-v1280 ::= SEQUENCE { + tbsIndexAlt-r12 ENUMERATED {a26, a33} OPTIONAL -- Need OR +} + +PDSCH-ConfigDedicated-v1310 ::= SEQUENCE { + dmrs-ConfigPDSCH-v1310 DMRS-Config-v1310 OPTIONAL -- Need ON +} + +RE-MappingQCLConfigToAddModList-r11 ::= SEQUENCE (SIZE (1..maxRE-MapQCL-r11)) OF PDSCH-RE-MappingQCL-Config-r11 + +RE-MappingQCLConfigToReleaseList-r11 ::= SEQUENCE (SIZE (1..maxRE-MapQCL-r11)) OF PDSCH-RE-MappingQCL-ConfigId-r11 + +PDSCH-RE-MappingQCL-Config-r11 ::= SEQUENCE { + pdsch-RE-MappingQCL-ConfigId-r11 PDSCH-RE-MappingQCL-ConfigId-r11, + optionalSetOfFields-r11 SEQUENCE { + crs-PortsCount-r11 ENUMERATED {n1, n2, n4, spare1}, + crs-FreqShift-r11 INTEGER (0..5), + mbsfn-SubframeConfigList-r11 CHOICE { + release NULL, + setup SEQUENCE { + subframeConfigList MBSFN-SubframeConfigList + } + } OPTIONAL, -- Need ON + pdsch-Start-r11 ENUMERATED {reserved, n1, n2, n3, n4, assigned} + } OPTIONAL, -- Need OP + csi-RS-ConfigZPId-r11 CSI-RS-ConfigZPId-r11, + qcl-CSI-RS-ConfigNZPId-r11 CSI-RS-ConfigNZPId-r11 OPTIONAL, -- Need OR + ... +} + + +PDSCH-RE-MappingQCL-ConfigId-r11 ::= INTEGER (1..maxRE-MapQCL-r11) + + +PHICH-Config ::= SEQUENCE { + phich-Duration ENUMERATED {normal, extended}, + phich-Resource ENUMERATED {oneSixth, half, one, two} +} + + +PhysicalConfigDedicated ::= SEQUENCE { + pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON + pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON + pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON + uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON + tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON + tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON + cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Cond CQI-r8 + soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON + antennaInfo CHOICE { + explicitValue AntennaInfoDedicated, + defaultValue NULL + } OPTIONAL, -- Cond AI-r8 + schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON + ..., + [[ cqi-ReportConfig-v920 CQI-ReportConfig-v920 OPTIONAL, -- Cond CQI-r8 + antennaInfo-v920 AntennaInfoDedicated-v920 OPTIONAL -- Cond AI-r8 + ]], + [[ antennaInfo-r10 CHOICE { + explicitValue-r10 AntennaInfoDedicated-r10, + defaultValue NULL + } OPTIONAL, -- Cond AI-r10 + antennaInfoUL-r10 AntennaInfoUL-r10 OPTIONAL, -- Need ON + cif-Presence-r10 BOOLEAN OPTIONAL, -- Need ON + cqi-ReportConfig-r10 CQI-ReportConfig-r10 OPTIONAL, -- Cond CQI-r10 + csi-RS-Config-r10 CSI-RS-Config-r10 OPTIONAL, -- Need ON + pucch-ConfigDedicated-v1020 PUCCH-ConfigDedicated-v1020 OPTIONAL, -- Need ON + pusch-ConfigDedicated-v1020 PUSCH-ConfigDedicated-v1020 OPTIONAL, -- Need ON + schedulingRequestConfig-v1020 SchedulingRequestConfig-v1020 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicated-v1020 + SoundingRS-UL-ConfigDedicated-v1020 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedAperiodic-r10 + SoundingRS-UL-ConfigDedicatedAperiodic-r10 OPTIONAL, -- Need ON + uplinkPowerControlDedicated-v1020 + UplinkPowerControlDedicated-v1020 OPTIONAL -- Need ON + ]], + [[ additionalSpectrumEmissionCA-r10 CHOICE { + release NULL, + setup SEQUENCE { + additionalSpectrumEmissionPCell-r10 AdditionalSpectrumEmission + } + } OPTIONAL -- Need ON + ]], + [[ -- DL configuration as well as configuration applicable for DL and UL + csi-RS-ConfigNZPToReleaseList-r11 + CSI-RS-ConfigNZPToReleaseList-r11 OPTIONAL, -- Need ON + csi-RS-ConfigNZPToAddModList-r11 + CSI-RS-ConfigNZPToAddModList-r11 OPTIONAL, -- Need ON + csi-RS-ConfigZPToReleaseList-r11 + CSI-RS-ConfigZPToReleaseList-r11 OPTIONAL, -- Need ON + csi-RS-ConfigZPToAddModList-r11 CSI-RS-ConfigZPToAddModList-r11 OPTIONAL, -- Need ON + epdcch-Config-r11 EPDCCH-Config-r11 OPTIONAL, -- Need ON + pdsch-ConfigDedicated-v1130 PDSCH-ConfigDedicated-v1130 OPTIONAL, -- Need ON + -- UL configuration + cqi-ReportConfig-v1130 CQI-ReportConfig-v1130 OPTIONAL, -- Need ON + pucch-ConfigDedicated-v1130 PUCCH-ConfigDedicated-v1130 OPTIONAL, -- Need ON + pusch-ConfigDedicated-v1130 PUSCH-ConfigDedicated-v1130 OPTIONAL, -- Need ON + uplinkPowerControlDedicated-v1130 + UplinkPowerControlDedicated-v1130 OPTIONAL -- Need ON + ]], + [[ antennaInfo-v1250 AntennaInfoDedicated-v1250 OPTIONAL, -- Cond AI-r10 + eimta-MainConfig-r12 EIMTA-MainConfig-r12 OPTIONAL, -- Need ON + eimta-MainConfigPCell-r12 EIMTA-MainConfigServCell-r12 OPTIONAL, -- Need ON + pucch-ConfigDedicated-v1250 PUCCH-ConfigDedicated-v1250 OPTIONAL, -- Need ON + cqi-ReportConfigPCell-v1250 CQI-ReportConfig-v1250 OPTIONAL, -- Need ON + uplinkPowerControlDedicated-v1250 + UplinkPowerControlDedicated-v1250 OPTIONAL, -- Need ON + pusch-ConfigDedicated-v1250 PUSCH-ConfigDedicated-v1250 OPTIONAL, -- Need ON + csi-RS-Config-v1250 CSI-RS-Config-v1250 OPTIONAL -- Need ON + ]], + [[ pdsch-ConfigDedicated-v1280 PDSCH-ConfigDedicated-v1280 OPTIONAL -- Need ON + ]], + [[ pdsch-ConfigDedicated-v1310 PDSCH-ConfigDedicated-v1310 OPTIONAL, -- Need ON + pucch-ConfigDedicated-r13 PUCCH-ConfigDedicated-r13 OPTIONAL, -- Need ON + pusch-ConfigDedicated-r13 PUSCH-ConfigDedicated-r13 OPTIONAL, -- Need ON + pdcch-CandidateReductions-r13 + PDCCH-CandidateReductions-r13 OPTIONAL, -- Need ON + cqi-ReportConfig-v1310 CQI-ReportConfig-v1310 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicated-v1310 + SoundingRS-UL-ConfigDedicated-v1310 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedUpPTsExt-r13 + SoundingRS-UL-ConfigDedicatedUpPTsExt-r13 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedAperiodic-v1310 + SoundingRS-UL-ConfigDedicatedAperiodic-v1310 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedAperiodicUpPTsExt-r13 + SoundingRS-UL-ConfigDedicatedAperiodicUpPTsExt-r13 OPTIONAL, -- Need ON + csi-RS-Config-v1310 CSI-RS-Config-v1310 OPTIONAL, -- Need ON + ce-Mode-r13 CHOICE { + release NULL, + setup ENUMERATED {ce-ModeA,ce-ModeB} + } OPTIONAL, -- Need ON + csi-RS-ConfigNZPToAddModListExt-r13 CSI-RS-ConfigNZPToAddModListExt-r13 OPTIONAL, -- Need ON + csi-RS-ConfigNZPToReleaseListExt-r13 CSI-RS-ConfigNZPToReleaseListExt-r13 OPTIONAL -- Need ON + ]], + [[ cqi-ReportConfig-v1320 CQI-ReportConfig-v1320 OPTIONAL -- Need ON + ]], + [[ typeA-SRS-TPC-PDCCH-Group-r14 SEQUENCE (SIZE (1..32)) OF SRS-TPC-PDCCH-Config-r14 OPTIONAL, -- Need ON + must-Config-r14 CHOICE{ + release NULL, + setup SEQUENCE { + k-max-r14 ENUMERATED {l1, l3}, + p-a-must-r14 ENUMERATED { + dB-6, dB-4dot77, dB-3, dB-1dot77, + dB0, dB1, dB2, dB3} OPTIONAL -- Need ON + } + } OPTIONAL -- Need ON + ]] + +} + +PhysicalConfigDedicatedSCell-r10 ::= SEQUENCE { + -- DL configuration as well as configuration applicable for DL and UL + nonUL-Configuration-r10 SEQUENCE { + antennaInfo-r10 + AntennaInfoDedicated-r10 OPTIONAL, -- Need ON + crossCarrierSchedulingConfig-r10 + CrossCarrierSchedulingConfig-r10 OPTIONAL, -- Need ON + csi-RS-Config-r10 CSI-RS-Config-r10 OPTIONAL, -- Need ON + pdsch-ConfigDedicated-r10 PDSCH-ConfigDedicated OPTIONAL -- Need ON + } OPTIONAL, -- Cond SCellAdd + -- UL configuration + ul-Configuration-r10 SEQUENCE { + antennaInfoUL-r10 AntennaInfoUL-r10 OPTIONAL, -- Need ON + pusch-ConfigDedicatedSCell-r10 + PUSCH-ConfigDedicatedSCell-r10 OPTIONAL, -- Cond PUSCH-SCell1 + uplinkPowerControlDedicatedSCell-r10 + UplinkPowerControlDedicatedSCell-r10 OPTIONAL, -- Need ON + cqi-ReportConfigSCell-r10 CQI-ReportConfigSCell-r10 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicated-r10 + SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicated-v1020 + SoundingRS-UL-ConfigDedicated-v1020 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedAperiodic-r10 + SoundingRS-UL-ConfigDedicatedAperiodic-r10 OPTIONAL -- Need ON + } OPTIONAL, -- Cond CommonUL + ..., + [[ -- DL configuration as well as configuration applicable for DL and UL + csi-RS-ConfigNZPToReleaseList-r11 + CSI-RS-ConfigNZPToReleaseList-r11 OPTIONAL, -- Need ON + csi-RS-ConfigNZPToAddModList-r11 + CSI-RS-ConfigNZPToAddModList-r11 OPTIONAL, -- Need ON + csi-RS-ConfigZPToReleaseList-r11 + CSI-RS-ConfigZPToReleaseList-r11 OPTIONAL, -- Need ON + csi-RS-ConfigZPToAddModList-r11 + CSI-RS-ConfigZPToAddModList-r11 OPTIONAL, -- Need ON + epdcch-Config-r11 EPDCCH-Config-r11 OPTIONAL, -- Need ON + pdsch-ConfigDedicated-v1130 PDSCH-ConfigDedicated-v1130 OPTIONAL, -- Need ON + -- UL configuration + cqi-ReportConfig-v1130 CQI-ReportConfig-v1130 OPTIONAL, -- Need ON + pusch-ConfigDedicated-v1130 + PUSCH-ConfigDedicated-v1130 OPTIONAL, -- Cond PUSCH-SCell1 + uplinkPowerControlDedicatedSCell-v1130 + UplinkPowerControlDedicated-v1130 OPTIONAL -- Need ON + ]], + [[ antennaInfo-v1250 AntennaInfoDedicated-v1250 OPTIONAL, -- Need ON + eimta-MainConfigSCell-r12 + EIMTA-MainConfigServCell-r12 OPTIONAL, -- Need ON + cqi-ReportConfigSCell-v1250 CQI-ReportConfig-v1250 OPTIONAL, -- Need ON + uplinkPowerControlDedicatedSCell-v1250 + UplinkPowerControlDedicated-v1250 OPTIONAL, -- Need ON + csi-RS-Config-v1250 CSI-RS-Config-v1250 OPTIONAL -- Need ON + ]], + [[ pdsch-ConfigDedicated-v1280 PDSCH-ConfigDedicated-v1280 OPTIONAL -- Need ON + ]], + [[ pucch-Cell-r13 ENUMERATED {true} OPTIONAL, -- Cond PUCCH-SCell1 + pucch-SCell CHOICE{ + release NULL, + setup SEQUENCE { + pucch-ConfigDedicated-r13 + PUCCH-ConfigDedicated-r13 OPTIONAL, -- Need ON + schedulingRequestConfig-r13 + SchedulingRequestConfigSCell-r13 OPTIONAL, -- Need ON + tpc-PDCCH-ConfigPUCCH-SCell-r13 + TPC-PDCCH-ConfigSCell-r13 OPTIONAL, -- Need ON + pusch-ConfigDedicated-r13 + PUSCH-ConfigDedicated-r13 OPTIONAL, -- Cond PUSCH-SCell + uplinkPowerControlDedicated-r13 + UplinkPowerControlDedicatedSCell-v1310 OPTIONAL -- Need ON + } + } OPTIONAL, -- Need ON + crossCarrierSchedulingConfig-r13 + CrossCarrierSchedulingConfig-r13 OPTIONAL, -- Cond Cross-Carrier-Config + pdcch-ConfigSCell-r13 PDCCH-ConfigSCell-r13 OPTIONAL, -- Need ON + cqi-ReportConfig-v1310 CQI-ReportConfig-v1310 OPTIONAL, -- Need ON + pdsch-ConfigDedicated-v1310 PDSCH-ConfigDedicated-v1310 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicated-v1310 + SoundingRS-UL-ConfigDedicated-v1310 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedUpPTsExt-r13 + SoundingRS-UL-ConfigDedicatedUpPTsExt-r13 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedAperiodic-v1310 + SoundingRS-UL-ConfigDedicatedAperiodic-v1310 OPTIONAL, -- Need ON + soundingRS-UL-ConfigDedicatedAperiodicUpPTsExt-r13 + SoundingRS-UL-ConfigDedicatedAperiodicUpPTsExt-r13 OPTIONAL, -- Need ON + csi-RS-Config-v1310 CSI-RS-Config-v1310 OPTIONAL, -- Need ON + laa-SCellConfiguration-r13 LAA-SCellConfiguration-r13 OPTIONAL, -- Need ON + csi-RS-ConfigNZPToAddModListExt-r13 CSI-RS-ConfigNZPToAddModListExt-r13 OPTIONAL, -- Need ON + csi-RS-ConfigNZPToReleaseListExt-r13 CSI-RS-ConfigNZPToReleaseListExt-r13 OPTIONAL -- Need ON + ]], + [[ cqi-ReportConfig-v1320 CQI-ReportConfig-v1320 OPTIONAL -- Need ON + ]], + [[ laa-SCellConfiguration-v14xy LAA-SCellConfiguration-v14xy OPTIONAL, -- Need ON + typeB-SRS-TPC-PDCCH-Config-r14 SRS-TPC-PDCCH-Config-r14 OPTIONAL, -- Need ON + + uplinkPUSCH-LessPowerControlDedicated-v14xy UplinkPUSCH-LessPowerControlDedicated-v14xy OPTIONAL, -- Need ON + soundingRS-UL-PeriodicConfigDedicatedList-r14 SEQUENCE (SIZE (1..2)) OF SoundingRS-UL-ConfigDedicated OPTIONAL, -- Cond PeriodicSRS + soundingRS-UL-PeriodicConfigDedicatedUpPTsExtList-r14 SEQUENCE (SIZE (1..4)) OF SoundingRS-UL-ConfigDedicatedUpPTsExt-r13 OPTIONAL, -- Cond PeriodicSRSExt + + soundingRS-UL-AperiodicConfigDedicatedList-r14 SEQUENCE (SIZE (1..2)) OF SoundingRSAperiodicGroup-r14 OPTIONAL, -- Cond AperiodicSRS + soundingRS-UL-AperiodicConfigDedicatedUpPTsExtList-r14 SEQUENCE (SIZE (1..4)) OF SoundingRSAperiodicGroupUpPTsExt-r14 OPTIONAL, -- Cond AperiodicSRSExt + + must-Config-r14 CHOICE{ + release NULL, + setup SEQUENCE { + k-max-r14 ENUMERATED {l1, l3}, + p-a-must-r14 ENUMERATED { + dB-6, dB-4dot77, dB-3, dB-1dot77, + dB0, dB1, dB2, dB3} OPTIONAL -- Need ON + } + } OPTIONAL -- Need ON + ]] +} + +LAA-SCellConfiguration-r13 ::= SEQUENCE { + subframeStartPosition-r13 ENUMERATED {s0, s07}, + laa-SCellSubframeConfig-r13 BIT STRING (SIZE(8)) +} + +LAA-SCellConfiguration-v14xy ::= SEQUENCE { + crossCarrierSchedulingConfig-UL-r14 CHOICE { + release NULL, + setup SEQUENCE { + crossCarrierSchedulingConfigLAA-UL-r14 CrossCarrierSchedulingConfigLAA-UL-r14 + } + } OPTIONAL, -- Cond Cross-Carrier-ConfigUL + lbt-Config-r14 LBT-Config-r14 OPTIONAL, -- Need ON + pdcch-ConfigLAA-r14 PDCCH-ConfigLAA-r14 OPTIONAL, -- Need ON + absenceOfAnyOtherTechnology-r14 ENUMERATED {true} OPTIONAL, -- Need OR + soundingRS-UL-ConfigDedicatedAperiodic-v14xy + SoundingRS-UL-ConfigDedicatedAperiodic-v14xy OPTIONAL -- Need ON +} + +LBT-Config-r14 ::= CHOICE{ + maxEnergyDetectionThreshold-r14 INTEGER(-85..-52), + energyDetectionThresholdOffset-r14 INTEGER(-13..20) +} + +CSI-RS-ConfigNZPToAddModList-r11 ::= SEQUENCE (SIZE (1..maxCSI-RS-NZP-r11)) OF CSI-RS-ConfigNZP-r11 + +CSI-RS-ConfigNZPToAddModListExt-r13 ::= SEQUENCE (SIZE (1..maxCSI-RS-NZP-v1310)) OF CSI-RS-ConfigNZP-r11 + +CSI-RS-ConfigNZPToReleaseList-r11 ::= SEQUENCE (SIZE (1..maxCSI-RS-NZP-r11)) OF CSI-RS-ConfigNZPId-r11 + +CSI-RS-ConfigNZPToReleaseListExt-r13 ::= SEQUENCE (SIZE (1..maxCSI-RS-NZP-v1310)) OF CSI-RS-ConfigNZPId-v1310 + +CSI-RS-ConfigZPToAddModList-r11 ::= SEQUENCE (SIZE (1..maxCSI-RS-ZP-r11)) OF CSI-RS-ConfigZP-r11 + +CSI-RS-ConfigZPToReleaseList-r11 ::= SEQUENCE (SIZE (1..maxCSI-RS-ZP-r11)) OF CSI-RS-ConfigZPId-r11 + +SoundingRSAperiodicGroup-r14 ::= SEQUENCE{ + srsCcGroupIndexList SEQUENCE (SIZE (1..4)) OF SrsCcGroupIndex OPTIONAL, -- Cond Srs-Trigger-TypeA + soundingRS-UL-ConfigDedicatedAperiodic-r10 SoundingRS-UL-ConfigDedicatedAperiodic-r10 +} + +SoundingRSAperiodicGroupUpPTsExt-r14 ::= SEQUENCE{ + srsCcGroupIndexList SEQUENCE (SIZE (1..4)) OF SrsCcGroupIndex OPTIONAL, -- Cond Srs-Trigger-TypeA + soundingRS-UL-ConfigDedicatedAperiodicUpPTsExt-r13 SoundingRS-UL-ConfigDedicatedAperiodicUpPTsExt-r13 +} + + +P-Max ::= INTEGER (-30..33) + + +PRACH-ConfigSIB ::= SEQUENCE { + rootSequenceIndex INTEGER (0..837), + prach-ConfigInfo PRACH-ConfigInfo +} + +PRACH-ConfigSIB-v1310 ::= SEQUENCE { + rsrp-ThresholdsPrachInfoList-r13 RSRP-ThresholdsPrachInfoList-r13, + mpdcch-startSF-CSS-RA-r13 CHOICE { + fdd-r13 ENUMERATED {v1, v1dot5, v2, v2dot5, v4, v5, v8, + v10}, + tdd-r13 ENUMERATED {v1, v2, v4, v5, v8, v10, v20, spare} + } OPTIONAL, -- Cond MP + prach-HoppingOffset-r13 INTEGER (0..94) OPTIONAL, -- Need OR + prach-ParametersListCE-r13 PRACH-ParametersListCE-r13 +} + +PRACH-Config ::= SEQUENCE { + rootSequenceIndex INTEGER (0..837), + prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON +} + +PRACH-Config-v1310 ::= SEQUENCE { + rsrp-ThresholdsPrachInfoList-r13 RSRP-ThresholdsPrachInfoList-r13 OPTIONAL, -- Cond HO + mpdcch-startSF-CSS-RA-r13 CHOICE { + fdd-r13 ENUMERATED {v1, v1dot5, v2, v2dot5, v4, v5, v8, + v10}, + tdd-r13 ENUMERATED {v1, v2, v4, v5, v8, v10, v20, spare} + } OPTIONAL, -- Cond MP + prach-HoppingOffset-r13 INTEGER (0..94) OPTIONAL, -- Need OR + prach-ParametersListCE-r13 PRACH-ParametersListCE-r13 OPTIONAL, -- Cond MP + initial-CE-level-r13 INTEGER (0..3) OPTIONAL -- Need OR +} + +PRACH-Config-v14xy ::= SEQUENCE { + rootSequenceIndexHighSpeed-r14 INTEGER (0..837), + zeroCorrelationZoneConfigHighSpeed-r14 INTEGER (0..12) +} + +PRACH-ConfigSCell-r10 ::= SEQUENCE { + prach-ConfigIndex-r10 INTEGER (0..63) +} + +PRACH-ConfigInfo ::= SEQUENCE { + prach-ConfigIndex INTEGER (0..63), + highSpeedFlag BOOLEAN, + zeroCorrelationZoneConfig INTEGER (0..15), + prach-FreqOffset INTEGER (0..94) +} + +PRACH-ParametersListCE-r13 ::= SEQUENCE (SIZE(1..maxCE-Level-r13)) OF PRACH-ParametersCE-r13 + +PRACH-ParametersCE-r13 ::= SEQUENCE { + prach-ConfigIndex-r13 INTEGER (0..63), + prach-FreqOffset-r13 INTEGER (0..94), + prach-StartingSubframe-r13 ENUMERATED {sf2, sf4, sf8, sf16, sf32, sf64, sf128, + sf256} OPTIONAL, -- Need OP + maxNumPreambleAttemptCE-r13 + ENUMERATED {n3, n4, n5, n6, n7, n8, n10} OPTIONAL, -- Need OP + numRepetitionPerPreambleAttempt-r13 ENUMERATED {n1,n2,n4,n8,n16,n32,n64,n128}, + mpdcch-NarrowbandsToMonitor-r13 SEQUENCE (SIZE(1..2)) OF + INTEGER (1..maxAvailNarrowBands-r13), + mpdcch-NumRepetition-RA-r13 ENUMERATED {r1, r2, r4, r8, r16, + r32, r64, r128, r256}, + prach-HoppingConfig-r13 ENUMERATED {on,off} +} + +RSRP-ThresholdsPrachInfoList-r13 ::= SEQUENCE (SIZE(1..3)) OF RSRP-Range + + +PresenceAntennaPort1 ::= BOOLEAN + + +PUCCH-ConfigCommon ::= SEQUENCE { + deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3}, + nRB-CQI INTEGER (0..98), + nCS-AN INTEGER (0..7), + n1PUCCH-AN INTEGER (0..2047) +} + +PUCCH-ConfigCommon-v1310 ::= SEQUENCE { + n1PUCCH-AN-InfoList-r13 N1PUCCH-AN-InfoList-r13 OPTIONAL, -- Need OR + pucch-NumRepetitionCE-Msg4-Level0-r13 ENUMERATED {n1, n2, n4, n8} OPTIONAL, -- Need OR + pucch-NumRepetitionCE-Msg4-Level1-r13 ENUMERATED {n1, n2, n4, n8} OPTIONAL, -- Need OR + pucch-NumRepetitionCE-Msg4-Level2-r13 ENUMERATED {n4, n8, n16, n32} OPTIONAL, -- Need OR + pucch-NumRepetitionCE-Msg4-Level3-r13 ENUMERATED {n4, n8, n16, n32} OPTIONAL -- Need OR +} + +PUCCH-ConfigDedicated ::= SEQUENCE { + ackNackRepetition CHOICE{ + release NULL, + setup SEQUENCE { + repetitionFactor ENUMERATED {n2, n4, n6, spare1}, + n1PUCCH-AN-Rep INTEGER (0..2047) + } + }, + tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD +} + +PUCCH-ConfigDedicated-v1020 ::= SEQUENCE { + pucch-Format-r10 CHOICE { + format3-r10 SEQUENCE { + n3PUCCH-AN-List-r10 SEQUENCE (SIZE (1..4)) OF INTEGER (0..549) OPTIONAL, -- Need ON + twoAntennaPortActivatedPUCCH-Format3-r10 CHOICE { + release NULL, + setup SEQUENCE { + n3PUCCH-AN-ListP1-r10 SEQUENCE (SIZE (1..4)) OF INTEGER (0..549) + } + } OPTIONAL -- Need ON + }, + channelSelection-r10 SEQUENCE { + n1PUCCH-AN-CS-r10 CHOICE { + release NULL, + setup SEQUENCE { + n1PUCCH-AN-CS-List-r10 SEQUENCE (SIZE (1..2)) OF N1PUCCH-AN-CS-r10 + } + } OPTIONAL -- Need ON + } + } OPTIONAL, -- Need OR + twoAntennaPortActivatedPUCCH-Format1a1b-r10 ENUMERATED {true} OPTIONAL, -- Need OR + simultaneousPUCCH-PUSCH-r10 ENUMERATED {true} OPTIONAL, -- Need OR + n1PUCCH-AN-RepP1-r10 INTEGER (0..2047) OPTIONAL -- Need OR +} + +PUCCH-ConfigDedicated-v1130 ::= SEQUENCE { + n1PUCCH-AN-CS-v1130 CHOICE { + release NULL, + setup SEQUENCE { + n1PUCCH-AN-CS-ListP1-r11 SEQUENCE (SIZE (2..4)) OF INTEGER (0..2047) + } + } OPTIONAL, -- Need ON + nPUCCH-Param-r11 CHOICE { + release NULL, + setup SEQUENCE { + nPUCCH-Identity-r11 INTEGER (0..503), + n1PUCCH-AN-r11 INTEGER (0..2047) + } + } OPTIONAL -- Need ON +} + +PUCCH-ConfigDedicated-v1250 ::= SEQUENCE { + nkaPUCCH-Param-r12 CHOICE { + release NULL, + setup SEQUENCE { + nkaPUCCH-AN-r12 INTEGER (0..2047) + } + } +} + +PUCCH-ConfigDedicated-r13 ::= SEQUENCE { +--Release 8 + ackNackRepetition-r13 CHOICE{ + release NULL, + setup SEQUENCE { + repetitionFactor-r13 ENUMERATED {n2, n4, n6, spare1}, + n1PUCCH-AN-Rep-r13 INTEGER (0..2047) + } + }, + tdd-AckNackFeedbackMode-r13 ENUMERATED {bundling, multiplexing} OPTIONAL, -- Cond TDD +--Release 10 + pucch-Format-r13 CHOICE { + format3-r13 SEQUENCE { + n3PUCCH-AN-List-r13 SEQUENCE (SIZE (1..4)) OF INTEGER (0..549) OPTIONAL, -- Need ON + twoAntennaPortActivatedPUCCH-Format3-r13 CHOICE { + release NULL, + setup SEQUENCE { + n3PUCCH-AN-ListP1-r13 SEQUENCE (SIZE (1..4)) OF INTEGER (0..549) + } + } OPTIONAL -- Need ON + }, + channelSelection-r13 SEQUENCE { + n1PUCCH-AN-CS-r13 CHOICE { + release NULL, + setup SEQUENCE { + n1PUCCH-AN-CS-List-r13 SEQUENCE (SIZE (1..2)) OF N1PUCCH-AN-CS-r10, + n1PUCCH-AN-CS-ListP1-r13 SEQUENCE (SIZE (2..4)) OF INTEGER (0..2047) + } + } OPTIONAL -- Need ON + }, + format4-r13 SEQUENCE { + format4-resourceConfiguration-r13 SEQUENCE (SIZE (4)) OF Format4-resource-r13, + format4-MultiCSI-resourceConfiguration-r13 SEQUENCE (SIZE (1..2)) OF Format4-resource-r13 OPTIONAL -- Need OR + }, + format5-r13 SEQUENCE { + format5-resourceConfiguration-r13 SEQUENCE (SIZE (4)) OF Format5-resource-r13, + format5-MultiCSI-resourceConfiguration-r13 Format5-resource-r13 OPTIONAL -- Need OR + } + } OPTIONAL, -- Need OR + twoAntennaPortActivatedPUCCH-Format1a1b-r13 ENUMERATED {true} OPTIONAL, -- Need OR + simultaneousPUCCH-PUSCH-r13 ENUMERATED {true} OPTIONAL, -- Need OR + n1PUCCH-AN-RepP1-r13 INTEGER (0..2047) OPTIONAL, -- Need OR +--Release 11 + nPUCCH-Param-r13 CHOICE { + release NULL, + setup SEQUENCE { + nPUCCH-Identity-r13 INTEGER (0..503), + n1PUCCH-AN-r13 INTEGER (0..2047) + } + } OPTIONAL, -- Need ON +--Release 12 + nkaPUCCH-Param-r13 CHOICE { + release NULL, + setup SEQUENCE { + nkaPUCCH-AN-r13 INTEGER (0..2047) + } + } OPTIONAL, -- Need ON +--Release 13 + spatialBundlingPUCCH-r13 BOOLEAN, + spatialBundlingPUSCH-r13 BOOLEAN, + harq-TimingTDD-r13 BOOLEAN, + codebooksizeDetermination-r13 ENUMERATED {dai,cc} OPTIONAL, -- Need OR + maximumPayloadCoderate-r13 INTEGER (0..7) OPTIONAL, -- Need OR + pucch-NumRepetitionCE-r13 CHOICE { + release NULL, + setup CHOICE { + modeA SEQUENCE { + pucch-NumRepetitionCE-format1-r13 ENUMERATED {r1, r2, r4, r8}, + pucch-NumRepetitionCE-format2-r13 ENUMERATED {r1, r2, r4, r8} + }, + modeB SEQUENCE { + pucch-NumRepetitionCE-format1-r13 ENUMERATED {r4, r8, r16, r32}, + pucch-NumRepetitionCE-format2-r13 ENUMERATED {r4, r8, r16, r32} + } + } + } OPTIONAL --Need ON +} + +Format4-resource-r13 ::= SEQUENCE { + startingPRB-format4-r13 INTEGER (0..109), + numberOfPRB-format4-r13 INTEGER (0..7) +} + +Format5-resource-r13 ::= SEQUENCE { + startingPRB-format5-r13 INTEGER (0..109), + cdm-index-format5-r13 INTEGER (0..1) +} + + + +N1PUCCH-AN-CS-r10 ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047) + +N1PUCCH-AN-InfoList-r13 ::= SEQUENCE (SIZE(1..maxCE-Level-r13)) OF INTEGER (0..2047) + + +PUSCH-ConfigCommon ::= SEQUENCE { + pusch-ConfigBasic SEQUENCE { + n-SB INTEGER (1..4), + hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame}, + pusch-HoppingOffset INTEGER (0..98), + enable64QAM BOOLEAN + }, + ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH +} + +PUSCH-ConfigCommon-v1270 ::= SEQUENCE { + enable64QAM-v1270 ENUMERATED {true} +} + +PUSCH-ConfigCommon-v1310 ::= SEQUENCE { + pusch-maxNumRepetitionCEmodeA-r13 ENUMERATED { + r8, r16, r32 } OPTIONAL, -- Need OR + pusch-maxNumRepetitionCEmodeB-r13 ENUMERATED { + r192, r256, r384, r512, r768, r1024, + r1536, r2048} OPTIONAL, -- Need OR + pusch-HoppingOffset-v1310 + INTEGER (1..maxAvailNarrowBands-r13) OPTIONAL -- Need OR +} + +PUSCH-ConfigDedicated ::= SEQUENCE { + betaOffset-ACK-Index INTEGER (0..15), + betaOffset-RI-Index INTEGER (0..15), + betaOffset-CQI-Index INTEGER (0..15) +} + +PUSCH-ConfigDedicated-v1020 ::= SEQUENCE { + betaOffsetMC-r10 SEQUENCE { + betaOffset-ACK-Index-MC-r10 INTEGER (0..15), + betaOffset-RI-Index-MC-r10 INTEGER (0..15), + betaOffset-CQI-Index-MC-r10 INTEGER (0..15) + } OPTIONAL, -- Need OR + groupHoppingDisabled-r10 ENUMERATED {true} OPTIONAL, -- Need OR + dmrs-WithOCC-Activated-r10 ENUMERATED {true} OPTIONAL -- Need OR +} + +PUSCH-ConfigDedicated-v1130 ::= SEQUENCE { + pusch-DMRS-r11 CHOICE { + release NULL, + setup SEQUENCE { + nPUSCH-Identity-r11 INTEGER (0..509), + nDMRS-CSH-Identity-r11 INTEGER (0..509) + } + } +} + +PUSCH-ConfigDedicated-v1250::= SEQUENCE { + uciOnPUSCH CHOICE { + release NULL, + setup SEQUENCE { + betaOffset-ACK-Index-SubframeSet2-r12 INTEGER (0..15), + betaOffset-RI-Index-SubframeSet2-r12 INTEGER (0..15), + betaOffset-CQI-Index-SubframeSet2-r12 INTEGER (0..15), + betaOffsetMC-r12 SEQUENCE { + betaOffset-ACK-Index-MC-SubframeSet2-r12 INTEGER (0..15), + betaOffset-RI-Index-MC-SubframeSet2-r12 INTEGER (0..15), + betaOffset-CQI-Index-MC-SubframeSet2-r12 INTEGER (0..15) + } OPTIONAL -- Need OR + } + } +} +PUSCH-ConfigDedicated-r13 ::= SEQUENCE { + betaOffset-ACK-Index-r13 INTEGER (0..15), + betaOffset2-ACK-Index-r13 INTEGER (0..15) OPTIONAL, -- Need OR + betaOffset-RI-Index-r13 INTEGER (0..15), + betaOffset-CQI-Index-r13 INTEGER (0..15), + betaOffsetMC-r13 SEQUENCE { + betaOffset-ACK-Index-MC-r13 INTEGER (0..15), + betaOffset2-ACK-Index-MC-r13 INTEGER (0..15) OPTIONAL, -- Need OR + betaOffset-RI-Index-MC-r13 INTEGER (0..15), + betaOffset-CQI-Index-MC-r13 INTEGER (0..15) + } OPTIONAL, -- Need OR + groupHoppingDisabled-r13 ENUMERATED {true} OPTIONAL, -- Need OR + dmrs-WithOCC-Activated-r13 ENUMERATED {true} OPTIONAL, -- Need OR + pusch-DMRS-r11 CHOICE { + release NULL, + setup SEQUENCE { + nPUSCH-Identity-r13 INTEGER (0..509), + nDMRS-CSH-Identity-r13 INTEGER (0..509) + } + } OPTIONAL, -- Need ON + uciOnPUSCH CHOICE { + release NULL, + setup SEQUENCE { + betaOffset-ACK-Index-SubframeSet2-r13 INTEGER (0..15), + betaOffset2-ACK-Index-SubframeSet2-r13 INTEGER (0..15) OPTIONAL, -- Need OR + betaOffset-RI-Index-SubframeSet2-r13 INTEGER (0..15), + betaOffset-CQI-Index-SubframeSet2-r13 INTEGER (0..15), + betaOffsetMC-r12 SEQUENCE { + betaOffset-ACK-Index-MC-SubframeSet2-r13 INTEGER (0..15), + betaOffset2-ACK-Index-MC-SubframeSet2-r13 INTEGER (0..15) OPTIONAL, -- Need OR + betaOffset-RI-Index-MC-SubframeSet2-r13 INTEGER (0..15), + betaOffset-CQI-Index-MC-SubframeSet2-r13 INTEGER (0..15) + } OPTIONAL -- Need OR + } + } OPTIONAL, -- Need ON + pusch-HoppingConfig-r13 ENUMERATED {on} OPTIONAL -- Need OR +} + +PUSCH-ConfigDedicatedSCell-r10 ::= SEQUENCE { + groupHoppingDisabled-r10 ENUMERATED {true} OPTIONAL, -- Need OR + dmrs-WithOCC-Activated-r10 ENUMERATED {true} OPTIONAL -- Need OR +} + +UL-ReferenceSignalsPUSCH ::= SEQUENCE { + groupHoppingEnabled BOOLEAN, + groupAssignmentPUSCH INTEGER (0..29), + sequenceHoppingEnabled BOOLEAN, + cyclicShift INTEGER (0..7) +} + + +RACH-ConfigCommon ::= SEQUENCE { + preambleInfo SEQUENCE { + numberOfRA-Preambles ENUMERATED { + n4, n8, n12, n16, n20, n24, n28, + n32, n36, n40, n44, n48, n52, n56, + n60, n64}, + preamblesGroupAConfig SEQUENCE { + sizeOfRA-PreamblesGroupA ENUMERATED { + n4, n8, n12, n16, n20, n24, n28, + n32, n36, n40, n44, n48, n52, n56, + n60}, + messageSizeGroupA ENUMERATED {b56, b144, b208, b256}, + messagePowerOffsetGroupB ENUMERATED { + minusinfinity, dB0, dB5, dB8, dB10, dB12, + dB15, dB18}, + ... + } OPTIONAL -- Need OP + }, + powerRampingParameters PowerRampingParameters, + ra-SupervisionInfo SEQUENCE { + preambleTransMax PreambleTransMax, + ra-ResponseWindowSize ENUMERATED { + sf2, sf3, sf4, sf5, sf6, sf7, + sf8, sf10}, + mac-ContentionResolutionTimer ENUMERATED { + sf8, sf16, sf24, sf32, sf40, sf48, + sf56, sf64} + }, + maxHARQ-Msg3Tx INTEGER (1..8), + ..., + [[ preambleTransMax-CE-r13 PreambleTransMax OPTIONAL, -- Need OR + rach-CE-LevelInfoList-r13 RACH-CE-LevelInfoList-r13 OPTIONAL -- Need OR + ]] +} + +RACH-ConfigCommon-v1250 ::= SEQUENCE { + txFailParams-r12 SEQUENCE { + connEstFailCount-r12 ENUMERATED {n1, n2, n3, n4}, + connEstFailOffsetValidity-r12 ENUMERATED {s30, s60, s120, s240, + s300, s420, s600, s900}, + connEstFailOffset-r12 INTEGER (0..15) OPTIONAL -- Need OP + } +} + +RACH-ConfigCommonSCell-r11 ::= SEQUENCE { + powerRampingParameters-r11 PowerRampingParameters, + ra-SupervisionInfo-r11 SEQUENCE { + preambleTransMax-r11 PreambleTransMax + }, + ... +} + +RACH-CE-LevelInfoList-r13 ::= SEQUENCE (SIZE (1..maxCE-Level-r13)) OF RACH-CE-LevelInfo-r13 + +RACH-CE-LevelInfo-r13 ::= SEQUENCE { + preambleMappingInfo-r13 SEQUENCE { + firstPreamble-r13 INTEGER(0..63), + lastPreamble-r13 INTEGER(0..63) + }, + ra-ResponseWindowSize-r13 ENUMERATED {sf20, sf50, sf80, sf120, sf180, + sf240, sf320, sf400}, + + mac-ContentionResolutionTimer-r13 ENUMERATED {sf80, sf100, sf120, + sf160, sf200, sf240, sf480, sf960}, + rar-HoppingConfig-r13 ENUMERATED {on,off}, + ... +} + +PowerRampingParameters ::= SEQUENCE { + powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6}, + preambleInitialReceivedTargetPower ENUMERATED { + dBm-120, dBm-118, dBm-116, dBm-114, dBm-112, + dBm-110, dBm-108, dBm-106, dBm-104, dBm-102, + dBm-100, dBm-98, dBm-96, dBm-94, + dBm-92, dBm-90} +} + +PreambleTransMax ::= ENUMERATED { + n3, n4, n5, n6, n7, n8, n10, n20, n50, + n100, n200} + + +RACH-ConfigDedicated ::= SEQUENCE { + ra-PreambleIndex INTEGER (0..63), + ra-PRACH-MaskIndex INTEGER (0..15) +} + + +RadioResourceConfigCommonSIB ::= SEQUENCE { + rach-ConfigCommon RACH-ConfigCommon, + bcch-Config BCCH-Config, + pcch-Config PCCH-Config, + prach-Config PRACH-ConfigSIB, + pdsch-ConfigCommon PDSCH-ConfigCommon, + pusch-ConfigCommon PUSCH-ConfigCommon, + pucch-ConfigCommon PUCCH-ConfigCommon, + soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon, + uplinkPowerControlCommon UplinkPowerControlCommon, + ul-CyclicPrefixLength UL-CyclicPrefixLength, + ..., + [[ uplinkPowerControlCommon-v1020 UplinkPowerControlCommon-v1020 OPTIONAL -- Need OR + ]], + [[ rach-ConfigCommon-v1250 RACH-ConfigCommon-v1250 OPTIONAL -- Need OR + ]], + [[ pusch-ConfigCommon-v1270 PUSCH-ConfigCommon-v1270 OPTIONAL -- Need OR + ]], + [[ bcch-Config-v1310 BCCH-Config-v1310 OPTIONAL, -- Need OR + pcch-Config-v1310 PCCH-Config-v1310 OPTIONAL, -- Need OR + freqHoppingParameters-r13 FreqHoppingParameters-r13 OPTIONAL, -- Need OR + pdsch-ConfigCommon-v1310 PDSCH-ConfigCommon-v1310 OPTIONAL, -- Need OR + pusch-ConfigCommon-v1310 PUSCH-ConfigCommon-v1310 OPTIONAL, -- Need OR + prach-ConfigCommon-v1310 PRACH-ConfigSIB-v1310 OPTIONAL, -- Need OR + pucch-ConfigCommon-v1310 PUCCH-ConfigCommon-v1310 OPTIONAL -- Need OR + ]], + [[ highSpeedConfig-r14 HighSpeedConfig-r14 OPTIONAL, -- Need OR + prach-Config-v14xy PRACH-Config-v14xy OPTIONAL -- Need OR + ]] +} + +RadioResourceConfigCommon ::= SEQUENCE { + rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON + prach-Config PRACH-Config, + pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON + pusch-ConfigCommon PUSCH-ConfigCommon, + phich-Config PHICH-Config OPTIONAL, -- Need ON + pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON + soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON + uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON + antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON + p-Max P-Max OPTIONAL, -- Need OP + tdd-Config TDD-Config OPTIONAL, -- Cond TDD + ul-CyclicPrefixLength UL-CyclicPrefixLength, + ..., + [[ uplinkPowerControlCommon-v1020 UplinkPowerControlCommon-v1020 OPTIONAL -- Need ON + ]], + [[ tdd-Config-v1130 TDD-Config-v1130 OPTIONAL -- Cond TDD3 + ]], + [[ pusch-ConfigCommon-v1270 PUSCH-ConfigCommon-v1270 OPTIONAL -- Need OR + ]], + [[ + prach-Config-v1310 PRACH-Config-v1310 OPTIONAL, -- Need ON + freqHoppingParameters-r13 FreqHoppingParameters-r13 OPTIONAL, -- Need ON + pdsch-ConfigCommon-v1310 PDSCH-ConfigCommon-v1310 OPTIONAL, -- Need ON + pucch-ConfigCommon-v1310 PUCCH-ConfigCommon-v1310 OPTIONAL, -- Need ON + pusch-ConfigCommon-v1310 PUSCH-ConfigCommon-v1310 OPTIONAL, -- Need ON + uplinkPowerControlCommon-v1310 UplinkPowerControlCommon-v1310 OPTIONAL -- Need ON + ]], + [[ highSpeedConfig-r14 HighSpeedConfig-r14 OPTIONAL, -- Need OR + prach-Config-v14xy PRACH-Config-v14xy OPTIONAL -- Need OR + ]] +} + +RadioResourceConfigCommonPSCell-r12 ::= SEQUENCE { + basicFields-r12 RadioResourceConfigCommonSCell-r10, + pucch-ConfigCommon-r12 PUCCH-ConfigCommon, + rach-ConfigCommon-r12 RACH-ConfigCommon, + uplinkPowerControlCommonPSCell-r12 UplinkPowerControlCommonPSCell-r12, + ..., + [[ uplinkPowerControlCommonPSCell-v1310 + UplinkPowerControlCommon-v1310 OPTIONAL -- Need ON + ]] +} + +RadioResourceConfigCommonSCell-r10 ::= SEQUENCE { + -- DL configuration as well as configuration applicable for DL and UL + nonUL-Configuration-r10 SEQUENCE { + -- 1: Cell characteristics + dl-Bandwidth-r10 ENUMERATED {n6, n15, n25, n50, n75, n100}, + -- 2: Physical configuration, general + antennaInfoCommon-r10 AntennaInfoCommon, + mbsfn-SubframeConfigList-r10 MBSFN-SubframeConfigList OPTIONAL, -- Need OR + -- 3: Physical configuration, control + phich-Config-r10 PHICH-Config, + -- 4: Physical configuration, physical channels + pdsch-ConfigCommon-r10 PDSCH-ConfigCommon, + tdd-Config-r10 TDD-Config OPTIONAL -- Cond TDDSCell + }, + -- UL configuration + ul-Configuration-r10 SEQUENCE { + ul-FreqInfo-r10 SEQUENCE { + ul-CarrierFreq-r10 ARFCN-ValueEUTRA OPTIONAL, -- Need OP + ul-Bandwidth-r10 ENUMERATED {n6, n15, + n25, n50, n75, n100} OPTIONAL, -- Need OP + additionalSpectrumEmissionSCell-r10 AdditionalSpectrumEmission + }, + p-Max-r10 P-Max OPTIONAL, -- Need OP + uplinkPowerControlCommonSCell-r10 UplinkPowerControlCommonSCell-r10, + -- A special version of IE UplinkPowerControlCommon may be introduced + -- 3: Physical configuration, control + soundingRS-UL-ConfigCommon-r10 SoundingRS-UL-ConfigCommon, + ul-CyclicPrefixLength-r10 UL-CyclicPrefixLength, + -- 4: Physical configuration, physical channels + prach-ConfigSCell-r10 PRACH-ConfigSCell-r10 OPTIONAL, -- Cond TDD-OR-NoR11 + pusch-ConfigCommon-r10 PUSCH-ConfigCommon + } OPTIONAL, -- Need OR + ..., + [[ ul-CarrierFreq-v1090 ARFCN-ValueEUTRA-v9e0 OPTIONAL -- Need OP + ]], + [[ rach-ConfigCommonSCell-r11 RACH-ConfigCommonSCell-r11 OPTIONAL, -- Cond ULSCell + prach-ConfigSCell-r11 PRACH-Config OPTIONAL, -- Cond UL + tdd-Config-v1130 TDD-Config-v1130 OPTIONAL, -- Cond TDD2 + uplinkPowerControlCommonSCell-v1130 + UplinkPowerControlCommonSCell-v1130 OPTIONAL -- Cond UL + ]], + [[ pusch-ConfigCommon-v1270 PUSCH-ConfigCommon-v1270 OPTIONAL -- Need OR + ]], + [[ pucch-ConfigCommon-r13 PUCCH-ConfigCommon OPTIONAL, -- Cond UL + uplinkPowerControlCommonSCell-v1310 + UplinkPowerControlCommonSCell-v1310 OPTIONAL -- Cond UL + ]], + [[ highSpeedConfigSCell-r14 HighSpeedConfigSCell-r14 OPTIONAL, -- Need OR + prach-Config-v14xy PRACH-Config-v14xy OPTIONAL, -- Cond UL + ul-Configuration-r14 SEQUENCE { + ul-FreqInfo-r14 SEQUENCE { + ul-CarrierFreq-r14 ARFCN-ValueEUTRA-r9 OPTIONAL, -- Need OP + ul-Bandwidth-r14 ENUMERATED {n6, n15, + n25, n50, n75, n100} OPTIONAL, -- Need OP + additionalSpectrumEmissionSCell-r14 AdditionalSpectrumEmission + }, + p-Max-r14 P-Max OPTIONAL, -- Need OP + soundingRS-UL-ConfigCommon-r14 SoundingRS-UL-ConfigCommon, + ul-CyclicPrefixLength-r14 UL-CyclicPrefixLength, + prach-ConfigSCell-r14 PRACH-ConfigSCell-r10 OPTIONAL, -- Cond TDD-OR-NoR11 + uplinkPowerControlCommonPUSCH-LessCell-v14xy UplinkPowerControlCommonPUSCH-LessCell-v14xy OPTIONAL -- Need OR +} OPTIONAL, -- Cond ULSRS + harq-ReferenceConfig-r14 ENUMERATED {sa2,sa4,sa5} OPTIONAL, -- Need OR + soundingRS-FlexibleTiming-r14 ENUMERATED {true} OPTIONAL -- Need OR + ]] +} + +BCCH-Config ::= SEQUENCE { + modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16} +} + +BCCH-Config-v1310 ::= SEQUENCE { + modificationPeriodCoeff-v1310 ENUMERATED {n64} +} + +FreqHoppingParameters-r13 ::= SEQUENCE { + mpdcch-pdsch-HoppingNB-r13 ENUMERATED {nb2, nb4} OPTIONAL, -- Cond HO + interval-DLHoppingConfigCommonModeA-r13 CHOICE { + interval-FDD-r13 ENUMERATED {int1, int2, int4, int8}, + interval-TDD-r13 ENUMERATED {int1, int5, int10, int20} + } OPTIONAL, -- Cond HO + interval-DLHoppingConfigCommonModeB-r13 CHOICE { + interval-FDD-r13 ENUMERATED {int2, int4, int8, int16}, + interval-TDD-r13 ENUMERATED { int5, int10, int20, int40} + } OPTIONAL, -- Cond HO + interval-ULHoppingConfigCommonModeA-r13 CHOICE { + interval-FDD-r13 ENUMERATED {int1, int2, int4, int8}, + interval-TDD-r13 ENUMERATED {int1, int5, int10, int20} + } OPTIONAL, -- Cond MP-A + interval-ULHoppingConfigCommonModeB-r13 CHOICE { + interval-FDD-r13 ENUMERATED {int2, int4, int8, int16}, + interval-TDD-r13 ENUMERATED { int5, int10, int20, int40} + } OPTIONAL, -- Cond MP-B + mpdcch-pdsch-HoppingOffset-r13 INTEGER (1..maxAvailNarrowBands-r13) + OPTIONAL -- Cond HO +} + +PCCH-Config ::= SEQUENCE { + defaultPagingCycle ENUMERATED { + rf32, rf64, rf128, rf256}, + nB ENUMERATED { + fourT, twoT, oneT, halfT, quarterT, oneEighthT, + oneSixteenthT, oneThirtySecondT} +} + +PCCH-Config-v1310 ::= SEQUENCE { + paging-narrowBands-r13 INTEGER (1..maxAvailNarrowBands-r13), + mpdcch-NumRepetition-Paging-r13 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, r128, r256}, + nB-v1310 ENUMERATED {one64thT, one128thT, one256thT} + OPTIONAL -- Need OR +} + +UL-CyclicPrefixLength ::= ENUMERATED {len1, len2} + +HighSpeedConfig-r14 ::= SEQUENCE { + highSpeedEnhancedMeasFlag-r14 ENUMERATED {true} OPTIONAL, -- Need OR + highSpeedEnhancedDemodulationFlag-r14 ENUMERATED {true} OPTIONAL -- Need OR +} + +HighSpeedConfigSCell-r14 ::= SEQUENCE { + highSpeedEnhancedDemodulationFlag-r14 ENUMERATED {true} OPTIONAL -- Need OR +} + + +RadioResourceConfigDedicated ::= SEQUENCE { + srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn + drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA + drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON + mac-MainConfig CHOICE { + explicitValue MAC-MainConfig, + defaultValue NULL + } OPTIONAL, -- Cond HO-toEUTRA2 + sps-Config SPS-Config OPTIONAL, -- Need ON + physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON + ..., + [[ rlf-TimersAndConstants-r9 RLF-TimersAndConstants-r9 OPTIONAL -- Need ON + ]], + [[ measSubframePatternPCell-r10 MeasSubframePatternPCell-r10 OPTIONAL -- Need ON + ]], + [[ neighCellsCRS-Info-r11 NeighCellsCRS-Info-r11 OPTIONAL -- Need ON + ]], + [[ naics-Info-r12 NAICS-AssistanceInfo-r12 OPTIONAL -- Need ON + ]], + [[ neighCellsCRS-Info-r13 NeighCellsCRS-Info-r13 OPTIONAL, -- Cond CRSIM + rlf-TimersAndConstants-r13 RLF-TimersAndConstants-r13 OPTIONAL -- Need ON + ]] +} + +RadioResourceConfigDedicatedPSCell-r12 ::= SEQUENCE { + -- UE specific configuration extensions applicable for an PSCell + physicalConfigDedicatedPSCell-r12 PhysicalConfigDedicated OPTIONAL, -- Need ON + sps-Config-r12 SPS-Config OPTIONAL, -- Need ON + naics-Info-r12 NAICS-AssistanceInfo-r12 OPTIONAL, -- Need ON + ..., + [[ neighCellsCRS-InfoPSCell-r13 NeighCellsCRS-Info-r13 OPTIONAL -- Need ON + ]] +} + +RadioResourceConfigDedicatedSCG-r12 ::= SEQUENCE { + drb-ToAddModListSCG-r12 DRB-ToAddModListSCG-r12 OPTIONAL, -- Need ON + mac-MainConfigSCG-r12 MAC-MainConfig OPTIONAL, -- Need ON + rlf-TimersAndConstantsSCG-r12 RLF-TimersAndConstantsSCG-r12 OPTIONAL, -- Need ON + ... +} + +RadioResourceConfigDedicatedSCell-r10 ::= SEQUENCE { + -- UE specific configuration extensions applicable for an SCell + physicalConfigDedicatedSCell-r10 PhysicalConfigDedicatedSCell-r10 OPTIONAL, -- Need ON + ..., + [[ mac-MainConfigSCell-r11 MAC-MainConfigSCell-r11 OPTIONAL -- Cond SCellAdd + ]], + [[ naics-Info-r12 NAICS-AssistanceInfo-r12 OPTIONAL -- Need ON + ]], + [[ neighCellsCRS-InfoSCell-r13 NeighCellsCRS-Info-r13 OPTIONAL -- Need ON + ]] + +} + +SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod + +SRB-ToAddMod ::= SEQUENCE { + srb-Identity INTEGER (1..2), + rlc-Config CHOICE { + explicitValue RLC-Config, + defaultValue NULL + } OPTIONAL, -- Cond Setup + logicalChannelConfig CHOICE { + explicitValue LogicalChannelConfig, + defaultValue NULL + } OPTIONAL, -- Cond Setup + ... +} + +DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod + +DRB-ToAddModListSCG-r12 ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddModSCG-r12 + +DRB-ToAddMod ::= SEQUENCE { + eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup + drb-Identity DRB-Identity, + pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP + rlc-Config RLC-Config OPTIONAL, -- Cond SetupM + logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-SetupM + logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond SetupM + ..., + [[ drb-TypeChange-r12 ENUMERATED {toMCG} OPTIONAL, -- Need OP + rlc-Config-v1250 RLC-Config-v1250 OPTIONAL -- Need ON + ]], + [[ rlc-Config-v1310 RLC-Config-v1310 OPTIONAL, -- Need ON + drb-TypeLWA-r13 BOOLEAN OPTIONAL, -- Need ON + drb-TypeLWIP-r13 ENUMERATED {lwip, lwip-DL-only, + lwip-UL-only, eutran} OPTIONAL -- Need ON + ]], + [[ rlc-Config-v14xy RLC-Config-v14xy OPTIONAL, -- Need ON + lwip-UL-Aggregation-r14 BOOLEAN OPTIONAL, -- Cond LWIP + lwip-DL-Aggregation-r14 BOOLEAN OPTIONAL -- Cond LWIP + ]] +} + +DRB-ToAddModSCG-r12 ::= SEQUENCE { + drb-Identity-r12 DRB-Identity, + drb-Type-r12 CHOICE { + split-r12 NULL, + scg-r12 SEQUENCE { + eps-BearerIdentity-r12 INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup + pdcp-Config-r12 PDCP-Config OPTIONAL -- Cond PDCP-S + } + } OPTIONAL, -- Cond SetupS2 + rlc-ConfigSCG-r12 RLC-Config OPTIONAL, -- Cond SetupS + rlc-Config-v1250 RLC-Config-v1250 OPTIONAL, -- Need ON + logicalChannelIdentitySCG-r12 INTEGER (3..10) OPTIONAL, -- Cond DRB-SetupS + logicalChannelConfigSCG-r12 LogicalChannelConfig OPTIONAL, -- Cond SetupS + ..., + [[ rlc-Config-v14xy RLC-Config-v14xy OPTIONAL -- Need ON + ]] +} + +DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity + +MeasSubframePatternPCell-r10 ::= CHOICE { + release NULL, + setup MeasSubframePattern-r10 +} + +NeighCellsCRS-Info-r11 ::= CHOICE { + release NULL, + setup CRS-AssistanceInfoList-r11 +} + +CRS-AssistanceInfoList-r11 ::= SEQUENCE (SIZE (1..maxCellReport)) OF CRS-AssistanceInfo-r11 + +CRS-AssistanceInfo-r11 ::= SEQUENCE { + physCellId-r11 PhysCellId, + antennaPortsCount-r11 ENUMERATED {an1, an2, an4, spare1}, + mbsfn-SubframeConfigList-r11 MBSFN-SubframeConfigList, + ... +} + +NeighCellsCRS-Info-r13 ::= CHOICE { + release NULL, + setup CRS-AssistanceInfoList-r13 +} + +CRS-AssistanceInfoList-r13 ::= SEQUENCE (SIZE (1..maxCellReport)) OF CRS-AssistanceInfo-r13 + +CRS-AssistanceInfo-r13 ::= SEQUENCE { + physCellId-r13 PhysCellId, + antennaPortsCount-r13 ENUMERATED {an1, an2, an4, spare1}, + mbsfn-SubframeConfigList-r13 MBSFN-SubframeConfigList OPTIONAL, -- Need ON + ... +} + +NAICS-AssistanceInfo-r12 ::= CHOICE { + release NULL, + setup SEQUENCE { + neighCellsToReleaseList-r12 NeighCellsToReleaseList-r12 OPTIONAL , -- Need ON + neighCellsToAddModList-r12 NeighCellsToAddModList-r12 OPTIONAL, -- Need ON + servCellp-a-r12 P-a OPTIONAL -- Need ON + } +} + +NeighCellsToReleaseList-r12 ::= SEQUENCE (SIZE (1..maxNeighCell-r12)) OF PhysCellId + +NeighCellsToAddModList-r12 ::= SEQUENCE (SIZE (1..maxNeighCell-r12)) OF NeighCellsInfo-r12 + +NeighCellsInfo-r12 ::= SEQUENCE { + physCellId-r12 PhysCellId, + p-b-r12 INTEGER (0..3), + crs-PortsCount-r12 ENUMERATED {n1, n2, n4, spare}, + mbsfn-SubframeConfig-r12 MBSFN-SubframeConfigList OPTIONAL, -- Need ON + p-aList-r12 SEQUENCE (SIZE (1..maxP-a-PerNeighCell-r12)) OF P-a, + transmissionModeList-r12 BIT STRING (SIZE(8)), + resAllocGranularity-r12 INTEGER (1..4), + ... +} +P-a ::= ENUMERATED { dB-6, dB-4dot77, dB-3, dB-1dot77, + dB0, dB1, dB2, dB3} + + +RCLWI-Configuration-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + rclwi-Config-r13 RCLWI-Config-r13 + } +} + +RCLWI-Config-r13 ::= SEQUENCE { + command CHOICE { + steerToWLAN-r13 SEQUENCE { + mobilityConfig-r13 WLAN-Id-List-r12 + }, + steerToLTE-r13 NULL + }, + ... +} + + +RLC-Config ::= CHOICE { + am SEQUENCE { + ul-AM-RLC UL-AM-RLC, + dl-AM-RLC DL-AM-RLC + }, + um-Bi-Directional SEQUENCE { + ul-UM-RLC UL-UM-RLC, + dl-UM-RLC DL-UM-RLC + }, + um-Uni-Directional-UL SEQUENCE { + ul-UM-RLC UL-UM-RLC + }, + um-Uni-Directional-DL SEQUENCE { + dl-UM-RLC DL-UM-RLC + }, + ... +} + +RLC-Config-v1250 ::= SEQUENCE { + ul-extended-RLC-LI-Field-r12 BOOLEAN, + dl-extended-RLC-LI-Field-r12 BOOLEAN +} + +RLC-Config-v1310 ::= SEQUENCE { + ul-extended-RLC-AM-SN-r13 BOOLEAN, + dl-extended-RLC-AM-SN-r13 BOOLEAN, + pollPDU-v1310 PollPDU-v1310 OPTIONAL -- Need OR +} + +RLC-Config-v14xy ::= CHOICE { + release NULL, + setup SEQUENCE { + pollByte-r14 PollByte-r14 + } +} + +UL-AM-RLC ::= SEQUENCE { + t-PollRetransmit T-PollRetransmit, + pollPDU PollPDU, + pollByte PollByte, + maxRetxThreshold ENUMERATED { + t1, t2, t3, t4, t6, t8, t16, t32} +} + +DL-AM-RLC ::= SEQUENCE { + t-Reordering T-Reordering, + t-StatusProhibit T-StatusProhibit +} + +UL-UM-RLC ::= SEQUENCE { + sn-FieldLength SN-FieldLength +} + +DL-UM-RLC ::= SEQUENCE { + sn-FieldLength SN-FieldLength, + t-Reordering T-Reordering +} + +SN-FieldLength ::= ENUMERATED {size5, size10} + +T-PollRetransmit ::= ENUMERATED { + ms5, ms10, ms15, ms20, ms25, ms30, ms35, + ms40, ms45, ms50, ms55, ms60, ms65, ms70, + ms75, ms80, ms85, ms90, ms95, ms100, ms105, + ms110, ms115, ms120, ms125, ms130, ms135, + ms140, ms145, ms150, ms155, ms160, ms165, + ms170, ms175, ms180, ms185, ms190, ms195, + ms200, ms205, ms210, ms215, ms220, ms225, + ms230, ms235, ms240, ms245, ms250, ms300, + ms350, ms400, ms450, ms500, ms800-v1310, + ms1000-v1310, ms2000-v1310, ms4000-v1310, + spare5, spare4, spare3, spare2, spare1} + +PollPDU ::= ENUMERATED { + p4, p8, p16, p32, p64, p128, p256, pInfinity} + +PollPDU-v1310 ::= ENUMERATED { + p512, p1024, p2048, p4096, p6144, p8192, p12288, p16384} + +PollByte ::= ENUMERATED { + kB25, kB50, kB75, kB100, kB125, kB250, kB375, + kB500, kB750, kB1000, kB1250, kB1500, kB2000, + kB3000, kBinfinity, spare1} + +PollByte-r14 ::= ENUMERATED { + kB1, kB2, kB5, kB8, kB10, kB15, kB3500, + kB4000, kB4500, kB5000, kB5500, kB6000, kB6500, + kB7000, kB7500, kB8000, kB9000, kB10000, kB11000, kB12000, + kB13000, kB14000, kB15000, kB16000, kB17000, kB18000, + kB19000, kB20000, kB25000, kB30000, kB35000, kB40000} + +T-Reordering ::= ENUMERATED { + ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, + ms40, ms45, ms50, ms55, ms60, ms65, ms70, + ms75, ms80, ms85, ms90, ms95, ms100, ms110, + ms120, ms130, ms140, ms150, ms160, ms170, + ms180, ms190, ms200, ms1600-v1310} + +T-StatusProhibit ::= ENUMERATED { + ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, + ms40, ms45, ms50, ms55, ms60, ms65, ms70, + ms75, ms80, ms85, ms90, ms95, ms100, ms105, + ms110, ms115, ms120, ms125, ms130, ms135, + ms140, ms145, ms150, ms155, ms160, ms165, + ms170, ms175, ms180, ms185, ms190, ms195, + ms200, ms205, ms210, ms215, ms220, ms225, + ms230, ms235, ms240, ms245, ms250, ms300, + ms350, ms400, ms450, ms500, ms800-v1310, + ms1000-v1310, ms1200-v1310, ms1600-v1310, ms2000-v1310, ms2400-v1310, spare2, + spare1} + + +RLF-TimersAndConstants-r9 ::= CHOICE { + release NULL, + setup SEQUENCE { + t301-r9 ENUMERATED { + ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, + ms2000}, + t310-r9 ENUMERATED { + ms0, ms50, ms100, ms200, ms500, ms1000, ms2000}, + n310-r9 ENUMERATED { + n1, n2, n3, n4, n6, n8, n10, n20}, + t311-r9 ENUMERATED { + ms1000, ms3000, ms5000, ms10000, ms15000, + ms20000, ms30000}, + n311-r9 ENUMERATED { + n1, n2, n3, n4, n5, n6, n8, n10}, + ... + } +} + +RLF-TimersAndConstants-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + t301-v1310 ENUMERATED { + ms2500, ms3000, ms3500, ms4000, ms5000, + ms6000, ms8000, ms10000}, + ..., + [[ t310-v1330 ENUMERATED {ms4000, ms6000} OPTIONAL -- Need ON + ]] + } +} + +RLF-TimersAndConstantsSCG-r12 ::= CHOICE { + release NULL, + setup SEQUENCE { + t313-r12 ENUMERATED { + ms0, ms50, ms100, ms200, ms500, ms1000, ms2000}, + n313-r12 ENUMERATED { + n1, n2, n3, n4, n6, n8, n10, n20}, + n314-r12 ENUMERATED { + n1, n2, n3, n4, n5, n6, n8, n10}, + ... + } +} + + +RN-SubframeConfig-r10 ::= SEQUENCE { + subframeConfigPattern-r10 CHOICE { + subframeConfigPatternFDD-r10 BIT STRING (SIZE(8)), + subframeConfigPatternTDD-r10 INTEGER (0..31) + } OPTIONAL, -- Need ON + rpdcch-Config-r10 SEQUENCE { + resourceAllocationType-r10 ENUMERATED {type0, type1, type2Localized, type2Distributed, + spare4, spare3, spare2, spare1}, + resourceBlockAssignment-r10 CHOICE { + type01-r10 CHOICE { + nrb6-r10 BIT STRING (SIZE(6)), + nrb15-r10 BIT STRING (SIZE(8)), + nrb25-r10 BIT STRING (SIZE(13)), + nrb50-r10 BIT STRING (SIZE(17)), + nrb75-r10 BIT STRING (SIZE(19)), + nrb100-r10 BIT STRING (SIZE(25)) + }, + type2-r10 CHOICE { + nrb6-r10 BIT STRING (SIZE(5)), + nrb15-r10 BIT STRING (SIZE(7)), + nrb25-r10 BIT STRING (SIZE(9)), + nrb50-r10 BIT STRING (SIZE(11)), + nrb75-r10 BIT STRING (SIZE(12)), + nrb100-r10 BIT STRING (SIZE(13)) + }, + ... + }, + demodulationRS-r10 CHOICE { + interleaving-r10 ENUMERATED {crs}, + noInterleaving-r10 ENUMERATED {crs, dmrs} + }, + pdsch-Start-r10 INTEGER (1..3), + pucch-Config-r10 CHOICE { + tdd CHOICE { + channelSelectionMultiplexingBundling SEQUENCE { + n1PUCCH-AN-List-r10 SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047) + }, + fallbackForFormat3 SEQUENCE { + n1PUCCH-AN-P0-r10 INTEGER (0..2047), + n1PUCCH-AN-P1-r10 INTEGER (0..2047) OPTIONAL -- Need OR + } + }, + fdd SEQUENCE { + n1PUCCH-AN-P0-r10 INTEGER (0..2047), + n1PUCCH-AN-P1-r10 INTEGER (0..2047) OPTIONAL -- Need OR + } + }, + ... + } OPTIONAL, -- Need ON + ... +} + + +SchedulingRequestConfig ::= CHOICE { + release NULL, + setup SEQUENCE { + sr-PUCCH-ResourceIndex INTEGER (0..2047), + sr-ConfigIndex INTEGER (0..157), + dsr-TransMax ENUMERATED { + n4, n8, n16, n32, n64, spare3, spare2, spare1} + } +} + +SchedulingRequestConfig-v1020 ::= SEQUENCE { + sr-PUCCH-ResourceIndexP1-r10 INTEGER (0..2047) OPTIONAL -- Need OR +} + +SchedulingRequestConfigSCell-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + sr-PUCCH-ResourceIndex-r13 INTEGER (0..2047), + sr-PUCCH-ResourceIndexP1-r13 INTEGER (0..2047) OPTIONAL, -- Need OR + sr-ConfigIndex-r13 INTEGER (0..157), + dsr-TransMax-r13 ENUMERATED { + n4, n8, n16, n32, n64, spare3, spare2, spare1} + } + +} + + +SoundingRS-UL-ConfigCommon ::= CHOICE { + release NULL, + setup SEQUENCE { + srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7}, + srs-SubframeConfig ENUMERATED { + sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7, + sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15}, + ackNackSRS-SimultaneousTransmission BOOLEAN, + srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD + } +} + +SoundingRS-UL-ConfigDedicated ::= CHOICE{ + release NULL, + setup SEQUENCE { + srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3}, + srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3}, + freqDomainPosition INTEGER (0..23), + duration BOOLEAN, + srs-ConfigIndex INTEGER (0..1023), + transmissionComb INTEGER (0..1), + cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7} + } +} + +SoundingRS-UL-ConfigDedicated-v1020 ::= SEQUENCE { + srs-AntennaPort-r10 SRS-AntennaPort +} + +SoundingRS-UL-ConfigDedicated-v1310 ::= CHOICE{ + release NULL, + setup SEQUENCE { + transmissionComb-v1310 INTEGER (2..3) OPTIONAL, -- Need OR + cyclicShift-v1310 ENUMERATED {cs8, cs9, cs10, cs11} OPTIONAL, -- Need OR + transmissionCombNum-r13 ENUMERATED {n2, n4} OPTIONAL -- Need OR + } +} + +SoundingRS-UL-ConfigDedicatedUpPTsExt-r13 ::= CHOICE{ + release NULL, + setup SEQUENCE { + srs-UpPtsAdd-r13 ENUMERATED {sym2, sym4}, + srs-Bandwidth-r13 ENUMERATED {bw0, bw1, bw2, bw3}, + srs-HoppingBandwidth-r13 ENUMERATED {hbw0, hbw1, hbw2, hbw3}, + freqDomainPosition-r13 INTEGER (0..23), + duration-r13 BOOLEAN, + srs-ConfigIndex-r13 INTEGER (0..1023), + transmissionComb-r13 INTEGER (0..3), + cyclicShift-r13 ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, + cs8, cs9, cs10, cs11}, + srs-AntennaPort-r13 SRS-AntennaPort, + transmissionCombNum-r13 ENUMERATED {n2, n4} + } +} + +SoundingRS-UL-ConfigDedicatedAperiodic-r10 ::= CHOICE{ + release NULL, + setup SEQUENCE { + srs-ConfigIndexAp-r10 INTEGER (0..31), + srs-ConfigApDCI-Format4-r10 SEQUENCE (SIZE (1..3)) OF SRS-ConfigAp-r10 OPTIONAL,--Need ON + srs-ActivateAp-r10 CHOICE { + release NULL, + setup SEQUENCE { + srs-ConfigApDCI-Format0-r10 SRS-ConfigAp-r10, + srs-ConfigApDCI-Format1a2b2c-r10 SRS-ConfigAp-r10, + ... + } + } OPTIONAL -- Need ON + } +} + +SoundingRS-UL-ConfigDedicatedAperiodic-v1310 ::= CHOICE{ + release NULL, + setup SEQUENCE { + srs-ConfigApDCI-Format4-v1310 SEQUENCE (SIZE (1..3)) OF SRS-ConfigAp-v1310 OPTIONAL,--Need ON + srs-ActivateAp-v1310 CHOICE { + release NULL, + setup SEQUENCE { + srs-ConfigApDCI-Format0-v1310 SRS-ConfigAp-v1310 OPTIONAL, -- Need ON + srs-ConfigApDCI-Format1a2b2c-v1310 SRS-ConfigAp-v1310 OPTIONAL -- Need ON + } + } OPTIONAL -- Need ON + } +} + +SoundingRS-UL-ConfigDedicatedAperiodicUpPTsExt-r13 ::= CHOICE{ + release NULL, + setup SEQUENCE { + srs-UpPtsAdd-r13 ENUMERATED {sym2, sym4}, + srs-ConfigIndexAp-r13 INTEGER (0..31), + srs-ConfigApDCI-Format4-r13 SEQUENCE (SIZE (1..3)) OF SRS-ConfigAp-r13 OPTIONAL,--Need ON + srs-ActivateAp-r13 CHOICE { + release NULL, + setup SEQUENCE { + srs-ConfigApDCI-Format0-r13 SRS-ConfigAp-r13, + srs-ConfigApDCI-Format1a2b2c-r13 SRS-ConfigAp-r13 + } + } OPTIONAL -- Need ON + } +} + +SoundingRS-UL-ConfigDedicatedAperiodic-v14xy ::= CHOICE{ + release NULL, + setup SEQUENCE { + srs-SubframeIndication-r14 INTEGER (1..4) OPTIONAL -- Need ON + } +} + +SRS-ConfigAp-r10 ::= SEQUENCE { + srs-AntennaPortAp-r10 SRS-AntennaPort, + srs-BandwidthAp-r10 ENUMERATED {bw0, bw1, bw2, bw3}, + freqDomainPositionAp-r10 INTEGER (0..23), + transmissionCombAp-r10 INTEGER (0..1), + cyclicShiftAp-r10 ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7} +} + +SRS-ConfigAp-v1310 ::= SEQUENCE { + transmissionCombAp-v1310 INTEGER (2..3) OPTIONAL, -- Need OR + cyclicShiftAp-v1310 ENUMERATED {cs8, cs9, cs10, cs11} OPTIONAL, -- Need OR + transmissionCombNum-r13 ENUMERATED {n2, n4} OPTIONAL -- Need OR +} + +SRS-ConfigAp-r13 ::= SEQUENCE { + srs-AntennaPortAp-r13 SRS-AntennaPort, + srs-BandwidthAp-r13 ENUMERATED {bw0, bw1, bw2, bw3}, + freqDomainPositionAp-r13 INTEGER (0..23), + transmissionCombAp-r13 INTEGER (0..3), + cyclicShiftAp-r13 ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, + cs8, cs9, cs10, cs11}, + transmissionCombNum-r13 ENUMERATED {n2, n4} +} + +SRS-AntennaPort ::= ENUMERATED {an1, an2, an4, spare1} + + +SPS-Config ::= SEQUENCE { + semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR + sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON + sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON +} + +SPS-ConfigDL ::= CHOICE{ + release NULL, + setup SEQUENCE { + semiPersistSchedIntervalDL ENUMERATED { + sf10, sf20, sf32, sf40, sf64, sf80, + sf128, sf160, sf320, sf640, spare6, + spare5, spare4, spare3, spare2, + spare1}, + numberOfConfSPS-Processes INTEGER (1..8), + n1PUCCH-AN-PersistentList N1PUCCH-AN-PersistentList, + ..., + [[ twoAntennaPortActivated-r10 CHOICE { + release NULL, + setup SEQUENCE { + n1PUCCH-AN-PersistentListP1-r10 N1PUCCH-AN-PersistentList + } + } OPTIONAL -- Need ON + ]] + } +} + +SPS-ConfigUL ::= CHOICE { + release NULL, + setup SEQUENCE { + semiPersistSchedIntervalUL ENUMERATED { + sf10, sf20, sf32, sf40, sf64, sf80, + sf128, sf160, sf320, sf640, sf1-v14xy, + sf2-v14xy, sf3-v14xy, sf4-v14xy, sf5-v14xy, + spare1}, + implicitReleaseAfter ENUMERATED {e2, e3, e4, e8}, + p0-Persistent SEQUENCE { + p0-NominalPUSCH-Persistent INTEGER (-126..24), + p0-UE-PUSCH-Persistent INTEGER (-8..7) + } OPTIONAL, -- Need OP + twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD + ..., + [[ p0-PersistentSubframeSet2-r12 CHOICE { + release NULL, + setup SEQUENCE { + p0-NominalPUSCH-PersistentSubframeSet2-r12 INTEGER (-126..24), + p0-UE-PUSCH-PersistentSubframeSet2-r12 INTEGER (-8..7) + } + } OPTIONAL -- Need ON + ]], + [[ numberOfConfUlSPS-Processes-r13 INTEGER (1..8) OPTIONAL -- Need OR + ]], + [[ fixedRV-NonAdaptive-r14 ENUMERATED {true} OPTIONAL -- Need OR + ]] + } +} + +N1PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047) + + +SRS-TPC-PDCCH-Config-r14 ::= CHOICE { + release NULL, + setup SEQUENCE { + srs-TPC-RNTI-r14 BIT STRING (SIZE (16)), + startingBitOfFormat3B-r14 INTEGER (0..31), fieldTypeFormat3B-r14 INTEGER (1..4), + srsCcGroupIndexlist SEQUENCE (SIZE(1..4)) OF SrsCcGroupIndex OPTIONAL -- Cond Srs-Trigger-TypeA + + } +} + +SrsCcGroupIndex ::= INTEGER (0..3) + +TDD-Config ::= SEQUENCE { + subframeAssignment ENUMERATED { + sa0, sa1, sa2, sa3, sa4, sa5, sa6}, + specialSubframePatterns ENUMERATED { + ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7, + ssp8} +} + +TDD-Config-v1130 ::= SEQUENCE { + specialSubframePatterns-v1130 ENUMERATED {ssp7,ssp9} +} + +TDD-ConfigSL-r12 ::= SEQUENCE { + subframeAssignmentSL-r12 ENUMERATED { + none, sa0, sa1, sa2, sa3, sa4, sa5, sa6} +} + + +TimeAlignmentTimer ::= ENUMERATED { + sf500, sf750, sf1280, sf1920, sf2560, sf5120, + sf10240, infinity} + +TPC-PDCCH-Config ::= CHOICE { + release NULL, + setup SEQUENCE { + tpc-RNTI BIT STRING (SIZE (16)), + tpc-Index TPC-Index + } +} + +TPC-PDCCH-ConfigSCell-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + tpc-Index-PUCCH-SCell-r13 TPC-Index + } +} + +TPC-Index ::= CHOICE { + indexOfFormat3 INTEGER (1..15), + indexOfFormat3A INTEGER (1..31) +} + + +TunnelConfigLWIP-r13 ::= SEQUENCE { + ip-Address-r13 IP-Address-r13, + ike-Identity-r13 IKE-Identity-r13, + ..., + [[ lwip-Counter-r13 INTEGER (0..65535) OPTIONAL -- Cond LWIP-Setup + ]] +} + +IKE-Identity-r13 ::= SEQUENCE { + idI-r13 OCTET STRING +} + +IP-Address-r13 ::= CHOICE { + ipv4-r13 BIT STRING (SIZE (32)), + ipv6-r13 BIT STRING (SIZE (128)) +} + + +UplinkPowerControlCommon ::= SEQUENCE { + p0-NominalPUSCH INTEGER (-126..24), + alpha Alpha-r12, + p0-NominalPUCCH INTEGER (-127..-96), + deltaFList-PUCCH DeltaFList-PUCCH, + deltaPreambleMsg3 INTEGER (-1..6) +} + +UplinkPowerControlCommon-v1020 ::= SEQUENCE { + deltaF-PUCCH-Format3-r10 ENUMERATED {deltaF-1, deltaF0, deltaF1, deltaF2, + deltaF3, deltaF4, deltaF5, deltaF6}, + deltaF-PUCCH-Format1bCS-r10 ENUMERATED {deltaF1, deltaF2, spare2, spare1} +} + +UplinkPowerControlCommon-v1310 ::= SEQUENCE { + deltaF-PUCCH-Format4-r13 ENUMERATED {deltaF16, deltaF15, deltaF14,deltaF13, deltaF12, + deltaF11, deltaF10, spare1} OPTIONAL, -- Need OR + deltaF-PUCCH-Format5-13 ENUMERATED { deltaF13, deltaF12, deltaF11, deltaF10, deltaF9, + deltaF8, deltaF7, spare1} OPTIONAL -- Need OR +} + +UplinkPowerControlCommonPSCell-r12 ::= SEQUENCE { +-- For uplink power control the additional/ missing fields are signalled (compared to SCell) + deltaF-PUCCH-Format3-r12 ENUMERATED {deltaF-1, deltaF0, deltaF1, deltaF2, + deltaF3, deltaF4, deltaF5, deltaF6}, + deltaF-PUCCH-Format1bCS-r12 ENUMERATED {deltaF1, deltaF2, spare2, spare1}, + p0-NominalPUCCH-r12 INTEGER (-127..-96), + deltaFList-PUCCH-r12 DeltaFList-PUCCH +} + + +UplinkPowerControlCommonSCell-r10 ::= SEQUENCE { + p0-NominalPUSCH-r10 INTEGER (-126..24), + alpha-r10 Alpha-r12 +} + +UplinkPowerControlCommonSCell-v1130 ::= SEQUENCE { + deltaPreambleMsg3-r11 INTEGER (-1..6) +} + +UplinkPowerControlCommonSCell-v1310 ::= SEQUENCE { +-- For uplink power control the additional/ missing fields are signalled (compared to SCell) + p0-NominalPUCCH INTEGER (-127..-96), + deltaFList-PUCCH DeltaFList-PUCCH, + deltaF-PUCCH-Format3-r12 ENUMERATED {deltaF-1, deltaF0, deltaF1, + deltaF2, deltaF3, deltaF4, deltaF5, + deltaF6} OPTIONAL, -- Need OR + deltaF-PUCCH-Format1bCS-r12 ENUMERATED {deltaF1, deltaF2, + spare2, spare1} OPTIONAL, -- Need OR + deltaF-PUCCH-Format4-r13 ENUMERATED {deltaF16, deltaF15, deltaF14, + deltaF13, deltaF12, deltaF11, deltaF10, + spare1} OPTIONAL, -- Need OR + deltaF-PUCCH-Format5-13 ENUMERATED { deltaF13, deltaF12, deltaF11, + deltaF10, deltaF9, deltaF8, deltaF7, + spare1} OPTIONAL -- Need OR +} +UplinkPowerControlCommonPUSCH-LessCell-v14xy ::= SEQUENCE { + p0-Nominal-PeriodicSRS INTEGER (-126..24) OPTIONAL, -- Need OR + p0-Nominal-AperiodicSRS INTEGER (-126..24) OPTIONAL, -- Need OR + alpha-SRS-r14 Alpha-r12 OPTIONAL -- Need OR +} + +UplinkPowerControlDedicated ::= SEQUENCE { + p0-UE-PUSCH INTEGER (-8..7), + deltaMCS-Enabled ENUMERATED {en0, en1}, + accumulationEnabled BOOLEAN, + p0-UE-PUCCH INTEGER (-8..7), + pSRS-Offset INTEGER (0..15), + filterCoefficient FilterCoefficient DEFAULT fc4 +} + +UplinkPowerControlDedicated-v1020 ::= SEQUENCE { + deltaTxD-OffsetListPUCCH-r10 DeltaTxD-OffsetListPUCCH-r10 OPTIONAL, -- Need OR + pSRS-OffsetAp-r10 INTEGER (0..15) OPTIONAL -- Need OR +} + +UplinkPowerControlDedicated-v1130 ::= SEQUENCE { + pSRS-Offset-v1130 INTEGER (16..31) OPTIONAL, -- Need OR + pSRS-OffsetAp-v1130 INTEGER (16..31) OPTIONAL, -- Need OR + deltaTxD-OffsetListPUCCH-v1130 DeltaTxD-OffsetListPUCCH-v1130 OPTIONAL -- Need OR +} + +UplinkPowerControlDedicated-v1250 ::= SEQUENCE { + set2PowerControlParameter CHOICE { + release NULL, + setup SEQUENCE { + tpc-SubframeSet-r12 BIT STRING (SIZE(10)), + p0-NominalPUSCH-SubframeSet2-r12 INTEGER (-126..24), + alpha-SubframeSet2-r12 Alpha-r12, + p0-UE-PUSCH-SubframeSet2-r12 INTEGER (-8..7) + } + } +} + +UplinkPUSCH-LessPowerControlDedicated-v14xy ::= SEQUENCE { + p0-UE-PeriodicSRS INTEGER (-8..7) OPTIONAL, -- Need OR + p0-UE-AperiodicSRS INTEGER (-8..7) OPTIONAL, -- Need OR + accumulationEnabled BOOLEAN +} + +UplinkPowerControlDedicatedSCell-r10 ::= SEQUENCE { + p0-UE-PUSCH-r10 INTEGER (-8..7), + deltaMCS-Enabled-r10 ENUMERATED {en0, en1}, + accumulationEnabled-r10 BOOLEAN, + pSRS-Offset-r10 INTEGER (0..15), + pSRS-OffsetAp-r10 INTEGER (0..15) OPTIONAL, -- Need OR + filterCoefficient-r10 FilterCoefficient DEFAULT fc4, + pathlossReferenceLinking-r10 ENUMERATED {pCell, sCell} +} + +UplinkPowerControlDedicatedSCell-v1310 ::= SEQUENCE { +--Release 8 + p0-UE-PUCCH INTEGER (-8..7), +--Release 10 + deltaTxD-OffsetListPUCCH-r10 DeltaTxD-OffsetListPUCCH-r10 OPTIONAL -- Need OR +} + +Alpha-r12 ::= ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1} + +DeltaFList-PUCCH ::= SEQUENCE { + deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2}, + deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5}, + deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2}, + deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2}, + deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2} +} + +DeltaTxD-OffsetListPUCCH-r10 ::= SEQUENCE { + deltaTxD-OffsetPUCCH-Format1-r10 ENUMERATED {dB0, dB-2}, + deltaTxD-OffsetPUCCH-Format1a1b-r10 ENUMERATED {dB0, dB-2}, + deltaTxD-OffsetPUCCH-Format22a2b-r10 ENUMERATED {dB0, dB-2}, + deltaTxD-OffsetPUCCH-Format3-r10 ENUMERATED {dB0, dB-2}, + ... + +} + +DeltaTxD-OffsetListPUCCH-v1130 ::= SEQUENCE { + deltaTxD-OffsetPUCCH-Format1bCS-r11 ENUMERATED {dB0, dB-1} +} + + +WLAN-Id-List-r13 ::= SEQUENCE (SIZE (1..maxWLAN-Id-r13)) OF WLAN-Identifiers-r12 + + +WLAN-MobilityConfig-r13 ::= SEQUENCE { + wlan-ToReleaseList-r13 WLAN-Id-List-r13 OPTIONAL, -- Need ON + wlan-ToAddList-r13 WLAN-Id-List-r13 OPTIONAL, -- Need ON + associationTimer-r13 ENUMERATED {s10, s30, + s60, s120, s240} OPTIONAL, -- Need OR + successReportRequested-r13 ENUMERATED {true} OPTIONAL, -- Need OR + ... +} + + +NextHopChainingCount ::= INTEGER (0..7) + + +SecurityAlgorithmConfig ::= SEQUENCE { + cipheringAlgorithm CipheringAlgorithm-r12, + integrityProtAlgorithm ENUMERATED { + eia0-v920, eia1, eia2, eia3-v1130, spare4, spare3, + spare2, spare1, ...} +} + +CipheringAlgorithm-r12 ::= ENUMERATED { + eea0, eea1, eea2, eea3-v1130, spare4, spare3, + spare2, spare1, ...} + + +ShortMAC-I ::= BIT STRING (SIZE (16)) + + +AdditionalSpectrumEmission ::= INTEGER (1..32) + + +ARFCN-ValueCDMA2000 ::= INTEGER (0..2047) + + +ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN) + +ARFCN-ValueEUTRA-v9e0 ::= INTEGER (maxEARFCN-Plus1..maxEARFCN2) + +ARFCN-ValueEUTRA-r9 ::= INTEGER (0..maxEARFCN2) + + +ARFCN-ValueGERAN ::= INTEGER (0..1023) + + +ARFCN-ValueUTRA ::= INTEGER (0..16383) + + +BandclassCDMA2000 ::= ENUMERATED { + bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8, + bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16, + bc17, bc18-v9a0, bc19-v9a0, bc20-v9a0, bc21-v9a0, + spare10, spare9, spare8, spare7, spare6, spare5, spare4, + spare3, spare2, spare1, ...} + + +BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900} + + +CarrierFreqCDMA2000 ::= SEQUENCE { + bandClass BandclassCDMA2000, + arfcn ARFCN-ValueCDMA2000 +} + + +CarrierFreqGERAN ::= SEQUENCE { + arfcn ARFCN-ValueGERAN, + bandIndicator BandIndicatorGERAN +} + + +CarrierFreqsGERAN ::= SEQUENCE { + startingARFCN ARFCN-ValueGERAN, + bandIndicator BandIndicatorGERAN, + followingARFCNs CHOICE { + explicitListOfARFCNs ExplicitListOfARFCNs, + equallySpacedARFCNs SEQUENCE { + arfcn-Spacing INTEGER (1..8), + numberOfFollowingARFCNs INTEGER (0..31) + }, + variableBitMapOfARFCNs OCTET STRING (SIZE (1..16)) + } +} + +ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN + + +CarrierFreqListMBMS-r11 ::= SEQUENCE (SIZE (1..maxFreqMBMS-r11)) OF ARFCN-ValueEUTRA-r9 + + +CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD} + + +CellIdentity ::= BIT STRING (SIZE (28)) + + +CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex + +CellIndex ::= INTEGER (1..maxCellMeas) + + +CellReselectionPriority ::= INTEGER (0..7) + + +CellSelectionInfoCE-r13 ::= SEQUENCE { + q-RxLevMinCE-r13 Q-RxLevMin, + q-QualMinRSRQ-CE-r13 Q-QualMin-r9 OPTIONAL -- Need OR +} + + +CellReselectionSubPriority-r13 ::= ENUMERATED {oDot2, oDot4, oDot6, oDot8} + + +CSFB-RegistrationParam1XRTT ::= SEQUENCE { + sid BIT STRING (SIZE (15)), + nid BIT STRING (SIZE (16)), + multipleSID BOOLEAN, + multipleNID BOOLEAN, + homeReg BOOLEAN, + foreignSIDReg BOOLEAN, + foreignNIDReg BOOLEAN, + parameterReg BOOLEAN, + powerUpReg BOOLEAN, + registrationPeriod BIT STRING (SIZE (7)), + registrationZone BIT STRING (SIZE (12)), + totalZone BIT STRING (SIZE (3)), + zoneTimer BIT STRING (SIZE (3)) +} + +CSFB-RegistrationParam1XRTT-v920 ::= SEQUENCE { + powerDownReg-r9 ENUMERATED {true} +} + + +CellGlobalIdEUTRA ::= SEQUENCE { + plmn-Identity PLMN-Identity, + cellIdentity CellIdentity +} + + +CellGlobalIdUTRA ::= SEQUENCE { + plmn-Identity PLMN-Identity, + cellIdentity BIT STRING (SIZE (28)) +} + + +CellGlobalIdGERAN ::= SEQUENCE { + plmn-Identity PLMN-Identity, + locationAreaCode BIT STRING (SIZE (16)), + cellIdentity BIT STRING (SIZE (16)) +} + + +CellGlobalIdCDMA2000 ::= CHOICE { + cellGlobalId1XRTT BIT STRING (SIZE (47)), + cellGlobalIdHRPD BIT STRING (SIZE (128)) +} + + +CellSelectionInfoNFreq-r13 ::= SEQUENCE { + -- Cell selection information as in SIB1 + q-RxLevMin-r13 Q-RxLevMin, + q-RxLevMinOffset INTEGER (1..8) OPTIONAL, -- Need OP + -- Cell re-selection information as in SIB3 + q-Hyst-r13 ENUMERATED { + dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10, + dB12, dB14, dB16, dB18, dB20, dB22, dB24}, + q-RxLevMinReselection-r13 Q-RxLevMin, + t-ReselectionEUTRA-r13 T-Reselection +} + + +CSG-Identity ::= BIT STRING (SIZE (27)) + + +FreqBandIndicator ::= INTEGER (1..maxFBI) + +FreqBandIndicator-v9e0 ::= INTEGER (maxFBI-Plus1..maxFBI2) + +FreqBandIndicator-r11 ::= INTEGER (1..maxFBI2) + + +MobilityControlInfo ::= SEQUENCE { + targetPhysCellId PhysCellId, + carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA2 + carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA + additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA + t304 ENUMERATED { + ms50, ms100, ms150, ms200, ms500, ms1000, + ms2000, ms10000-v1310}, + newUE-Identity C-RNTI, + radioResourceConfigCommon RadioResourceConfigCommon, + rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP + ..., + [[ carrierFreq-v9e0 CarrierFreqEUTRA-v9e0 OPTIONAL -- Need ON + ]], + [[ drb-ContinueROHC-r11 ENUMERATED {true} OPTIONAL -- Cond HO + ]], + [[ mobilityControlInfoV2X-r14 MobilityControlInfoV2X-r14 OPTIONAL -- Need OR + ]] +} + +MobilityControlInfoSCG-r12 ::= SEQUENCE { + t307-r12 ENUMERATED { + ms50, ms100, ms150, ms200, ms500, ms1000, + ms2000, spare1}, + ue-IdentitySCG-r12 C-RNTI OPTIONAL, -- Cond SCGEst, + rach-ConfigDedicated-r12 RACH-ConfigDedicated OPTIONAL, -- Need OP + cipheringAlgorithmSCG-r12 CipheringAlgorithm-r12 OPTIONAL, -- Need ON + ... +} + +MobilityControlInfoV2X-r14 ::= SEQUENCE { + v2x-CommTxPoolExceptional-r14 SL-CommResourcePoolV2X-r14 OPTIONAL, -- Need OR + v2x-CommRxPool-r14 SL-CommRxPoolListV2X-r14 OPTIONAL, -- Need OR + v2x-CommSyncConfig-r14 SL-SyncConfigListV2X-r14 OPTIONAL -- Need OR +} + +CarrierBandwidthEUTRA ::= SEQUENCE { + dl-Bandwidth ENUMERATED { + n6, n15, n25, n50, n75, n100, spare10, + spare9, spare8, spare7, spare6, spare5, + spare4, spare3, spare2, spare1}, + ul-Bandwidth ENUMERATED { + n6, n15, n25, n50, n75, n100, spare10, + spare9, spare8, spare7, spare6, spare5, + spare4, spare3, spare2, spare1} OPTIONAL -- Need OP +} + +CarrierFreqEUTRA ::= SEQUENCE { + dl-CarrierFreq ARFCN-ValueEUTRA, + ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD +} + +CarrierFreqEUTRA-v9e0 ::= SEQUENCE { + dl-CarrierFreq-v9e0 ARFCN-ValueEUTRA-r9, + ul-CarrierFreq-v9e0 ARFCN-ValueEUTRA-r9 OPTIONAL -- Cond FDD +} + + +MobilityParametersCDMA2000 ::= OCTET STRING + + +MobilityStateParameters ::= SEQUENCE { + t-Evaluation ENUMERATED { + s30, s60, s120, s180, s240, spare3, spare2, spare1}, + t-HystNormal ENUMERATED { + s30, s60, s120, s180, s240, spare3, spare2, spare1}, + n-CellChangeMedium INTEGER (1..16), + n-CellChangeHigh INTEGER (1..16) +} + + +MultiBandInfoList ::= SEQUENCE (SIZE (1..maxMultiBands)) OF FreqBandIndicator + +MultiBandInfoList-v9e0 ::= SEQUENCE (SIZE (1..maxMultiBands)) OF MultiBandInfo-v9e0 + +MultiBandInfoList-v10j0 ::= SEQUENCE (SIZE (1..maxMultiBands)) OF NS-PmaxList-r10 + +MultiBandInfoList-r11 ::= SEQUENCE (SIZE (1..maxMultiBands)) OF FreqBandIndicator-r11 + +MultiBandInfo-v9e0 ::= SEQUENCE { + freqBandIndicator-v9e0 FreqBandIndicator-v9e0 OPTIONAL -- Need OP +} + + +NS-PmaxList-r10 ::= SEQUENCE (SIZE (1..maxNS-Pmax-r10)) OF NS-PmaxValue-r10 + +NS-PmaxValue-r10 ::= SEQUENCE { + additionalPmax-r10 P-Max OPTIONAL, -- Need OP + additionalSpectrumEmission AdditionalSpectrumEmission +} + + +PhysCellId ::= INTEGER (0..503) + + +PhysCellIdRange ::= SEQUENCE { + start PhysCellId, + range ENUMERATED { + n4, n8, n12, n16, n24, n32, n48, n64, n84, + n96, n128, n168, n252, n504, spare2, + spare1} OPTIONAL -- Need OP +} + + +PhysCellIdRangeUTRA-FDDList-r9::= SEQUENCE (SIZE (1..maxPhysCellIdRange-r9)) OF PhysCellIdRangeUTRA-FDD-r9 + +PhysCellIdRangeUTRA-FDD-r9 ::= SEQUENCE { + start-r9 PhysCellIdUTRA-FDD, + range-r9 INTEGER (2..512) OPTIONAL -- Need OP +} + + +PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset) + + +PhysCellIdGERAN ::= SEQUENCE { + networkColourCode BIT STRING (SIZE (3)), + baseStationColourCode BIT STRING (SIZE (3)) +} + + +PhysCellIdUTRA-FDD ::= INTEGER (0..511) + + +PhysCellIdUTRA-TDD ::= INTEGER (0..127) + + +PLMN-Identity ::= SEQUENCE { + mcc MCC OPTIONAL, -- Cond MCC + mnc MNC +} + +MCC ::= SEQUENCE (SIZE (3)) OF + MCC-MNC-Digit + +MNC ::= SEQUENCE (SIZE (2..3)) OF + MCC-MNC-Digit + +MCC-MNC-Digit ::= INTEGER (0..9) + + + +PLMN-IdentityList3-r11 ::= SEQUENCE (SIZE (1..16)) OF PLMN-Identity + + +PreRegistrationInfoHRPD ::= SEQUENCE { + preRegistrationAllowed BOOLEAN, + preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed + secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR +} + +SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD + +PreRegistrationZoneIdHRPD ::= INTEGER (0..255) + + +Q-QualMin-r9 ::= INTEGER (-34..-3) + + +Q-RxLevMin ::= INTEGER (-70..-22) + + +Q-OffsetRange ::= ENUMERATED { + dB-24, dB-22, dB-20, dB-18, dB-16, dB-14, + dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3, + dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5, + dB6, dB8, dB10, dB12, dB14, dB16, dB18, + dB20, dB22, dB24} + + +Q-OffsetRangeInterRAT ::= INTEGER (-15..15) + + +ReselectionThreshold ::= INTEGER (0..31) + + +ReselectionThresholdQ-r9 ::= INTEGER (0..31) + + +SCellIndex-r10 ::= INTEGER (1..7) +SCellIndex-r13 ::= INTEGER (1..31) + + +ServCellIndex-r10 ::= INTEGER (0..7) +ServCellIndex-r13 ::= INTEGER (0..31) + + +SpeedStateScaleFactors ::= SEQUENCE { + sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0}, + sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0} +} + +SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF + OCTET STRING (SIZE (1..23)) + + +SystemTimeInfoCDMA2000 ::= SEQUENCE { + cdma-EUTRA-Synchronisation BOOLEAN, + cdma-SystemTime CHOICE { + synchronousSystemTime BIT STRING (SIZE (39)), + asynchronousSystemTime BIT STRING (SIZE (49)) + } +} + + +TrackingAreaCode ::= BIT STRING (SIZE (16)) + + +T-Reselection ::= INTEGER (0..7) + + +T-ReselectionEUTRA-CE-r13 ::= INTEGER (0..15) + + +AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100} + + +CSI-RSRP-Range-r12 ::= INTEGER(0..97) + + +Hysteresis ::= INTEGER (0..30) + + +LocationInfo-r10 ::= SEQUENCE { + locationCoordinates-r10 CHOICE { + ellipsoid-Point-r10 OCTET STRING, + ellipsoidPointWithAltitude-r10 OCTET STRING, + ..., + ellipsoidPointWithUncertaintyCircle-r11 OCTET STRING, + ellipsoidPointWithUncertaintyEllipse-r11 OCTET STRING, + ellipsoidPointWithAltitudeAndUncertaintyEllipsoid-r11 OCTET STRING, + ellipsoidArc-r11 OCTET STRING, + polygon-r11 OCTET STRING + }, + horizontalVelocity-r10 OCTET STRING OPTIONAL, + gnss-TOD-msec-r10 OCTET STRING OPTIONAL, + ... +} + + +MBSFN-RSRQ-Range-r12 ::= INTEGER(0..31) + +MeasConfig ::= SEQUENCE { + -- Measurement objects + measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON + measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON + -- Reporting configurations + reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON + reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON + -- Measurement identities + measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON + measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON + -- Other parameters + quantityConfig QuantityConfig OPTIONAL, -- Need ON + measGapConfig MeasGapConfig OPTIONAL, -- Need ON + s-Measure RSRP-Range OPTIONAL, -- Need ON + preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP + speedStatePars CHOICE { + release NULL, + setup SEQUENCE { + mobilityStateParameters MobilityStateParameters, + timeToTrigger-SF SpeedStateScaleFactors + } + } OPTIONAL, -- Need ON + ..., + [[ measObjectToAddModList-v9e0 MeasObjectToAddModList-v9e0 OPTIONAL -- Need ON + ]], + [[ allowInterruptions-r11 BOOLEAN OPTIONAL -- Need ON + ]], + [[ measScaleFactor-r12 CHOICE { + release NULL, + setup MeasScaleFactor-r12 + } OPTIONAL, -- Need ON + measIdToRemoveListExt-r12 MeasIdToRemoveListExt-r12 OPTIONAL, -- Need ON + measIdToAddModListExt-r12 MeasIdToAddModListExt-r12 OPTIONAL, -- Need ON + measRSRQ-OnAllSymbols-r12 BOOLEAN OPTIONAL -- Need ON + ]], + [[ + measObjectToRemoveListExt-r13 MeasObjectToRemoveListExt-r13 OPTIONAL, -- Need ON + measObjectToAddModListExt-r13 MeasObjectToAddModListExt-r13 OPTIONAL, -- Need ON + measIdToAddModList-v1310 MeasIdToAddModList-v1310 OPTIONAL, -- Need ON + measIdToAddModListExt-v1310 MeasIdToAddModListExt-v1310 OPTIONAL -- Need ON + ]] +} + +MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId + +MeasIdToRemoveListExt-r12 ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId-v1250 + +MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId + +MeasObjectToRemoveListExt-r13 ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId-v1310 + +ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId + + +MeasDS-Config-r12 ::= CHOICE { + release NULL, + setup SEQUENCE { + dmtc-PeriodOffset-r12 CHOICE { + ms40-r12 INTEGER(0..39), + ms80-r12 INTEGER(0..79), + ms160-r12 INTEGER(0..159), + ... + }, + ds-OccasionDuration-r12 CHOICE { + durationFDD-r12 INTEGER(1..maxDS-Duration-r12), + durationTDD-r12 INTEGER(2..maxDS-Duration-r12) + }, + measCSI-RS-ToRemoveList-r12 MeasCSI-RS-ToRemoveList-r12 OPTIONAL, -- Need ON + measCSI-RS-ToAddModList-r12 MeasCSI-RS-ToAddModList-r12 OPTIONAL, -- Need ON + ... + } +} + +MeasCSI-RS-ToRemoveList-r12 ::= SEQUENCE (SIZE (1..maxCSI-RS-Meas-r12)) OF MeasCSI-RS-Id-r12 + +MeasCSI-RS-ToAddModList-r12 ::= SEQUENCE (SIZE (1..maxCSI-RS-Meas-r12)) OF MeasCSI-RS-Config-r12 + +MeasCSI-RS-Id-r12 ::= INTEGER (1..maxCSI-RS-Meas-r12) + +MeasCSI-RS-Config-r12 ::= SEQUENCE { + measCSI-RS-Id-r12 MeasCSI-RS-Id-r12, + physCellId-r12 INTEGER (0..503), + scramblingIdentity-r12 INTEGER (0..503), + resourceConfig-r12 INTEGER (0..31), + subframeOffset-r12 INTEGER (0..4), + csi-RS-IndividualOffset-r12 Q-OffsetRange, + ... +} + + +MeasGapConfig ::= CHOICE { + release NULL, + setup SEQUENCE { + gapOffset CHOICE { + gp0 INTEGER (0..39), + gp1 INTEGER (0..79), + ... + } + } +} + + +MeasId ::= INTEGER (1..maxMeasId) + +MeasId-v1250 ::= INTEGER (maxMeasId-Plus1..maxMeasId-r12) + + +MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod + +MeasIdToAddModList-v1310 ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod-v1310 + +MeasIdToAddModListExt-r12 ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddModExt-r12 + +MeasIdToAddModListExt-v1310 ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod-v1310 + +MeasIdToAddMod ::= SEQUENCE { + measId MeasId, + measObjectId MeasObjectId, + reportConfigId ReportConfigId +} + +MeasIdToAddModExt-r12 ::= SEQUENCE { + measId-v1250 MeasId-v1250, + measObjectId-r12 MeasObjectId, + reportConfigId-r12 ReportConfigId +} + +MeasIdToAddMod-v1310 ::= SEQUENCE { + measObjectId-v1310 MeasObjectId-v1310 OPTIONAL +} + + +MeasObjectCDMA2000 ::= SEQUENCE { + cdma2000-Type CDMA2000-Type, + carrierFreq CarrierFreqCDMA2000, + searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON + offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, + cellsToRemoveList CellIndexList OPTIONAL, -- Need ON + cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON + cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON + ... +} + +CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000 + +CellsToAddModCDMA2000 ::= SEQUENCE { + cellIndex INTEGER (1..maxCellMeas), + physCellId PhysCellIdCDMA2000 +} + + +MeasObjectEUTRA ::= SEQUENCE { + carrierFreq ARFCN-ValueEUTRA, + allowedMeasBandwidth AllowedMeasBandwidth, + presenceAntennaPort1 PresenceAntennaPort1, + neighCellConfig NeighCellConfig, + offsetFreq Q-OffsetRange DEFAULT dB0, + -- Cell list + cellsToRemoveList CellIndexList OPTIONAL, -- Need ON + cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON + -- Black list + blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON + blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON + cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON + ..., + [[measCycleSCell-r10 MeasCycleSCell-r10 OPTIONAL, -- Need ON + measSubframePatternConfigNeigh-r10 MeasSubframePatternConfigNeigh-r10 OPTIONAL -- Need ON + ]], + [[widebandRSRQ-Meas-r11 BOOLEAN OPTIONAL -- Cond WB-RSRQ + ]], + [[ altTTT-CellsToRemoveList-r12 CellIndexList OPTIONAL, -- Need ON + altTTT-CellsToAddModList-r12 AltTTT-CellsToAddModList-r12 OPTIONAL, -- Need ON + t312-r12 CHOICE { + release NULL, + setup ENUMERATED {ms0, ms50, ms100, ms200, + ms300, ms400, ms500, ms1000} + } OPTIONAL, -- Need ON + reducedMeasPerformance-r12 BOOLEAN OPTIONAL, -- Need ON + measDS-Config-r12 MeasDS-Config-r12 OPTIONAL -- Need ON + ]], + [[ + whiteCellsToRemoveList-r13 CellIndexList OPTIONAL, -- Need ON + whiteCellsToAddModList-r13 WhiteCellsToAddModList-r13 OPTIONAL, -- Need ON + rmtc-Config-r13 RMTC-Config-r13 OPTIONAL, -- Need ON + carrierFreq-r13 ARFCN-ValueEUTRA-v9e0 OPTIONAL -- Need ON + ]] +} + +MeasObjectEUTRA-v9e0 ::= SEQUENCE { + carrierFreq-v9e0 ARFCN-ValueEUTRA-v9e0 +} + +CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod + +CellsToAddMod ::= SEQUENCE { + cellIndex INTEGER (1..maxCellMeas), + physCellId PhysCellId, + cellIndividualOffset Q-OffsetRange +} + +BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod + +BlackCellsToAddMod ::= SEQUENCE { + cellIndex INTEGER (1..maxCellMeas), + physCellIdRange PhysCellIdRange +} + +MeasCycleSCell-r10 ::= ENUMERATED {sf160, sf256, sf320, sf512, + sf640, sf1024, sf1280, spare1} + +MeasSubframePatternConfigNeigh-r10 ::= CHOICE { + release NULL, + setup SEQUENCE { + measSubframePatternNeigh-r10 MeasSubframePattern-r10, + measSubframeCellList-r10 MeasSubframeCellList-r10 OPTIONAL -- Cond always + } +} + +MeasSubframeCellList-r10 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF PhysCellIdRange + +AltTTT-CellsToAddModList-r12 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF AltTTT-CellsToAddMod-r12 + +AltTTT-CellsToAddMod-r12 ::= SEQUENCE { + cellIndex-r12 INTEGER (1..maxCellMeas), + physCellIdRange-r12 PhysCellIdRange +} + +WhiteCellsToAddModList-r13 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF WhiteCellsToAddMod-r13 + +WhiteCellsToAddMod-r13 ::= SEQUENCE { + cellIndex-r13 INTEGER (1..maxCellMeas), + physCellIdRange-r13 PhysCellIdRange +} + +RMTC-Config-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + rmtc-Period-r13 ENUMERATED {ms40, ms80, ms160, ms320, ms640}, + rmtc-SubframeOffset-r13 INTEGER(0..639) OPTIONAL, -- Need ON + measDuration-r13 ENUMERATED {sym1, sym14, sym28, sym42, sym70}, + ... + } +} + + +MeasObjectGERAN ::= SEQUENCE { + carrierFreqs CarrierFreqsGERAN, + offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, + ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B, + cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON + ... +} + + +MeasObjectId ::= INTEGER (1..maxObjectId) + +MeasObjectId-v1310 ::= INTEGER (maxObjectId-Plus1-r13..maxObjectId-r13) + +MeasObjectId-r13 ::= INTEGER (1..maxObjectId-r13) + + +MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod + +MeasObjectToAddModListExt-r13 ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddModExt-r13 + +MeasObjectToAddModList-v9e0 ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod-v9e0 + +MeasObjectToAddMod ::= SEQUENCE { + measObjectId MeasObjectId, + measObject CHOICE { + measObjectEUTRA MeasObjectEUTRA, + measObjectUTRA MeasObjectUTRA, + measObjectGERAN MeasObjectGERAN, + measObjectCDMA2000 MeasObjectCDMA2000, + ..., + measObjectWLAN-r13 MeasObjectWLAN-r13 + } +} + +MeasObjectToAddModExt-r13 ::= SEQUENCE { + measObjectId-r13 MeasObjectId-v1310, + measObject-r13 CHOICE { + measObjectEUTRA-r13 MeasObjectEUTRA, + measObjectUTRA-r13 MeasObjectUTRA, + measObjectGERAN-r13 MeasObjectGERAN, + measObjectCDMA2000-r13 MeasObjectCDMA2000, + ..., + measObjectWLAN-v1320 MeasObjectWLAN-r13 + } +} + +MeasObjectToAddMod-v9e0 ::= SEQUENCE { + measObjectEUTRA-v9e0 MeasObjectEUTRA-v9e0 OPTIONAL -- Cond eutra +} + + +MeasObjectUTRA ::= SEQUENCE { + carrierFreq ARFCN-ValueUTRA, + offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, + cellsToRemoveList CellIndexList OPTIONAL, -- Need ON + cellsToAddModList CHOICE { + cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD, + cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD + } OPTIONAL, -- Need ON + cellForWhichToReportCGI CHOICE { + utra-FDD PhysCellIdUTRA-FDD, + utra-TDD PhysCellIdUTRA-TDD + } OPTIONAL, -- Need ON + ..., + [[ csg-allowedReportingCells-v930 CSG-AllowedReportingCells-r9 OPTIONAL -- Need ON + ]], + [[ reducedMeasPerformance-r12 BOOLEAN OPTIONAL -- Need ON + ]] +} + +CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD + +CellsToAddModUTRA-FDD ::= SEQUENCE { + cellIndex INTEGER (1..maxCellMeas), + physCellId PhysCellIdUTRA-FDD +} + +CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD + +CellsToAddModUTRA-TDD ::= SEQUENCE { + cellIndex INTEGER (1..maxCellMeas), + physCellId PhysCellIdUTRA-TDD +} + +CSG-AllowedReportingCells-r9 ::= SEQUENCE { + physCellIdRangeUTRA-FDDList-r9 PhysCellIdRangeUTRA-FDDList-r9 OPTIONAL -- Need OR +} + +MeasObjectWLAN-r13 ::= SEQUENCE { + carrierFreq-r13 CHOICE { + bandIndicatorListWLAN-r13 SEQUENCE (SIZE (1..maxWLAN-Bands-r13)) OF WLAN-BandIndicator-r13, + carrierInfoListWLAN-r13 SEQUENCE (SIZE (1..maxWLAN-CarrierInfo-r13)) OF WLAN-CarrierInfo-r13 + } OPTIONAL, -- Need ON + wlan-ToAddModList-r13 WLAN-Id-List-r13 OPTIONAL, -- Need ON + wlan-ToRemoveList-r13 WLAN-Id-List-r13 OPTIONAL, -- Need ON + ... +} + +WLAN-BandIndicator-r13 ::= ENUMERATED {band2dot4, band5, spare6, spare5, spare4, spare3, spare2, spare1, ...} + + +MeasResults ::= SEQUENCE { + measId MeasId, + measResultPCell SEQUENCE { + rsrpResult RSRP-Range, + rsrqResult RSRQ-Range + }, + measResultNeighCells CHOICE { + measResultListEUTRA MeasResultListEUTRA, + measResultListUTRA MeasResultListUTRA, + measResultListGERAN MeasResultListGERAN, + measResultsCDMA2000 MeasResultsCDMA2000, + ... + } OPTIONAL, + ..., + [[ measResultForECID-r9 MeasResultForECID-r9 OPTIONAL + ]], + [[ locationInfo-r10 LocationInfo-r10 OPTIONAL, + measResultServFreqList-r10 MeasResultServFreqList-r10 OPTIONAL + ]], + [[ measId-v1250 MeasId-v1250 OPTIONAL, + measResultPCell-v1250 RSRQ-Range-v1250 OPTIONAL, + measResultCSI-RS-List-r12 MeasResultCSI-RS-List-r12 OPTIONAL + ]], + [[ measResultForRSSI-r13 MeasResultForRSSI-r13 OPTIONAL, + measResultServFreqListExt-r13 MeasResultServFreqListExt-r13 OPTIONAL, + measResultSSTD-r13 MeasResultSSTD-r13 OPTIONAL, + measResultPCell-v1310 SEQUENCE { + rs-sinr-Result-r13 RS-SINR-Range-r13 + } OPTIONAL, + ul-PDCP-DelayResultList-r13 UL-PDCP-DelayResultList-r13 OPTIONAL, + measResultListWLAN-r13 MeasResultListWLAN-r13 OPTIONAL + ]] + +} + +MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA + +MeasResultEUTRA ::= SEQUENCE { + physCellId PhysCellId, + cgi-Info SEQUENCE { + cellGlobalId CellGlobalIdEUTRA, + trackingAreaCode TrackingAreaCode, + plmn-IdentityList PLMN-IdentityList2 OPTIONAL + } OPTIONAL, + measResult SEQUENCE { + rsrpResult RSRP-Range OPTIONAL, + rsrqResult RSRQ-Range OPTIONAL, + ..., + [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL + ]], + [[ primaryPLMN-Suitable-r12 ENUMERATED {true} OPTIONAL, + measResult-v1250 RSRQ-Range-v1250 OPTIONAL + ]], + [[ rs-sinr-Result-r13 RS-SINR-Range-r13 OPTIONAL, + cgi-Info-v1310 SEQUENCE { + freqBandIndicator-r13 FreqBandIndicator-r11 OPTIONAL, + multiBandInfoList-r13 MultiBandInfoList-r11 OPTIONAL, + freqBandIndicatorPriority-r13 ENUMERATED {true} OPTIONAL + } OPTIONAL + ]] + } +} + +MeasResultServFreqList-r10 ::= SEQUENCE (SIZE (1..maxServCell-r10)) OF MeasResultServFreq-r10 + +MeasResultServFreqListExt-r13 ::= SEQUENCE (SIZE (1..maxServCell-r13)) OF MeasResultServFreq-r13 + +MeasResultServFreq-r10 ::= SEQUENCE { + servFreqId-r10 ServCellIndex-r10, + measResultSCell-r10 SEQUENCE { + rsrpResultSCell-r10 RSRP-Range, + rsrqResultSCell-r10 RSRQ-Range + } OPTIONAL, + measResultBestNeighCell-r10 SEQUENCE { + physCellId-r10 PhysCellId, + rsrpResultNCell-r10 RSRP-Range, + rsrqResultNCell-r10 RSRQ-Range + } OPTIONAL, + ..., + [[ measResultSCell-v1250 RSRQ-Range-v1250 OPTIONAL, + measResultBestNeighCell-v1250 RSRQ-Range-v1250 OPTIONAL + ]], + [[ measResultSCell-v1310 SEQUENCE { + rs-sinr-Result-r13 RS-SINR-Range-r13 + } OPTIONAL, + measResultBestNeighCell-v1310 SEQUENCE { + rs-sinr-Result-r13 RS-SINR-Range-r13 + } OPTIONAL + ]] +} + +MeasResultServFreq-r13 ::= SEQUENCE { + servFreqId-r13 ServCellIndex-r13, + measResultSCell-r13 SEQUENCE { + rsrpResultSCell-r13 RSRP-Range, + rsrqResultSCell-r13 RSRQ-Range-r13, + rs-sinr-Result-r13 RS-SINR-Range-r13 OPTIONAL + } OPTIONAL, + measResultBestNeighCell-r13 SEQUENCE { + physCellId-r13 PhysCellId, + rsrpResultNCell-r13 RSRP-Range, + rsrqResultNCell-r13 RSRQ-Range-r13, + rs-sinr-Result-r13 RS-SINR-Range-r13 OPTIONAL + } OPTIONAL, + ... +} + +MeasResultCSI-RS-List-r12 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCSI-RS-r12 + +MeasResultCSI-RS-r12 ::= SEQUENCE { + measCSI-RS-Id-r12 MeasCSI-RS-Id-r12, + csi-RSRP-Result-r12 CSI-RSRP-Range-r12, + ... +} + +MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA + +MeasResultUTRA ::= SEQUENCE { + physCellId CHOICE { + fdd PhysCellIdUTRA-FDD, + tdd PhysCellIdUTRA-TDD + }, + cgi-Info SEQUENCE { + cellGlobalId CellGlobalIdUTRA, + locationAreaCode BIT STRING (SIZE (16)) OPTIONAL, + routingAreaCode BIT STRING (SIZE (8)) OPTIONAL, + plmn-IdentityList PLMN-IdentityList2 OPTIONAL + } OPTIONAL, + measResult SEQUENCE { + utra-RSCP INTEGER (-5..91) OPTIONAL, + utra-EcN0 INTEGER (0..49) OPTIONAL, + ..., + [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL + ]], + [[ primaryPLMN-Suitable-r12 ENUMERATED {true} OPTIONAL + ]] + } +} + +MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN + +MeasResultGERAN ::= SEQUENCE { + carrierFreq CarrierFreqGERAN, + physCellId PhysCellIdGERAN, + cgi-Info SEQUENCE { + cellGlobalId CellGlobalIdGERAN, + routingAreaCode BIT STRING (SIZE (8)) OPTIONAL + } OPTIONAL, + measResult SEQUENCE { + rssi INTEGER (0..63), + ... + } +} + +MeasResultsCDMA2000 ::= SEQUENCE { + preRegistrationStatusHRPD BOOLEAN, + measResultListCDMA2000 MeasResultListCDMA2000 +} + +MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000 + +MeasResultCDMA2000 ::= SEQUENCE { + physCellId PhysCellIdCDMA2000, + cgi-Info CellGlobalIdCDMA2000 OPTIONAL, + measResult SEQUENCE { + pilotPnPhase INTEGER (0..32767) OPTIONAL, + pilotStrength INTEGER (0..63), + ... + } +} + +MeasResultListWLAN-r13 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultWLAN-r13 + +MeasResultWLAN-r13 ::= SEQUENCE { + wlan-Identifiers-r13 WLAN-Identifiers-r12, + carrierInfoWLAN-r13 WLAN-CarrierInfo-r13 OPTIONAL, + bandWLAN-r13 WLAN-BandIndicator-r13 OPTIONAL, + rssiWLAN-r13 WLAN-RSSI-Range-r13, + availableAdmissionCapacityWLAN-r13 INTEGER (0..31250) OPTIONAL, + backhaulDL-BandwidthWLAN-r13 WLAN-backhaulRate-r12 OPTIONAL, + backhaulUL-BandwidthWLAN-r13 WLAN-backhaulRate-r12 OPTIONAL, + channelUtilizationWLAN-r13 INTEGER (0..255) OPTIONAL, + stationCountWLAN-r13 INTEGER (0..65535) OPTIONAL, + connectedWLAN-r13 ENUMERATED {true} OPTIONAL, + ... +} + +MeasResultForECID-r9 ::= SEQUENCE { + ue-RxTxTimeDiffResult-r9 INTEGER (0..4095), + currentSFN-r9 BIT STRING (SIZE (10)) +} + +PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity + +AdditionalSI-Info-r9 ::= SEQUENCE { + csg-MemberStatus-r9 ENUMERATED {member} OPTIONAL, + csg-Identity-r9 CSG-Identity OPTIONAL +} +MeasResultForRSSI-r13 ::= SEQUENCE { + rssi-Result-r13 RSSI-Range-r13, + channelOccupancy-r13 INTEGER (0..100), + ... +} + +UL-PDCP-DelayResultList-r13 ::= SEQUENCE (SIZE (1..maxQCI-r13)) OF UL-PDCP-DelayResult-r13 + + +UL-PDCP-DelayResult-r13 ::= SEQUENCE { + qci-Id-r13 ENUMERATED {qci1, qci2, qci3, qci4, spare4, spare3, spare2, spare1}, + excessDelay-r13 INTEGER (0..31), + ... +} + + +MeasResultSSTD-r13 ::= SEQUENCE { + sfn-OffsetResult-r13 INTEGER (0..1023), + frameBoundaryOffsetResult-r13 INTEGER (-5..4), + subframeBoundaryOffsetResult-r13 INTEGER (0..127) +} + + +MeasScaleFactor-r12 ::= ENUMERATED {sf-EUTRA-cf1, sf-EUTRA-cf2} + + +QuantityConfig ::= SEQUENCE { + quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON + quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON + quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON + quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON + ..., + [[ quantityConfigUTRA-v1020 QuantityConfigUTRA-v1020 OPTIONAL -- Need ON + ]], + [[ quantityConfigEUTRA-v1250 QuantityConfigEUTRA-v1250 OPTIONAL -- Need ON + ]], + [[ quantityConfigEUTRA-v1310 QuantityConfigEUTRA-v1310 OPTIONAL, -- Need ON + quantityConfigWLAN-r13 QuantityConfigWLAN-r13 OPTIONAL -- Need ON + ]] +} + +QuantityConfigEUTRA ::= SEQUENCE { + filterCoefficientRSRP FilterCoefficient DEFAULT fc4, + filterCoefficientRSRQ FilterCoefficient DEFAULT fc4 +} + +QuantityConfigEUTRA-v1250 ::= SEQUENCE { + filterCoefficientCSI-RSRP-r12 FilterCoefficient OPTIONAL -- Need OR +} + +QuantityConfigEUTRA-v1310 ::= SEQUENCE { + filterCoefficientRS-SINR-r13 FilterCoefficient DEFAULT fc4 +} + +QuantityConfigUTRA ::= SEQUENCE { + measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0}, + measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP}, + filterCoefficient FilterCoefficient DEFAULT fc4 +} + +QuantityConfigUTRA-v1020 ::= SEQUENCE { + filterCoefficient2-FDD-r10 FilterCoefficient DEFAULT fc4 +} + +QuantityConfigGERAN ::= SEQUENCE { + measQuantityGERAN ENUMERATED {rssi}, + filterCoefficient FilterCoefficient DEFAULT fc2 +} + +QuantityConfigCDMA2000 ::= SEQUENCE { + measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength} +} + +QuantityConfigWLAN-r13 ::= SEQUENCE { + measQuantityWLAN-r13 ENUMERATED {rssiWLAN}, + filterCoefficient-r13 FilterCoefficient DEFAULT fc4 +} + + +ReportConfigEUTRA ::= SEQUENCE { + triggerType CHOICE { + event SEQUENCE { + eventId CHOICE { + eventA1 SEQUENCE { + a1-Threshold ThresholdEUTRA + }, + eventA2 SEQUENCE { + a2-Threshold ThresholdEUTRA + }, + eventA3 SEQUENCE { + a3-Offset INTEGER (-30..30), + reportOnLeave BOOLEAN + }, + eventA4 SEQUENCE { + a4-Threshold ThresholdEUTRA + }, + eventA5 SEQUENCE { + a5-Threshold1 ThresholdEUTRA, + a5-Threshold2 ThresholdEUTRA + }, + ..., + eventA6-r10 SEQUENCE { + a6-Offset-r10 INTEGER (-30..30), + a6-ReportOnLeave-r10 BOOLEAN + }, + eventC1-r12 SEQUENCE { + c1-Threshold-r12 ThresholdEUTRA-v1250, + c1-ReportOnLeave-r12 BOOLEAN + }, + eventC2-r12 SEQUENCE { + c2-RefCSI-RS-r12 MeasCSI-RS-Id-r12, + c2-Offset-r12 INTEGER (-30..30), + c2-ReportOnLeave-r12 BOOLEAN + } + }, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger + }, + periodical SEQUENCE { + purpose ENUMERATED { + reportStrongestCells, reportCGI} + } + }, + triggerQuantity ENUMERATED {rsrp, rsrq}, + reportQuantity ENUMERATED {sameAsTriggerQuantity, both}, + maxReportCells INTEGER (1..maxCellReport), + reportInterval ReportInterval, + reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + ..., + [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL, -- Cond reportCGI + ue-RxTxTimeDiffPeriodical-r9 ENUMERATED {setup} OPTIONAL -- Need OR + ]], + [[ includeLocationInfo-r10 ENUMERATED {true} OPTIONAL, -- Need OR + reportAddNeighMeas-r10 ENUMERATED {setup} OPTIONAL -- Need OR + ]], + [[ alternativeTimeToTrigger-r12 CHOICE { + release NULL, + setup TimeToTrigger + } OPTIONAL, -- Need ON + useT312-r12 BOOLEAN OPTIONAL, -- Need ON + usePSCell-r12 BOOLEAN OPTIONAL, -- Need ON + aN-Threshold1-v1250 RSRQ-RangeConfig-r12 OPTIONAL, -- Need ON + a5-Threshold2-v1250 RSRQ-RangeConfig-r12 OPTIONAL, -- Need ON + reportStrongestCSI-RSs-r12 BOOLEAN OPTIONAL, -- Need ON + reportCRS-Meas-r12 BOOLEAN OPTIONAL, -- Need ON + triggerQuantityCSI-RS-r12 BOOLEAN OPTIONAL -- Need ON + ]], + [[ reportSSTD-Meas-r13 BOOLEAN OPTIONAL, -- Need ON + rs-sinr-Config-r13 CHOICE { + release NULL, + setup SEQUENCE { + triggerQuantity-v1310 ENUMERATED {sinr} OPTIONAL, -- Need ON + aN-Threshold1-r13 RS-SINR-Range-r13 OPTIONAL, -- Need ON + a5-Threshold2-r13 RS-SINR-Range-r13 OPTIONAL, -- Need ON + reportQuantity-v1310 ENUMERATED {rsrpANDsinr, rsrqANDsinr, all} + } + } OPTIONAL, -- Need ON + useWhiteCellList-r13 BOOLEAN OPTIONAL, -- Need ON + measRSSI-ReportConfig-r13 MeasRSSI-ReportConfig-r13 OPTIONAL, -- Need ON + includeMultiBandInfo-r13 ENUMERATED {true} OPTIONAL, -- Cond reportCGI + ul-DelayConfig-r13 UL-DelayConfig-r13 OPTIONAL -- Need ON + ]], + [[ ue-RxTxTimeDiffPeriodicalTDD-r13 BOOLEAN OPTIONAL -- Need ON + ]] +} + +RSRQ-RangeConfig-r12 ::= CHOICE { + release NULL, + setup RSRQ-Range-v1250 +} + +ThresholdEUTRA ::= CHOICE{ + threshold-RSRP RSRP-Range, + threshold-RSRQ RSRQ-Range +} + +ThresholdEUTRA-v1250 ::= CSI-RSRP-Range-r12 + +MeasRSSI-ReportConfig-r13 ::= SEQUENCE { + channelOccupancyThreshold-r13 RSSI-Range-r13 OPTIONAL -- Need OR +} + + +ReportConfigId ::= INTEGER (1..maxReportConfigId) + + +ReportConfigInterRAT ::= SEQUENCE { + triggerType CHOICE { + event SEQUENCE { + eventId CHOICE { + eventB1 SEQUENCE { + b1-Threshold CHOICE { + b1-ThresholdUTRA ThresholdUTRA, + b1-ThresholdGERAN ThresholdGERAN, + b1-ThresholdCDMA2000 ThresholdCDMA2000 + } + }, + eventB2 SEQUENCE { + b2-Threshold1 ThresholdEUTRA, + b2-Threshold2 CHOICE { + b2-Threshold2UTRA ThresholdUTRA, + b2-Threshold2GERAN ThresholdGERAN, + b2-Threshold2CDMA2000 ThresholdCDMA2000 + } + }, + ..., + eventW1-r13 SEQUENCE { + w1-Threshold-r13 WLAN-RSSI-Range-r13 + }, + eventW2-r13 SEQUENCE { + w2-Threshold1-r13 WLAN-RSSI-Range-r13, + w2-Threshold2-r13 WLAN-RSSI-Range-r13 + }, + eventW3-r13 SEQUENCE { + w3-Threshold-r13 WLAN-RSSI-Range-r13 + } + }, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger + }, + periodical SEQUENCE { + purpose ENUMERATED { + reportStrongestCells, + reportStrongestCellsForSON, + reportCGI} + } + }, + maxReportCells INTEGER (1..maxCellReport), + reportInterval ReportInterval, + reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + ..., + [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL -- Cond reportCGI + ]], + [[ reportQuantityUTRA-FDD-r10 ENUMERATED {both} OPTIONAL -- Need OR + ]], + [[ includeLocationInfo-r11 BOOLEAN OPTIONAL -- Need ON + ]], + [[ b2-Threshold1-v1250 CHOICE { + release NULL, + setup RSRQ-Range-v1250 + } OPTIONAL -- Need ON + ]], + [[ reportQuantityWLAN-r13 ReportQuantityWLAN-r13 OPTIONAL -- Need ON + ]] +} + +ThresholdUTRA ::= CHOICE{ + utra-RSCP INTEGER (-5..91), + utra-EcN0 INTEGER (0..49) +} + +ThresholdGERAN ::= INTEGER (0..63) + +ThresholdCDMA2000 ::= INTEGER (0..63) + +ReportQuantityWLAN-r13 ::= SEQUENCE { + bandRequestWLAN-r13 ENUMERATED {true} OPTIONAL, -- Need OR + carrierInfoRequestWLAN-r13 ENUMERATED {true} OPTIONAL, -- Need OR + availableAdmissionCapacityRequestWLAN-r13 ENUMERATED {true} OPTIONAL, -- Need ON + backhaulDL-BandwidthRequestWLAN-r13 ENUMERATED {true} OPTIONAL, -- Need OR + backhaulUL-BandwidthRequestWLAN-r13 ENUMERATED {true} OPTIONAL, -- Need OR + channelUtilizationRequestWLAN-r13 ENUMERATED {true} OPTIONAL, -- Need OR + stationCountRequestWLAN-r13 ENUMERATED {true} OPTIONAL , -- Need OR + ... +} + + +ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod + +ReportConfigToAddMod ::= SEQUENCE { + reportConfigId ReportConfigId, + reportConfig CHOICE { + reportConfigEUTRA ReportConfigEUTRA, + reportConfigInterRAT ReportConfigInterRAT + } +} + + + +ReportInterval ::= ENUMERATED { + ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240, + min1, min6, min12, min30, min60, spare3, spare2, spare1} + + +RSRP-Range ::= INTEGER(0..97) + +RSRP-RangeSL-r12 ::= INTEGER(0..13) + +RSRP-RangeSL2-r12 ::= INTEGER(0..7) + +RSRP-RangeSL3-r12 ::= INTEGER(0..11) + +RSRP-RangeSL4-r13 ::= INTEGER(0..49) + + +RSRQ-Range ::= INTEGER(0..34) + +RSRQ-Range-v1250 ::= INTEGER(-30..46) + +RSRQ-Range-r13 ::= INTEGER(-30..46) + + +RSRQ-Type-r12 ::= SEQUENCE { + allSymbols-r12 BOOLEAN, + wideBand-r12 BOOLEAN +} + + +RS-SINR-Range-r13 ::= INTEGER(0..127) + + +RSSI-Range-r13 ::= INTEGER(0..76) + + +TimeToTrigger ::= ENUMERATED { + ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256, + ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560, + ms5120} + + +UL-DelayConfig-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + delayThreshold-r13 ENUMERATED { + ms30, ms40, ms50, ms60, ms70, ms80, + ms90,ms100, ms150, ms300, ms500, ms750, spare4, spare3, spare2, spare1} + } +} + + +WLAN-CarrierInfo-r13 ::= SEQUENCE { + operatingClass-r13 INTEGER (0..255) OPTIONAL, -- Need ON + countryCode-r13 ENUMERATED {unitedStates, europe, japan, global, ...} OPTIONAL, -- Need ON + channelNumbers-r13 WLAN-ChannelList-r13 OPTIONAL, -- Need ON + ... +} + +WLAN-ChannelList-r13 ::= SEQUENCE (SIZE (1..maxWLAN-Channels-r13)) OF WLAN-Channel-r13 + +WLAN-Channel-r13 ::= INTEGER(0..255) + + +WLAN-RSSI-Range-r13 ::= INTEGER(0..141) + + +WLAN-Status-r13 ::= ENUMERATED {successfulAssociation, failureWlanRadioLink, failureWlanUnavailable, failureTimeout} + + +AbsoluteTimeInfo-r10 ::= BIT STRING (SIZE (48)) + + +AreaConfiguration-r10 ::= CHOICE { + cellGlobalIdList-r10 CellGlobalIdList-r10, + trackingAreaCodeList-r10 TrackingAreaCodeList-r10 +} + +AreaConfiguration-v1130 ::= SEQUENCE { + trackingAreaCodeList-v1130 TrackingAreaCodeList-v1130 +} + +CellGlobalIdList-r10 ::= SEQUENCE (SIZE (1..32)) OF CellGlobalIdEUTRA + +TrackingAreaCodeList-r10 ::= SEQUENCE (SIZE (1..8)) OF TrackingAreaCode + +TrackingAreaCodeList-v1130 ::= SEQUENCE { + plmn-Identity-perTAC-List-r11 SEQUENCE (SIZE (1..8)) OF PLMN-Identity +} + + +C-RNTI ::= BIT STRING (SIZE (16)) + + +DedicatedInfoCDMA2000 ::= OCTET STRING + + +DedicatedInfoNAS ::= OCTET STRING + + +FilterCoefficient ::= ENUMERATED { + fc0, fc1, fc2, fc3, fc4, fc5, + fc6, fc7, fc8, fc9, fc11, fc13, + fc15, fc17, fc19, spare1, ...} + + +LoggingDuration-r10 ::= ENUMERATED { + min10, min20, min40, min60, min90, min120, spare2, spare1} + + +LoggingInterval-r10 ::= ENUMERATED { + ms1280, ms2560, ms5120, ms10240, ms20480, + ms30720, ms40960, ms61440} + + +MeasSubframePattern-r10 ::= CHOICE { + subframePatternFDD-r10 BIT STRING (SIZE (40)), + subframePatternTDD-r10 CHOICE { + subframeConfig1-5-r10 BIT STRING (SIZE (20)), + subframeConfig0-r10 BIT STRING (SIZE (70)), + subframeConfig6-r10 BIT STRING (SIZE (60)), + ... + }, + ... +} + + +MMEC ::= BIT STRING (SIZE (8)) + + +NeighCellConfig ::= BIT STRING (SIZE (2)) + + +OtherConfig-r9 ::= SEQUENCE { + reportProximityConfig-r9 ReportProximityConfig-r9 OPTIONAL, -- Need ON + ..., + [[ idc-Config-r11 IDC-Config-r11 OPTIONAL, -- Need ON + powerPrefIndicationConfig-r11 PowerPrefIndicationConfig-r11 OPTIONAL, -- Need ON + obtainLocationConfig-r11 ObtainLocationConfig-r11 OPTIONAL -- Need ON + ]] +} + +IDC-Config-r11 ::= SEQUENCE { + idc-Indication-r11 ENUMERATED {setup} OPTIONAL, -- Need OR + autonomousDenialParameters-r11 SEQUENCE { + autonomousDenialSubframes-r11 ENUMERATED {n2, n5, n10, n15, + n20, n30, spare2, spare1}, + autonomousDenialValidity-r11 ENUMERATED { + sf200, sf500, sf1000, sf2000, + spare4, spare3, spare2, spare1} + } OPTIONAL, -- Need OR + ..., + [[ idc-Indication-UL-CA-r11 ENUMERATED {setup} OPTIONAL -- Cond idc-Ind + ]] +} + +ObtainLocationConfig-r11 ::= SEQUENCE { + obtainLocation-r11 ENUMERATED {setup} OPTIONAL -- Need OR +} + +PowerPrefIndicationConfig-r11 ::= CHOICE{ + release NULL, + setup SEQUENCE{ + powerPrefIndicationTimer-r11 ENUMERATED {s0, s0dot5, s1, s2, s5, s10, s20, + s30, s60, s90, s120, s300, s600, spare3, + spare2, spare1} + } +} + +ReportProximityConfig-r9 ::= SEQUENCE { + proximityIndicationEUTRA-r9 ENUMERATED {enabled} OPTIONAL, -- Need OR + proximityIndicationUTRA-r9 ENUMERATED {enabled} OPTIONAL -- Need OR +} + + +RAND-CDMA2000 ::= BIT STRING (SIZE (32)) + + +RAT-Type ::= ENUMERATED { + eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT, + spare3, spare2, spare1, ...} + + +ResumeIdentity-r13 ::= BIT STRING (SIZE(40)) + + +RRC-TransactionIdentifier ::= INTEGER (0..3) + + +S-TMSI ::= SEQUENCE { + mmec MMEC, + m-TMSI BIT STRING (SIZE (32)) +} + + +TraceReference-r10 ::= SEQUENCE { + plmn-Identity-r10 PLMN-Identity, + traceId-r10 OCTET STRING (SIZE (3)) +} + + +UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container + +UE-CapabilityRAT-Container ::= SEQUENCE { + rat-Type RAT-Type, + ueCapabilityRAT-Container OCTET STRING +} + + +UE-EUTRA-Capability ::= SEQUENCE { + accessStratumRelease AccessStratumRelease, + ue-Category INTEGER (1..5), + pdcp-Parameters PDCP-Parameters, + phyLayerParameters PhyLayerParameters, + rf-Parameters RF-Parameters, + measParameters MeasParameters, + featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL, + interRAT-Parameters SEQUENCE { + utraFDD IRAT-ParametersUTRA-FDD OPTIONAL, + utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL, + utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL, + utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL, + geran IRAT-ParametersGERAN OPTIONAL, + cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL, + cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL + }, + nonCriticalExtension UE-EUTRA-Capability-v920-IEs OPTIONAL +} + +-- Late non critical extensions +UE-EUTRA-Capability-v9a0-IEs ::= SEQUENCE { + featureGroupIndRel9Add-r9 BIT STRING (SIZE (32)) OPTIONAL, + fdd-Add-UE-EUTRA-Capabilities-r9 UE-EUTRA-CapabilityAddXDD-Mode-r9 OPTIONAL, + tdd-Add-UE-EUTRA-Capabilities-r9 UE-EUTRA-CapabilityAddXDD-Mode-r9 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v9c0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v9c0-IEs ::= SEQUENCE { + interRAT-ParametersUTRA-v9c0 IRAT-ParametersUTRA-v9c0 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v9d0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v9d0-IEs ::= SEQUENCE { + phyLayerParameters-v9d0 PhyLayerParameters-v9d0 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v9e0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v9e0-IEs ::= SEQUENCE { + rf-Parameters-v9e0 RF-Parameters-v9e0 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v9h0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v9h0-IEs ::= SEQUENCE { + interRAT-ParametersUTRA-v9h0 IRAT-ParametersUTRA-v9h0 OPTIONAL, + -- Following field is only to be used for late REL-9 extensions + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v10c0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v10c0-IEs ::= SEQUENCE { + otdoa-PositioningCapabilities-r10 OTDOA-PositioningCapabilities-r10 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v10f0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v10f0-IEs ::= SEQUENCE { + rf-Parameters-v10f0 RF-Parameters-v10f0 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v10i0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v10i0-IEs ::= SEQUENCE { + rf-Parameters-v10i0 RF-Parameters-v10i0 OPTIONAL, + -- Following field is only to be used for late REL-10 extensions + lateNonCriticalExtension OCTET STRING (CONTAINING UE-EUTRA-Capability-v10j0-IEs) OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v11d0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v10j0-IEs ::= SEQUENCE { + rf-Parameters-v10j0 RF-Parameters-v10j0 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +UE-EUTRA-Capability-v11d0-IEs ::= SEQUENCE { + rf-Parameters-v11d0 RF-Parameters-v11d0 OPTIONAL, + otherParameters-v11d0 Other-Parameters-v11d0 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v11x0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v11x0-IEs ::= SEQUENCE { + -- Following field is only to be used for late REL-11 extensions + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v12b0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v12b0-IEs ::= SEQUENCE { + rf-Parameters-v12b0 RF-Parameters-v12b0 OPTIONAL, + -- Following field is only to be used for late REL-12 extensions + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- Regular non critical extensions +UE-EUTRA-Capability-v920-IEs ::= SEQUENCE { + phyLayerParameters-v920 PhyLayerParameters-v920, + interRAT-ParametersGERAN-v920 IRAT-ParametersGERAN-v920, + interRAT-ParametersUTRA-v920 IRAT-ParametersUTRA-v920 OPTIONAL, + interRAT-ParametersCDMA2000-v920 IRAT-ParametersCDMA2000-1XRTT-v920 OPTIONAL, + deviceType-r9 ENUMERATED {noBenFromBatConsumpOpt} OPTIONAL, + csg-ProximityIndicationParameters-r9 CSG-ProximityIndicationParameters-r9, + neighCellSI-AcquisitionParameters-r9 NeighCellSI-AcquisitionParameters-r9, + son-Parameters-r9 SON-Parameters-r9, + nonCriticalExtension UE-EUTRA-Capability-v940-IEs OPTIONAL +} + +UE-EUTRA-Capability-v940-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING (CONTAINING UE-EUTRA-Capability-v9a0-IEs) + OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1020-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1020-IEs ::= SEQUENCE { + ue-Category-v1020 INTEGER (6..8) OPTIONAL, + phyLayerParameters-v1020 PhyLayerParameters-v1020 OPTIONAL, + rf-Parameters-v1020 RF-Parameters-v1020 OPTIONAL, + measParameters-v1020 MeasParameters-v1020 OPTIONAL, + featureGroupIndRel10-r10 BIT STRING (SIZE (32)) OPTIONAL, + interRAT-ParametersCDMA2000-v1020 IRAT-ParametersCDMA2000-1XRTT-v1020 OPTIONAL, + ue-BasedNetwPerfMeasParameters-r10 UE-BasedNetwPerfMeasParameters-r10 OPTIONAL, + interRAT-ParametersUTRA-TDD-v1020 IRAT-ParametersUTRA-TDD-v1020 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1060-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1060-IEs ::= SEQUENCE { + fdd-Add-UE-EUTRA-Capabilities-v1060 UE-EUTRA-CapabilityAddXDD-Mode-v1060 OPTIONAL, + tdd-Add-UE-EUTRA-Capabilities-v1060 UE-EUTRA-CapabilityAddXDD-Mode-v1060 OPTIONAL, + rf-Parameters-v1060 RF-Parameters-v1060 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1090-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1090-IEs ::= SEQUENCE { + rf-Parameters-v1090 RF-Parameters-v1090 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1130-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1130-IEs ::= SEQUENCE { + pdcp-Parameters-v1130 PDCP-Parameters-v1130, + phyLayerParameters-v1130 PhyLayerParameters-v1130 OPTIONAL, + rf-Parameters-v1130 RF-Parameters-v1130, + measParameters-v1130 MeasParameters-v1130, + interRAT-ParametersCDMA2000-v1130 IRAT-ParametersCDMA2000-v1130, + otherParameters-r11 Other-Parameters-r11, + fdd-Add-UE-EUTRA-Capabilities-v1130 UE-EUTRA-CapabilityAddXDD-Mode-v1130 OPTIONAL, + tdd-Add-UE-EUTRA-Capabilities-v1130 UE-EUTRA-CapabilityAddXDD-Mode-v1130 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1170-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1170-IEs ::= SEQUENCE { + phyLayerParameters-v1170 PhyLayerParameters-v1170 OPTIONAL, + ue-Category-v1170 INTEGER (9..10) OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1180-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1180-IEs ::= SEQUENCE { + rf-Parameters-v1180 RF-Parameters-v1180 OPTIONAL, + mbms-Parameters-r11 MBMS-Parameters-r11 OPTIONAL, + fdd-Add-UE-EUTRA-Capabilities-v1180 UE-EUTRA-CapabilityAddXDD-Mode-v1180 OPTIONAL, + tdd-Add-UE-EUTRA-Capabilities-v1180 UE-EUTRA-CapabilityAddXDD-Mode-v1180 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v11a0-IEs OPTIONAL +} + +UE-EUTRA-Capability-v11a0-IEs ::= SEQUENCE { + ue-Category-v11a0 INTEGER (11..12) OPTIONAL, + measParameters-v11a0 MeasParameters-v11a0 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1250-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1250-IEs ::= SEQUENCE { + phyLayerParameters-v1250 PhyLayerParameters-v1250 OPTIONAL, + rf-Parameters-v1250 RF-Parameters-v1250 OPTIONAL, + rlc-Parameters-r12 RLC-Parameters-r12 OPTIONAL, + ue-BasedNetwPerfMeasParameters-v1250 UE-BasedNetwPerfMeasParameters-v1250 OPTIONAL, + ue-CategoryDL-r12 INTEGER (0..14) OPTIONAL, + ue-CategoryUL-r12 INTEGER (0..13) OPTIONAL, + wlan-IW-Parameters-r12 WLAN-IW-Parameters-r12 OPTIONAL, + measParameters-v1250 MeasParameters-v1250 OPTIONAL, + dc-Parameters-r12 DC-Parameters-r12 OPTIONAL, + mbms-Parameters-v1250 MBMS-Parameters-v1250 OPTIONAL, + mac-Parameters-r12 MAC-Parameters-r12 OPTIONAL, + fdd-Add-UE-EUTRA-Capabilities-v1250 UE-EUTRA-CapabilityAddXDD-Mode-v1250 OPTIONAL, + tdd-Add-UE-EUTRA-Capabilities-v1250 UE-EUTRA-CapabilityAddXDD-Mode-v1250 OPTIONAL, + sl-Parameters-r12 SL-Parameters-r12 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1260-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1260-IEs ::= SEQUENCE { + ue-CategoryDL-v1260 INTEGER (15..16) OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1270-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1270-IEs ::= SEQUENCE { + rf-Parameters-v1270 RF-Parameters-v1270 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1280-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1280-IEs ::= SEQUENCE { + phyLayerParameters-v1280 PhyLayerParameters-v1280 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1310-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1310-IEs ::= SEQUENCE { + ue-CategoryDL-v1310 ENUMERATED {n17, m1} OPTIONAL, + ue-CategoryUL-v1310 ENUMERATED {n14, m1} OPTIONAL, + pdcp-Parameters-v1310 PDCP-Parameters-v1310, + rlc-Parameters-v1310 RLC-Parameters-v1310, + mac-Parameters-v1310 MAC-Parameters-v1310 OPTIONAL, + phyLayerParameters-v1310 PhyLayerParameters-v1310 OPTIONAL, + rf-Parameters-v1310 RF-Parameters-v1310 OPTIONAL, + measParameters-v1310 MeasParameters-v1310 OPTIONAL, + dc-Parameters-v1310 DC-Parameters-v1310 OPTIONAL, + sl-Parameters-v1310 SL-Parameters-v1310 OPTIONAL, + scptm-Parameters-r13 SCPTM-Parameters-r13 OPTIONAL, + ce-Parameters-r13 CE-Parameters-r13 OPTIONAL, + interRAT-ParametersWLAN-r13 IRAT-ParametersWLAN-r13, + laa-Parameters-r13 LAA-Parameters-r13 OPTIONAL, + lwa-Parameters-r13 LWA-Parameters-r13 OPTIONAL, + wlan-IW-Parameters-v1310 WLAN-IW-Parameters-v1310, + lwip-Parameters-r13 LWIP-Parameters-r13, + fdd-Add-UE-EUTRA-Capabilities-v1310 UE-EUTRA-CapabilityAddXDD-Mode-v1310 OPTIONAL, + tdd-Add-UE-EUTRA-Capabilities-v1310 UE-EUTRA-CapabilityAddXDD-Mode-v1310 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1320-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1320-IEs ::= SEQUENCE { + ce-Parameters-v1320 CE-Parameters-v1320 OPTIONAL, + phyLayerParameters-v1320 PhyLayerParameters-v1320 OPTIONAL, + rf-Parameters-v1320 RF-Parameters-v1320 OPTIONAL, + fdd-Add-UE-EUTRA-Capabilities-v1320 UE-EUTRA-CapabilityAddXDD-Mode-v1320 OPTIONAL, + tdd-Add-UE-EUTRA-Capabilities-v1320 UE-EUTRA-CapabilityAddXDD-Mode-v1320 OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1330-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1330-IEs ::= SEQUENCE { + ue-CategoryDL-v1330 INTEGER (18..19) OPTIONAL, + phyLayerParameters-v1330 PhyLayerParameters-v1330 OPTIONAL, + ue-CE-NeedULGaps-r13 ENUMERATED {true} OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v1340-IEs OPTIONAL +} + +UE-EUTRA-Capability-v1340-IEs ::= SEQUENCE { + ue-CategoryUL-v1340 INTEGER (15) OPTIONAL, + nonCriticalExtension UE-EUTRA-Capability-v14xy-IEs OPTIONAL +} + +UE-EUTRA-Capability-v14xy-IEs ::= SEQUENCE { + mac-Parameters-v14xy MAC-Parameters-v14xy OPTIONAL, + rlc-Parameters-v14xy RLC-Parameters-v14xy, + laa-Parameters-v14xy LAA-Parameters-v14xy OPTIONAL, + lwip-Parameters-v14xy LWIP-Parameters-v14xy OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +UE-EUTRA-CapabilityAddXDD-Mode-r9 ::= SEQUENCE { + phyLayerParameters-r9 PhyLayerParameters OPTIONAL, + featureGroupIndicators-r9 BIT STRING (SIZE (32)) OPTIONAL, + featureGroupIndRel9Add-r9 BIT STRING (SIZE (32)) OPTIONAL, + interRAT-ParametersGERAN-r9 IRAT-ParametersGERAN OPTIONAL, + interRAT-ParametersUTRA-r9 IRAT-ParametersUTRA-v920 OPTIONAL, + interRAT-ParametersCDMA2000-r9 IRAT-ParametersCDMA2000-1XRTT-v920 OPTIONAL, + neighCellSI-AcquisitionParameters-r9 NeighCellSI-AcquisitionParameters-r9 OPTIONAL, + ... +} + +UE-EUTRA-CapabilityAddXDD-Mode-v1060 ::= SEQUENCE { + phyLayerParameters-v1060 PhyLayerParameters-v1020 OPTIONAL, + featureGroupIndRel10-v1060 BIT STRING (SIZE (32)) OPTIONAL, + interRAT-ParametersCDMA2000-v1060 IRAT-ParametersCDMA2000-1XRTT-v1020 OPTIONAL, + interRAT-ParametersUTRA-TDD-v1060 IRAT-ParametersUTRA-TDD-v1020 OPTIONAL, + ..., + [[ otdoa-PositioningCapabilities-r10 OTDOA-PositioningCapabilities-r10 OPTIONAL + ]] +} + +UE-EUTRA-CapabilityAddXDD-Mode-v1130 ::= SEQUENCE { + phyLayerParameters-v1130 PhyLayerParameters-v1130 OPTIONAL, + measParameters-v1130 MeasParameters-v1130 OPTIONAL, + otherParameters-r11 Other-Parameters-r11 OPTIONAL, + ... +} + +UE-EUTRA-CapabilityAddXDD-Mode-v1180 ::= SEQUENCE { + mbms-Parameters-r11 MBMS-Parameters-r11 +} + +UE-EUTRA-CapabilityAddXDD-Mode-v1250 ::= SEQUENCE { + phyLayerParameters-v1250 PhyLayerParameters-v1250 OPTIONAL, + measParameters-v1250 MeasParameters-v1250 OPTIONAL +} + +UE-EUTRA-CapabilityAddXDD-Mode-v1310 ::= SEQUENCE { + phyLayerParameters-v1310 PhyLayerParameters-v1310 OPTIONAL +} + +UE-EUTRA-CapabilityAddXDD-Mode-v1320 ::= SEQUENCE { + phyLayerParameters-v1320 PhyLayerParameters-v1320 OPTIONAL, + scptm-Parameters-r13 SCPTM-Parameters-r13 OPTIONAL +} + +AccessStratumRelease ::= ENUMERATED { + rel8, rel9, rel10, rel11, rel12, rel13, + spare2, spare1, ...} + +DC-Parameters-r12 ::= SEQUENCE { + drb-TypeSplit-r12 ENUMERATED {supported} OPTIONAL, + drb-TypeSCG-r12 ENUMERATED {supported} OPTIONAL +} + +DC-Parameters-v1310 ::= SEQUENCE { + pdcp-TransferSplitUL-r13 ENUMERATED {supported} OPTIONAL, + ue-SSTD-Meas-r13 ENUMERATED {supported} OPTIONAL +} + +MAC-Parameters-r12 ::= SEQUENCE { + logicalChannelSR-ProhibitTimer-r12 ENUMERATED {supported} OPTIONAL, + longDRX-Command-r12 ENUMERATED {supported} OPTIONAL +} + +MAC-Parameters-v1310 ::= SEQUENCE { + extendedMAC-LengthField-r13 ENUMERATED {supported} OPTIONAL, + extendedLongDRX-r13 ENUMERATED {supported} OPTIONAL +} + +MAC-Parameters-v14xy ::= SEQUENCE { + shortSPS-IntervalFDD-r14 ENUMERATED {supported} OPTIONAL, + shortSPS-IntervalTDD-r14 ENUMERATED {supported} OPTIONAL, + skipUplinkDynamic-r14 ENUMERATED {supported} OPTIONAL, + skipUplinkSPS-r14 ENUMERATED {supported} OPTIONAL +} + +RLC-Parameters-r12 ::= SEQUENCE { + extended-RLC-LI-Field-r12 ENUMERATED {supported} +} + +RLC-Parameters-v1310 ::= SEQUENCE { + extendedRLC-SN-SO-Field-r13 ENUMERATED {supported} OPTIONAL +} + +RLC-Parameters-v14xy ::= SEQUENCE { + extendedPollByte-r14 ENUMERATED {supported} OPTIONAL +} + +PDCP-Parameters ::= SEQUENCE { + supportedROHC-Profiles SEQUENCE { + profile0x0001 BOOLEAN, + profile0x0002 BOOLEAN, + profile0x0003 BOOLEAN, + profile0x0004 BOOLEAN, + profile0x0006 BOOLEAN, + profile0x0101 BOOLEAN, + profile0x0102 BOOLEAN, + profile0x0103 BOOLEAN, + profile0x0104 BOOLEAN + }, + maxNumberROHC-ContextSessions ENUMERATED { + cs2, cs4, cs8, cs12, cs16, cs24, cs32, + cs48, cs64, cs128, cs256, cs512, cs1024, + cs16384, spare2, spare1} DEFAULT cs16, + ... +} + +PDCP-Parameters-v1130 ::= SEQUENCE { + pdcp-SN-Extension-r11 ENUMERATED {supported} OPTIONAL, + supportRohcContextContinue-r11 ENUMERATED {supported} OPTIONAL +} + +PDCP-Parameters-v1310 ::= SEQUENCE { + pdcp-SN-Extension-18bits-r13 ENUMERATED {supported} OPTIONAL +} + +PhyLayerParameters ::= SEQUENCE { + ue-TxAntennaSelectionSupported BOOLEAN, + ue-SpecificRefSigsSupported BOOLEAN +} + +PhyLayerParameters-v920 ::= SEQUENCE { + enhancedDualLayerFDD-r9 ENUMERATED {supported} OPTIONAL, + enhancedDualLayerTDD-r9 ENUMERATED {supported} OPTIONAL +} + +PhyLayerParameters-v9d0 ::= SEQUENCE { + tm5-FDD-r9 ENUMERATED {supported} OPTIONAL, + tm5-TDD-r9 ENUMERATED {supported} OPTIONAL +} + +PhyLayerParameters-v1020 ::= SEQUENCE { + twoAntennaPortsForPUCCH-r10 ENUMERATED {supported} OPTIONAL, + tm9-With-8Tx-FDD-r10 ENUMERATED {supported} OPTIONAL, + pmi-Disabling-r10 ENUMERATED {supported} OPTIONAL, + crossCarrierScheduling-r10 ENUMERATED {supported} OPTIONAL, + simultaneousPUCCH-PUSCH-r10 ENUMERATED {supported} OPTIONAL, + multiClusterPUSCH-WithinCC-r10 ENUMERATED {supported} OPTIONAL, + nonContiguousUL-RA-WithinCC-List-r10 NonContiguousUL-RA-WithinCC-List-r10 OPTIONAL +} + +PhyLayerParameters-v1130 ::= SEQUENCE { + crs-InterfHandl-r11 ENUMERATED {supported} OPTIONAL, + ePDCCH-r11 ENUMERATED {supported} OPTIONAL, + multiACK-CSI-Reporting-r11 ENUMERATED {supported} OPTIONAL, + ss-CCH-InterfHandl-r11 ENUMERATED {supported} OPTIONAL, + tdd-SpecialSubframe-r11 ENUMERATED {supported} OPTIONAL, + txDiv-PUCCH1b-ChSelect-r11 ENUMERATED {supported} OPTIONAL, + ul-CoMP-r11 ENUMERATED {supported} OPTIONAL +} + +PhyLayerParameters-v1170 ::= SEQUENCE { + interBandTDD-CA-WithDifferentConfig-r11 BIT STRING (SIZE (2)) OPTIONAL +} + +PhyLayerParameters-v1250 ::= SEQUENCE { + e-HARQ-Pattern-FDD-r12 ENUMERATED {supported} OPTIONAL, + enhanced-4TxCodebook-r12 ENUMERATED {supported} OPTIONAL, + tdd-FDD-CA-PCellDuplex-r12 BIT STRING (SIZE (2)) OPTIONAL, + phy-TDD-ReConfig-TDD-PCell-r12 ENUMERATED {supported} OPTIONAL, + phy-TDD-ReConfig-FDD-PCell-r12 ENUMERATED {supported} OPTIONAL, + pusch-FeedbackMode-r12 ENUMERATED {supported} OPTIONAL, + pusch-SRS-PowerControl-SubframeSet-r12 ENUMERATED {supported} OPTIONAL, + csi-SubframeSet-r12 ENUMERATED {supported} OPTIONAL, + noResourceRestrictionForTTIBundling-r12 ENUMERATED {supported} OPTIONAL, + discoverySignalsInDeactSCell-r12 ENUMERATED {supported} OPTIONAL, + naics-Capability-List-r12 NAICS-Capability-List-r12 OPTIONAL +} + +PhyLayerParameters-v1280 ::= SEQUENCE { + alternativeTBS-Indices-r12 ENUMERATED {supported} OPTIONAL +} + +PhyLayerParameters-v1310 ::= SEQUENCE { + aperiodicCSI-Reporting-r13 BIT STRING (SIZE (2)) OPTIONAL, + codebook-HARQ-ACK-r13 BIT STRING (SIZE (2)) OPTIONAL, + crossCarrierScheduling-B5C-r13 ENUMERATED {supported} OPTIONAL, + fdd-HARQ-TimingTDD-r13 ENUMERATED {supported} OPTIONAL, maxNumberUpdatedCSI-Proc-r13 INTEGER(5..32) OPTIONAL, + pucch-Format4-r13 ENUMERATED {supported} OPTIONAL, + pucch-Format5-r13 ENUMERATED {supported} OPTIONAL, + pucch-SCell-r13 ENUMERATED {supported} OPTIONAL, + spatialBundling-HARQ-ACK-r13 ENUMERATED {supported} OPTIONAL, + supportedBlindDecoding-r13 SEQUENCE { + maxNumberDecoding-r13 INTEGER(1..32) OPTIONAL, + pdcch-CandidateReductions-r13 ENUMERATED {supported} OPTIONAL, + skipMonitoringDCI-Format0-1A-r13 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + uci-PUSCH-Ext-r13 ENUMERATED {supported} OPTIONAL, + crs-InterfMitigationTM10-r13 ENUMERATED {supported} OPTIONAL, + pdsch-CollisionHandling-r13 ENUMERATED {supported} OPTIONAL +} + +PhyLayerParameters-v1320 ::= SEQUENCE { + mimo-UE-Parameters-r13 MIMO-UE-Parameters-r13 OPTIONAL +} + +PhyLayerParameters-v1330 ::= SEQUENCE { + cch-InterfMitigation-RefRecTypeA-r13 ENUMERATED {supported} OPTIONAL, + cch-InterfMitigation-RefRecTypeB-r13 ENUMERATED {supported} OPTIONAL, + cch-InterfMitigation-MaxNumCCs-r13 INTEGER (1.. maxServCell-r13) OPTIONAL, + crs-InterfMitigationTM1toTM9-r13 INTEGER (1.. maxServCell-r13) OPTIONAL +} + +MIMO-UE-Parameters-r13 ::= SEQUENCE { + parametersTM9-r13 MIMO-UE-ParametersPerTM-r13 OPTIONAL, + parametersTM10-r13 MIMO-UE-ParametersPerTM-r13 OPTIONAL, + srs-EnhancementsTDD-r13 ENUMERATED {supported} OPTIONAL, + srs-Enhancements-r13 ENUMERATED {supported} OPTIONAL, + interferenceMeasRestriction-r13 ENUMERATED {supported} OPTIONAL +} + +MIMO-UE-ParametersPerTM-r13 ::= SEQUENCE { + nonPrecoded-r13 MIMO-NonPrecodedCapabilities-r13 OPTIONAL, + beamformed-r13 MIMO-UE-BeamformedCapabilities-r13 OPTIONAL, + channelMeasRestriction-r13 ENUMERATED {supported} OPTIONAL, + dmrs-Enhancements-r13 ENUMERATED {supported} OPTIONAL, + csi-RS-EnhancementsTDD-r13 ENUMERATED {supported} OPTIONAL +} + +MIMO-CA-ParametersPerBoBC-r13 ::= SEQUENCE { + parametersTM9-r13 MIMO-CA-ParametersPerBoBCPerTM-r13 OPTIONAL, + parametersTM10-r13 MIMO-CA-ParametersPerBoBCPerTM-r13 OPTIONAL +} + +MIMO-CA-ParametersPerBoBCPerTM-r13 ::= SEQUENCE { + nonPrecoded-r13 MIMO-NonPrecodedCapabilities-r13 OPTIONAL, + beamformed-r13 MIMO-BeamformedCapabilityList-r13 OPTIONAL, + dmrs-Enhancements-r13 ENUMERATED {different} OPTIONAL +} + +MIMO-NonPrecodedCapabilities-r13 ::= SEQUENCE { + config1-r13 ENUMERATED {supported} OPTIONAL, + config2-r13 ENUMERATED {supported} OPTIONAL, + config3-r13 ENUMERATED {supported} OPTIONAL, + config4-r13 ENUMERATED {supported} OPTIONAL +} + +MIMO-UE-BeamformedCapabilities-r13 ::= SEQUENCE { + altCodebook-r13 ENUMERATED {supported} OPTIONAL, + mimo-BeamformedCapabilities-r13 MIMO-BeamformedCapabilityList-r13 +} + +MIMO-BeamformedCapabilityList-r13 ::= SEQUENCE (SIZE (1..maxCSI-Proc-r11)) OF MIMO-BeamformedCapabilities-r13 + +MIMO-BeamformedCapabilities-r13 ::= SEQUENCE { + k-Max-r13 INTEGER (1..8), + n-MaxList-r13 BIT STRING (SIZE (1..7)) OPTIONAL + } + +NonContiguousUL-RA-WithinCC-List-r10 ::= SEQUENCE (SIZE (1..maxBands)) OF NonContiguousUL-RA-WithinCC-r10 + +NonContiguousUL-RA-WithinCC-r10 ::= SEQUENCE { + nonContiguousUL-RA-WithinCC-Info-r10 ENUMERATED {supported} OPTIONAL +} + +RF-Parameters ::= SEQUENCE { + supportedBandListEUTRA SupportedBandListEUTRA +} + +RF-Parameters-v9e0 ::= SEQUENCE { + supportedBandListEUTRA-v9e0 SupportedBandListEUTRA-v9e0 OPTIONAL +} + +RF-Parameters-v1020 ::= SEQUENCE { + supportedBandCombination-r10 SupportedBandCombination-r10 +} + +RF-Parameters-v1060 ::= SEQUENCE { + supportedBandCombinationExt-r10 SupportedBandCombinationExt-r10 +} + +RF-Parameters-v1090 ::= SEQUENCE { + supportedBandCombination-v1090 SupportedBandCombination-v1090 OPTIONAL +} + +RF-Parameters-v10f0 ::= SEQUENCE { + modifiedMPR-Behavior-r10 BIT STRING (SIZE (32)) OPTIONAL +} + +RF-Parameters-v10i0 ::= SEQUENCE { + supportedBandCombination-v10i0 SupportedBandCombination-v10i0 OPTIONAL +} + +RF-Parameters-v10j0 ::= SEQUENCE { + multiNS-Pmax-r10 ENUMERATED {supported} OPTIONAL +} + +RF-Parameters-v1130 ::= SEQUENCE { + supportedBandCombination-v1130 SupportedBandCombination-v1130 OPTIONAL +} + +RF-Parameters-v1180 ::= SEQUENCE { + freqBandRetrieval-r11 ENUMERATED {supported} OPTIONAL, + requestedBands-r11 SEQUENCE (SIZE (1.. maxBands)) OF FreqBandIndicator-r11 OPTIONAL, + supportedBandCombinationAdd-r11 SupportedBandCombinationAdd-r11 OPTIONAL +} + +RF-Parameters-v11d0 ::= SEQUENCE { + supportedBandCombinationAdd-v11d0 SupportedBandCombinationAdd-v11d0 OPTIONAL +} + +RF-Parameters-v1250 ::= SEQUENCE { + supportedBandListEUTRA-v1250 SupportedBandListEUTRA-v1250 OPTIONAL, + supportedBandCombination-v1250 SupportedBandCombination-v1250 OPTIONAL, + supportedBandCombinationAdd-v1250 SupportedBandCombinationAdd-v1250 OPTIONAL, + freqBandPriorityAdjustment-r12 ENUMERATED {supported} OPTIONAL +} + +RF-Parameters-v1270 ::= SEQUENCE { + supportedBandCombination-v1270 SupportedBandCombination-v1270 OPTIONAL, + supportedBandCombinationAdd-v1270 SupportedBandCombinationAdd-v1270 OPTIONAL +} + +RF-Parameters-v1310 ::= SEQUENCE { + eNB-RequestedParameters-r13 SEQUENCE { + reducedIntNonContCombRequested-r13 ENUMERATED {true} OPTIONAL, + requestedCCsDL-r13 INTEGER (2..32) OPTIONAL, + requestedCCsUL-r13 INTEGER (2..32) OPTIONAL, + skipFallbackCombRequested-r13 ENUMERATED {true} OPTIONAL + } OPTIONAL, + maximumCCsRetrieval-r13 ENUMERATED {supported} OPTIONAL, + skipFallbackCombinations-r13 ENUMERATED {supported} OPTIONAL, + reducedIntNonContComb-r13 ENUMERATED {supported} OPTIONAL, + supportedBandListEUTRA-v1310 SupportedBandListEUTRA-v1310 OPTIONAL, + supportedBandCombinationReduced-r13 SupportedBandCombinationReduced-r13 OPTIONAL +} + +RF-Parameters-v1320 ::= SEQUENCE { + supportedBandListEUTRA-v1320 SupportedBandListEUTRA-v1320 OPTIONAL, + supportedBandCombination-v1320 SupportedBandCombination-v1320 OPTIONAL, + supportedBandCombinationAdd-v1320 SupportedBandCombinationAdd-v1320 OPTIONAL, + supportedBandCombinationReduced-v1320 SupportedBandCombinationReduced-v1320 OPTIONAL +} + +RF-Parameters-v12b0 ::= SEQUENCE { + maxLayersMIMO-Indication-r12 ENUMERATED {supported} OPTIONAL +} + +SupportedBandCombination-r10 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParameters-r10 + +SupportedBandCombinationExt-r10 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParametersExt-r10 + +SupportedBandCombination-v1090 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParameters-v1090 + +SupportedBandCombination-v10i0 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParameters-v10i0 + +SupportedBandCombination-v1130 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParameters-v1130 + +SupportedBandCombination-v1250 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParameters-v1250 + +SupportedBandCombination-v1270 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParameters-v1270 + +SupportedBandCombination-v1320 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandCombinationParameters-v1320 + +SupportedBandCombinationAdd-r11 ::= SEQUENCE (SIZE (1..maxBandComb-r11)) OF BandCombinationParameters-r11 + +SupportedBandCombinationAdd-v11d0 ::= SEQUENCE (SIZE (1..maxBandComb-r11)) OF BandCombinationParameters-v10i0 + +SupportedBandCombinationAdd-v1250 ::= SEQUENCE (SIZE (1..maxBandComb-r11)) OF BandCombinationParameters-v1250 + +SupportedBandCombinationAdd-v1270 ::= SEQUENCE (SIZE (1..maxBandComb-r11)) OF BandCombinationParameters-v1270 + +SupportedBandCombinationAdd-v1320 ::= SEQUENCE (SIZE (1..maxBandComb-r11)) OF BandCombinationParameters-v1320 + +SupportedBandCombinationReduced-r13 ::= SEQUENCE (SIZE (1..maxBandComb-r13)) OF BandCombinationParameters-r13 + +SupportedBandCombinationReduced-v1320 ::= SEQUENCE (SIZE (1..maxBandComb-r13)) OF BandCombinationParameters-v1320 + +BandCombinationParameters-r10 ::= SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF BandParameters-r10 + +BandCombinationParametersExt-r10 ::= SEQUENCE { + supportedBandwidthCombinationSet-r10 SupportedBandwidthCombinationSet-r10 OPTIONAL +} + +BandCombinationParameters-v1090 ::= SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF BandParameters-v1090 + +BandCombinationParameters-v10i0::= SEQUENCE { +bandParameterList-v10i0 SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF + BandParameters-v10i0 OPTIONAL +} + +BandCombinationParameters-v1130 ::= SEQUENCE { + multipleTimingAdvance-r11 ENUMERATED {supported} OPTIONAL, + simultaneousRx-Tx-r11 ENUMERATED {supported} OPTIONAL, + bandParameterList-r11 SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF BandParameters-v1130 OPTIONAL, + ... +} + +BandCombinationParameters-r11 ::= SEQUENCE { + bandParameterList-r11 SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF + BandParameters-r11, + supportedBandwidthCombinationSet-r11 SupportedBandwidthCombinationSet-r10 OPTIONAL, + multipleTimingAdvance-r11 ENUMERATED {supported} OPTIONAL, + simultaneousRx-Tx-r11 ENUMERATED {supported} OPTIONAL, + bandInfoEUTRA-r11 BandInfoEUTRA, + ... +} + +BandCombinationParameters-v1250::= SEQUENCE { + dc-Support-r12 SEQUENCE { + asynchronous-r12 ENUMERATED {supported} OPTIONAL, + supportedCellGrouping-r12 CHOICE { + threeEntries-r12 BIT STRING (SIZE(3)), + fourEntries-r12 BIT STRING (SIZE(7)), + fiveEntries-r12 BIT STRING (SIZE(15)) + } OPTIONAL + } OPTIONAL, + supportedNAICS-2CRS-AP-r12 BIT STRING (SIZE (1..maxNAICS-Entries-r12)) OPTIONAL, + commSupportedBandsPerBC-r12 BIT STRING (SIZE (1.. maxBands)) OPTIONAL, + ... +} + +BandCombinationParameters-v1270 ::= SEQUENCE { + bandParameterList-v1270 SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF + BandParameters-v1270 OPTIONAL +} + +BandCombinationParameters-r13 ::= SEQUENCE { + differentFallbackSupported-r13 ENUMERATED {true} OPTIONAL, + bandParameterList-r13 SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF BandParameters-r13, + supportedBandwidthCombinationSet-r13 SupportedBandwidthCombinationSet-r10 OPTIONAL, + multipleTimingAdvance-r13 ENUMERATED {supported} OPTIONAL, + simultaneousRx-Tx-r13 ENUMERATED {supported} OPTIONAL, + bandInfoEUTRA-r13 BandInfoEUTRA, + dc-Support-r13 SEQUENCE { + asynchronous-r13 ENUMERATED {supported} OPTIONAL, + supportedCellGrouping-r13 CHOICE { + threeEntries-r13 BIT STRING (SIZE(3)), + fourEntries-r13 BIT STRING (SIZE(7)), + fiveEntries-r13 BIT STRING (SIZE(15)) + } OPTIONAL + } OPTIONAL, + supportedNAICS-2CRS-AP-r13 BIT STRING (SIZE (1..maxNAICS-Entries-r12)) OPTIONAL, + commSupportedBandsPerBC-r13 BIT STRING (SIZE (1.. maxBands)) OPTIONAL +} + +BandCombinationParameters-v1320 ::= SEQUENCE { + bandParameterList-v1320 SEQUENCE (SIZE (1..maxSimultaneousBands-r10)) OF + BandParameters-v1320 OPTIONAL, + additionalRx-Tx-PerformanceReq-r13 ENUMERATED {supported} OPTIONAL +} + +SupportedBandwidthCombinationSet-r10 ::= BIT STRING (SIZE (1..maxBandwidthCombSet-r10)) + +BandParameters-r10 ::= SEQUENCE { + bandEUTRA-r10 FreqBandIndicator, + bandParametersUL-r10 BandParametersUL-r10 OPTIONAL, + bandParametersDL-r10 BandParametersDL-r10 OPTIONAL +} + +BandParameters-v1090 ::= SEQUENCE { + bandEUTRA-v1090 FreqBandIndicator-v9e0 OPTIONAL, + ... +} + +BandParameters-v10i0::= SEQUENCE { + bandParametersDL-v10i0 SEQUENCE (SIZE (1..maxBandwidthClass-r10)) OF CA-MIMO-ParametersDL-v10i0 +} + +BandParameters-v1130 ::= SEQUENCE { + supportedCSI-Proc-r11 ENUMERATED {n1, n3, n4} +} + +BandParameters-r11 ::= SEQUENCE { + bandEUTRA-r11 FreqBandIndicator-r11, + bandParametersUL-r11 BandParametersUL-r10 OPTIONAL, + bandParametersDL-r11 BandParametersDL-r10 OPTIONAL, + supportedCSI-Proc-r11 ENUMERATED {n1, n3, n4} OPTIONAL +} + +BandParameters-v1270 ::= SEQUENCE { + bandParametersDL-v1270 SEQUENCE (SIZE (1..maxBandwidthClass-r10)) OF CA-MIMO-ParametersDL-v1270 +} + +BandParameters-r13 ::= SEQUENCE { + bandEUTRA-r13 FreqBandIndicator-r11, + bandParametersUL-r13 BandParametersUL-r13 OPTIONAL, + bandParametersDL-r13 BandParametersDL-r13 OPTIONAL, + supportedCSI-Proc-r13 ENUMERATED {n1, n3, n4} OPTIONAL +} + +BandParameters-v1320 ::= SEQUENCE { + bandParametersDL-v1320 MIMO-CA-ParametersPerBoBC-r13 +} + +BandParametersUL-r10 ::= SEQUENCE (SIZE (1..maxBandwidthClass-r10)) OF CA-MIMO-ParametersUL-r10 + +BandParametersUL-r13 ::= CA-MIMO-ParametersUL-r10 + + +CA-MIMO-ParametersUL-r10 ::= SEQUENCE { + ca-BandwidthClassUL-r10 CA-BandwidthClass-r10, + supportedMIMO-CapabilityUL-r10 MIMO-CapabilityUL-r10 OPTIONAL +} + +BandParametersDL-r10 ::= SEQUENCE (SIZE (1..maxBandwidthClass-r10)) OF CA-MIMO-ParametersDL-r10 + +BandParametersDL-r13 ::= CA-MIMO-ParametersDL-r13 + +CA-MIMO-ParametersDL-r10 ::= SEQUENCE { + ca-BandwidthClassDL-r10 CA-BandwidthClass-r10, + supportedMIMO-CapabilityDL-r10 MIMO-CapabilityDL-r10 OPTIONAL +} + +CA-MIMO-ParametersDL-v10i0 ::= SEQUENCE { + fourLayerTM3-TM4-r10 ENUMERATED {supported} OPTIONAL +} + +CA-MIMO-ParametersDL-v1270 ::= SEQUENCE { + intraBandContiguousCC-InfoList-r12 SEQUENCE (SIZE (1..maxServCell-r10)) OF IntraBandContiguousCC-Info-r12 +} + +CA-MIMO-ParametersDL-r13 ::= SEQUENCE { + ca-BandwidthClassDL-r13 CA-BandwidthClass-r10, + supportedMIMO-CapabilityDL-r13 MIMO-CapabilityDL-r10 OPTIONAL, + fourLayerTM3-TM4-r13 ENUMERATED {supported} OPTIONAL, + intraBandContiguousCC-InfoList-r13 SEQUENCE (SIZE (1..maxServCell-r13)) OF IntraBandContiguousCC-Info-r12 +} + +IntraBandContiguousCC-Info-r12 ::= SEQUENCE { + fourLayerTM3-TM4-perCC-r12 ENUMERATED {supported} OPTIONAL, + supportedMIMO-CapabilityDL-r12 MIMO-CapabilityDL-r10 OPTIONAL, + supportedCSI-Proc-r12 ENUMERATED {n1, n3, n4} OPTIONAL +} + +CA-BandwidthClass-r10 ::= ENUMERATED {a, b, c, d, e, f, ...} + +MIMO-CapabilityUL-r10 ::= ENUMERATED {twoLayers, fourLayers} + +MIMO-CapabilityDL-r10 ::= ENUMERATED {twoLayers, fourLayers, eightLayers} + +SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA + +SupportedBandListEUTRA-v9e0::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA-v9e0 + +SupportedBandListEUTRA-v1250 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA-v1250 + +SupportedBandListEUTRA-v1310 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA-v1310 + +SupportedBandListEUTRA-v1320 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA-v1320 + +SupportedBandEUTRA ::= SEQUENCE { + bandEUTRA FreqBandIndicator, + halfDuplex BOOLEAN +} + +SupportedBandEUTRA-v9e0 ::= SEQUENCE { + bandEUTRA-v9e0 FreqBandIndicator-v9e0 OPTIONAL +} + +SupportedBandEUTRA-v1250 ::= SEQUENCE { + dl-256QAM-r12 ENUMERATED {supported} OPTIONAL, + ul-64QAM-r12 ENUMERATED {supported} OPTIONAL +} + +SupportedBandEUTRA-v1310 ::= SEQUENCE { + ue-PowerClass-5-r13 ENUMERATED {supported} OPTIONAL +} +SupportedBandEUTRA-v1320 ::= SEQUENCE { + intraFreq-CE-NeedForGaps-r13 ENUMERATED {supported} OPTIONAL, + ue-PowerClass-N-r13 ENUMERATED {class1, class2, class4} OPTIONAL +} + +MeasParameters ::= SEQUENCE { + bandListEUTRA BandListEUTRA +} + +MeasParameters-v1020 ::= SEQUENCE { + bandCombinationListEUTRA-r10 BandCombinationListEUTRA-r10 +} + +MeasParameters-v1130 ::= SEQUENCE { + rsrqMeasWideband-r11 ENUMERATED {supported} OPTIONAL +} + +MeasParameters-v11a0 ::= SEQUENCE { + benefitsFromInterruption-r11 ENUMERATED {true} OPTIONAL +} + +MeasParameters-v1250 ::= SEQUENCE { + timerT312-r12 ENUMERATED {supported} OPTIONAL, + alternativeTimeToTrigger-r12 ENUMERATED {supported} OPTIONAL, + incMonEUTRA-r12 ENUMERATED {supported} OPTIONAL, + incMonUTRA-r12 ENUMERATED {supported} OPTIONAL, + extendedMaxMeasId-r12 ENUMERATED {supported} OPTIONAL, + extendedRSRQ-LowerRange-r12 ENUMERATED {supported} OPTIONAL, + rsrq-OnAllSymbols-r12 ENUMERATED {supported} OPTIONAL, + crs-DiscoverySignalsMeas-r12 ENUMERATED {supported} OPTIONAL, + csi-RS-DiscoverySignalsMeas-r12 ENUMERATED {supported} OPTIONAL +} + +MeasParameters-v1310 ::= SEQUENCE { + rs-SINR-Meas-r13 ENUMERATED {supported} OPTIONAL, + whiteCellList-r13 ENUMERATED {supported} OPTIONAL, + extendedMaxObjectId-r13 ENUMERATED {supported} OPTIONAL, + ul-PDCP-Delay-r13 ENUMERATED {supported} OPTIONAL, + extendedFreqPriorities-r13 ENUMERATED {supported} OPTIONAL, + multiBandInfoReport-r13 ENUMERATED {supported} OPTIONAL, + rssi-AndChannelOccupancyReporting-r13 ENUMERATED {supported} OPTIONAL +} + +BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA + +BandCombinationListEUTRA-r10 ::= SEQUENCE (SIZE (1..maxBandComb-r10)) OF BandInfoEUTRA + +BandInfoEUTRA ::= SEQUENCE { + interFreqBandList InterFreqBandList, + interRAT-BandList InterRAT-BandList OPTIONAL +} + +InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo + +InterFreqBandInfo ::= SEQUENCE { + interFreqNeedForGaps BOOLEAN +} + +InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo + +InterRAT-BandInfo ::= SEQUENCE { + interRAT-NeedForGaps BOOLEAN +} + +IRAT-ParametersUTRA-FDD ::= SEQUENCE { + supportedBandListUTRA-FDD SupportedBandListUTRA-FDD +} + +IRAT-ParametersUTRA-v920 ::= SEQUENCE { + e-RedirectionUTRA-r9 ENUMERATED {supported} +} + +IRAT-ParametersUTRA-v9c0 ::= SEQUENCE { + voiceOverPS-HS-UTRA-FDD-r9 ENUMERATED {supported} OPTIONAL, + voiceOverPS-HS-UTRA-TDD128-r9 ENUMERATED {supported} OPTIONAL, + srvcc-FromUTRA-FDD-ToUTRA-FDD-r9 ENUMERATED {supported} OPTIONAL, + srvcc-FromUTRA-FDD-ToGERAN-r9 ENUMERATED {supported} OPTIONAL, + srvcc-FromUTRA-TDD128-ToUTRA-TDD128-r9 ENUMERATED {supported} OPTIONAL, + srvcc-FromUTRA-TDD128-ToGERAN-r9 ENUMERATED {supported} OPTIONAL +} + +IRAT-ParametersUTRA-v9h0 ::= SEQUENCE { + mfbi-UTRA-r9 ENUMERATED {supported} +} + +SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD + +SupportedBandUTRA-FDD ::= ENUMERATED { + bandI, bandII, bandIII, bandIV, bandV, bandVI, + bandVII, bandVIII, bandIX, bandX, bandXI, + bandXII, bandXIII, bandXIV, bandXV, bandXVI, ..., + bandXVII-8a0, bandXVIII-8a0, bandXIX-8a0, bandXX-8a0, + bandXXI-8a0, bandXXII-8a0, bandXXIII-8a0, bandXXIV-8a0, + bandXXV-8a0, bandXXVI-8a0, bandXXVII-8a0, bandXXVIII-8a0, + bandXXIX-8a0, bandXXX-8a0, bandXXXI-8a0, bandXXXII-8a0} + +IRAT-ParametersUTRA-TDD128 ::= SEQUENCE { + supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128 +} + +SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128 + +SupportedBandUTRA-TDD128 ::= ENUMERATED { + a, b, c, d, e, f, g, h, i, j, k, l, m, n, + o, p, ...} + +IRAT-ParametersUTRA-TDD384 ::= SEQUENCE { + supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384 +} + +SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384 + +SupportedBandUTRA-TDD384 ::= ENUMERATED { + a, b, c, d, e, f, g, h, i, j, k, l, m, n, + o, p, ...} + +IRAT-ParametersUTRA-TDD768 ::= SEQUENCE { + supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768 +} + +SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768 + +SupportedBandUTRA-TDD768 ::= ENUMERATED { + a, b, c, d, e, f, g, h, i, j, k, l, m, n, + o, p, ...} + +IRAT-ParametersUTRA-TDD-v1020 ::= SEQUENCE { + e-RedirectionUTRA-TDD-r10 ENUMERATED {supported} +} + +IRAT-ParametersGERAN ::= SEQUENCE { + supportedBandListGERAN SupportedBandListGERAN, + interRAT-PS-HO-ToGERAN BOOLEAN +} + +IRAT-ParametersGERAN-v920 ::= SEQUENCE { + dtm-r9 ENUMERATED {supported} OPTIONAL, + e-RedirectionGERAN-r9 ENUMERATED {supported} OPTIONAL +} + +SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN + +SupportedBandGERAN ::= ENUMERATED { + gsm450, gsm480, gsm710, gsm750, gsm810, gsm850, + gsm900P, gsm900E, gsm900R, gsm1800, gsm1900, + spare5, spare4, spare3, spare2, spare1, ...} + +IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE { + supportedBandListHRPD SupportedBandListHRPD, + tx-ConfigHRPD ENUMERATED {single, dual}, + rx-ConfigHRPD ENUMERATED {single, dual} +} + +SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000 + +IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE { + supportedBandList1XRTT SupportedBandList1XRTT, + tx-Config1XRTT ENUMERATED {single, dual}, + rx-Config1XRTT ENUMERATED {single, dual} +} + +IRAT-ParametersCDMA2000-1XRTT-v920 ::= SEQUENCE { + e-CSFB-1XRTT-r9 ENUMERATED {supported}, + e-CSFB-ConcPS-Mob1XRTT-r9 ENUMERATED {supported} OPTIONAL +} + +IRAT-ParametersCDMA2000-1XRTT-v1020 ::= SEQUENCE { + e-CSFB-dual-1XRTT-r10 ENUMERATED {supported} +} + +IRAT-ParametersCDMA2000-v1130 ::= SEQUENCE { + cdma2000-NW-Sharing-r11 ENUMERATED {supported} OPTIONAL +} + +SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000 + +IRAT-ParametersWLAN-r13 ::= SEQUENCE { + supportedBandListWLAN-r13 SEQUENCE (SIZE (1..maxWLAN-Bands-r13)) OF WLAN-BandIndicator-r13 OPTIONAL +} + +CSG-ProximityIndicationParameters-r9 ::= SEQUENCE { + intraFreqProximityIndication-r9 ENUMERATED {supported} OPTIONAL, + interFreqProximityIndication-r9 ENUMERATED {supported} OPTIONAL, + utran-ProximityIndication-r9 ENUMERATED {supported} OPTIONAL +} + +NeighCellSI-AcquisitionParameters-r9 ::= SEQUENCE { + intraFreqSI-AcquisitionForHO-r9 ENUMERATED {supported} OPTIONAL, + interFreqSI-AcquisitionForHO-r9 ENUMERATED {supported} OPTIONAL, + utran-SI-AcquisitionForHO-r9 ENUMERATED {supported} OPTIONAL +} + +SON-Parameters-r9 ::= SEQUENCE { + rach-Report-r9 ENUMERATED {supported} OPTIONAL +} + +UE-BasedNetwPerfMeasParameters-r10 ::= SEQUENCE { + loggedMeasurementsIdle-r10 ENUMERATED {supported} OPTIONAL, + standaloneGNSS-Location-r10 ENUMERATED {supported} OPTIONAL +} + +UE-BasedNetwPerfMeasParameters-v1250 ::= SEQUENCE { + loggedMBSFNMeasurements-r12 ENUMERATED {supported} +} + +OTDOA-PositioningCapabilities-r10 ::= SEQUENCE { + otdoa-UE-Assisted-r10 ENUMERATED {supported}, + interFreqRSTD-Measurement-r10 ENUMERATED {supported} OPTIONAL +} + +Other-Parameters-r11 ::= SEQUENCE { + inDeviceCoexInd-r11 ENUMERATED {supported} OPTIONAL, + powerPrefInd-r11 ENUMERATED {supported} OPTIONAL, + ue-Rx-TxTimeDiffMeasurements-r11 ENUMERATED {supported} OPTIONAL +} + +Other-Parameters-v11d0 ::= SEQUENCE { + inDeviceCoexInd-UL-CA-r11 ENUMERATED {supported} OPTIONAL +} + +MBMS-Parameters-r11 ::= SEQUENCE { + mbms-SCell-r11 ENUMERATED {supported} OPTIONAL, + mbms-NonServingCell-r11 ENUMERATED {supported} OPTIONAL +} + +MBMS-Parameters-v1250 ::= SEQUENCE { + mbms-AsyncDC-r12 ENUMERATED {supported} OPTIONAL +} + +SCPTM-Parameters-r13 ::= SEQUENCE { + scptm-ParallelReception-r13 ENUMERATED {supported} OPTIONAL, + scptm-SCell-r13 ENUMERATED {supported} OPTIONAL, + scptm-NonServingCell-r13 ENUMERATED {supported} OPTIONAL, + scptm-AsyncDC-r13 ENUMERATED {supported} OPTIONAL +} + +CE-Parameters-r13 ::= SEQUENCE { + ce-ModeA-r13 ENUMERATED {supported} OPTIONAL, + ce-ModeB-r13 ENUMERATED {supported} OPTIONAL +} + +CE-Parameters-v1320 ::= SEQUENCE { + intraFreqA3-CE-ModeA-r13 ENUMERATED {supported} OPTIONAL, + intraFreqA3-CE-ModeB-r13 ENUMERATED {supported} OPTIONAL, + intraFreqHO-CE-ModeA-r13 ENUMERATED {supported} OPTIONAL, + intraFreqHO-CE-ModeB-r13 ENUMERATED {supported} OPTIONAL +} + +LAA-Parameters-r13 ::= SEQUENCE { + crossCarrierSchedulingLAA-DL-r13 ENUMERATED {supported} OPTIONAL, + csi-RS-DRS-RRM-MeasurementsLAA-r13 ENUMERATED {supported} OPTIONAL, + downlinkLAA-r13 ENUMERATED {supported} OPTIONAL, + endingDwPTS-r13 ENUMERATED {supported} OPTIONAL, + secondSlotStartingPosition-r13 ENUMERATED {supported} OPTIONAL, + tm9-LAA-r13 ENUMERATED {supported} OPTIONAL, + tm10-LAA-r13 ENUMERATED {supported} OPTIONAL +} + +LAA-Parameters-v14xy ::= SEQUENCE { + crossCarrierSchedulingLAA-UL-r14 ENUMERATED {supported} OPTIONAL, + uplinkLAA-r14 ENUMERATED {supported} OPTIONAL, + twoStepSchedulingTimingInfo-r14 ENUMERATED {nPlus1, nPlus2, nPlus3} OPTIONAL +} + +WLAN-IW-Parameters-r12 ::= SEQUENCE { + wlan-IW-RAN-Rules-r12 ENUMERATED {supported} OPTIONAL, + wlan-IW-ANDSF-Policies-r12 ENUMERATED {supported} OPTIONAL +} + +LWA-Parameters-r13 ::= SEQUENCE { + lwa-r13 ENUMERATED {supported} OPTIONAL, + lwa-SplitBearer-r13 ENUMERATED {supported} OPTIONAL, + wlan-MAC-Address-r13 OCTET STRING (SIZE (6)) OPTIONAL, + lwa-BufferSize-r13 ENUMERATED {supported} OPTIONAL +} + +WLAN-IW-Parameters-v1310 ::= SEQUENCE { + rclwi-r13 ENUMERATED {supported} OPTIONAL +} + +LWIP-Parameters-r13 ::= SEQUENCE { + lwip-r13 ENUMERATED {supported} OPTIONAL +} + +LWIP-Parameters-v14xy ::= SEQUENCE { + lwip-Aggregation-DL-r14 ENUMERATED {supported} OPTIONAL, + lwip-Aggregation-UL-r14 ENUMERATED {supported} OPTIONAL +} + +NAICS-Capability-List-r12 ::= SEQUENCE (SIZE (1..maxNAICS-Entries-r12)) OF NAICS-Capability-Entry-r12 + + +NAICS-Capability-Entry-r12 ::= SEQUENCE { + numberOfNAICS-CapableCC-r12 INTEGER(1..5), + numberOfAggregatedPRB-r12 ENUMERATED { + n50, n75, n100, n125, n150, n175, + n200, n225, n250, n275, n300, n350, + n400, n450, n500, spare}, + ... +} + +SL-Parameters-r12 ::= SEQUENCE { + commSimultaneousTx-r12 ENUMERATED {supported} OPTIONAL, + commSupportedBands-r12 FreqBandIndicatorListEUTRA-r12 OPTIONAL, + discSupportedBands-r12 SupportedBandInfoList-r12 OPTIONAL, + discScheduledResourceAlloc-r12 ENUMERATED {supported} OPTIONAL, + disc-UE-SelectedResourceAlloc-r12 ENUMERATED {supported} OPTIONAL, + disc-SLSS-r12 ENUMERATED {supported} OPTIONAL, + discSupportedProc-r12 ENUMERATED {n50, n400} OPTIONAL +} + +SL-Parameters-v1310 ::= SEQUENCE { + discSysInfoReporting-r13 ENUMERATED {supported} OPTIONAL, + commMultipleTx-r13 ENUMERATED {supported} OPTIONAL, + discInterFreqTx-r13 ENUMERATED {supported} OPTIONAL, + discPeriodicSLSS-r13 ENUMERATED {supported} OPTIONAL +} + + +SupportedBandInfoList-r12 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandInfo-r12 + +SupportedBandInfo-r12 ::= SEQUENCE { + support-r12 ENUMERATED {supported} OPTIONAL +} + +FreqBandIndicatorListEUTRA-r12 ::= SEQUENCE (SIZE (1..maxBands)) OF FreqBandIndicator-r11 + + +UE-RadioPagingInfo-r12 ::= SEQUENCE { + ue-Category-v1250 INTEGER (0) OPTIONAL, + ..., + [[ ue-CategoryDL-v1310 ENUMERATED {m1} OPTIONAL, + ce-ModeA-r13 ENUMERATED {true} OPTIONAL, + ce-ModeB-r13 ENUMERATED {true} OPTIONAL + ]] + +} + + +UE-TimersAndConstants ::= SEQUENCE { + t300 ENUMERATED { + ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, + ms2000}, + t301 ENUMERATED { + ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, + ms2000}, + t310 ENUMERATED { + ms0, ms50, ms100, ms200, ms500, ms1000, ms2000}, + n310 ENUMERATED { + n1, n2, n3, n4, n6, n8, n10, n20}, + t311 ENUMERATED { + ms1000, ms3000, ms5000, ms10000, ms15000, + ms20000, ms30000}, + n311 ENUMERATED { + n1, n2, n3, n4, n5, n6, n8, n10}, + ..., + [[ t300-v1310 ENUMERATED { + ms2500, ms3000, ms3500, ms4000, ms5000, ms6000, ms8000, + ms10000} OPTIONAL, -- Need OR + t301-v1310 ENUMERATED { + ms2500, ms3000, ms3500, ms4000, ms5000, ms6000, ms8000, + ms10000} OPTIONAL -- Need OR + ]], + [[ t310-v1330 ENUMERATED {ms4000, ms6000} + OPTIONAL -- Need OR + ]] +} + + +VisitedCellInfoList-r12 ::= SEQUENCE (SIZE (1..maxCellHistory-r12)) OF VisitedCellInfo-r12 + +VisitedCellInfo-r12 ::= SEQUENCE { + visitedCellId-r12 CHOICE { + cellGlobalId-r12 CellGlobalIdEUTRA, + pci-arfcn-r12 SEQUENCE { + physCellId-r12 PhysCellId, + carrierFreq-r12 ARFCN-ValueEUTRA-r9 + } + } OPTIONAL, + timeSpent-r12 INTEGER (0..4095), + ... +} + + +WLAN-OffloadConfig-r12 ::= SEQUENCE { + thresholdRSRP-r12 SEQUENCE { + thresholdRSRP-Low-r12 RSRP-Range, + thresholdRSRP-High-r12 RSRP-Range + } OPTIONAL, -- Need OR + thresholdRSRQ-r12 SEQUENCE { + thresholdRSRQ-Low-r12 RSRQ-Range, + thresholdRSRQ-High-r12 RSRQ-Range + } OPTIONAL, -- Need OR + thresholdRSRQ-OnAllSymbolsWithWB-r12 SEQUENCE { + thresholdRSRQ-OnAllSymbolsWithWB-Low-r12 RSRQ-Range, + thresholdRSRQ-OnAllSymbolsWithWB-High-r12 RSRQ-Range + } OPTIONAL, -- Need OP + thresholdRSRQ-OnAllSymbols-r12 SEQUENCE { + thresholdRSRQ-OnAllSymbolsLow-r12 RSRQ-Range, + thresholdRSRQ-OnAllSymbolsHigh-r12 RSRQ-Range + } OPTIONAL, -- Need OP + thresholdRSRQ-WB-r12 SEQUENCE { + thresholdRSRQ-WB-Low-r12 RSRQ-Range, + thresholdRSRQ-WB-High-r12 RSRQ-Range + } OPTIONAL, -- Need OP + + thresholdChannelUtilization-r12 SEQUENCE { + thresholdChannelUtilizationLow-r12 INTEGER (0..255), + thresholdChannelUtilizationHigh-r12 INTEGER (0..255) + } OPTIONAL, -- Need OR + thresholdBackhaul-Bandwidth-r12 SEQUENCE { + thresholdBackhaulDL-BandwidthLow-r12 WLAN-backhaulRate-r12, + thresholdBackhaulDL-BandwidthHigh-r12 WLAN-backhaulRate-r12, + thresholdBackhaulUL-BandwidthLow-r12 WLAN-backhaulRate-r12, + thresholdBackhaulUL-BandwidthHigh-r12 WLAN-backhaulRate-r12 + } OPTIONAL, -- Need OR + thresholdWLAN-RSSI-r12 SEQUENCE { + thresholdWLAN-RSSI-Low-r12 INTEGER (0..255), + thresholdWLAN-RSSI-High-r12 INTEGER (0..255) + } OPTIONAL, -- Need OR + offloadPreferenceIndicator-r12 BIT STRING (SIZE (16)) OPTIONAL, -- Need OR + t-SteeringWLAN-r12 T-Reselection OPTIONAL, -- Need OR + ... +} + +WLAN-backhaulRate-r12 ::= ENUMERATED + {r0, r4, r8, r16, r32, r64, r128, r256, r512, + r1024, r2048, r4096, r8192, r16384, r32768, r65536, r131072, + r262144, r524288, r1048576, r2097152, r4194304, r8388608, + r16777216, r33554432, r67108864, r134217728, r268435456, + r536870912, r1073741824, r2147483648, r4294967296} + + +MBMS-NotificationConfig-r9 ::= SEQUENCE { + notificationRepetitionCoeff-r9 ENUMERATED {n2, n4}, + notificationOffset-r9 INTEGER (0..10), + notificationSF-Index-r9 INTEGER (1..6) +} + + +MBMS-ServiceList-r13 ::= SEQUENCE (SIZE (0..maxMBMS-ServiceListPerUE-r13)) OF MBMS-ServiceInfo-r13 + +MBMS-ServiceInfo-r13 ::= SEQUENCE { + tmgi-r13 TMGI-r9 +} + + +MBSFN-AreaId-r12 ::= INTEGER (0..255) + + +MBSFN-AreaInfoList-r9 ::= SEQUENCE (SIZE(1..maxMBSFN-Area)) OF MBSFN-AreaInfo-r9 + +MBSFN-AreaInfo-r9 ::= SEQUENCE { + mbsfn-AreaId-r9 MBSFN-AreaId-r12, + non-MBSFNregionLength ENUMERATED {s1, s2}, + notificationIndicator-r9 INTEGER (0..7), + mcch-Config-r9 SEQUENCE { + mcch-RepetitionPeriod-r9 ENUMERATED {rf32, rf64, rf128, rf256}, + mcch-Offset-r9 INTEGER (0..10), + mcch-ModificationPeriod-r9 ENUMERATED {rf512, rf1024}, + sf-AllocInfo-r9 BIT STRING (SIZE(6)), + signallingMCS-r9 ENUMERATED {n2, n7, n13, n19} + }, + ... +} + + +MBSFN-SubframeConfig ::= SEQUENCE { + radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32}, + radioframeAllocationOffset INTEGER (0..7), + subframeAllocation CHOICE { + oneFrame BIT STRING (SIZE(6)), + fourFrames BIT STRING (SIZE(24)) + } +} + +PMCH-InfoList-r9 ::= SEQUENCE (SIZE (0..maxPMCH-PerMBSFN)) OF PMCH-Info-r9 + +PMCH-InfoListExt-r12 ::= SEQUENCE (SIZE (0..maxPMCH-PerMBSFN)) OF PMCH-InfoExt-r12 + +PMCH-Info-r9 ::= SEQUENCE { + pmch-Config-r9 PMCH-Config-r9, + mbms-SessionInfoList-r9 MBMS-SessionInfoList-r9, + ... +} + +PMCH-InfoExt-r12 ::= SEQUENCE { + pmch-Config-r12 PMCH-Config-r12, + mbms-SessionInfoList-r12 MBMS-SessionInfoList-r9, + ... +} + +MBMS-SessionInfoList-r9 ::= SEQUENCE (SIZE (0..maxSessionPerPMCH)) OF MBMS-SessionInfo-r9 + +MBMS-SessionInfo-r9 ::= SEQUENCE { + tmgi-r9 TMGI-r9, + sessionId-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Need OR + logicalChannelIdentity-r9 INTEGER (0..maxSessionPerPMCH-1), + ... +} + +PMCH-Config-r9 ::= SEQUENCE { + sf-AllocEnd-r9 INTEGER (0..1535), + dataMCS-r9 INTEGER (0..28), + mch-SchedulingPeriod-r9 ENUMERATED { + rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024}, + ... +} + +PMCH-Config-r12 ::= SEQUENCE { + sf-AllocEnd-r12 INTEGER (0..1535), + dataMCS-r12 CHOICE { + normal-r12 INTEGER (0..28), + higerOrder-r12 INTEGER (0..27) + }, + mch-SchedulingPeriod-r12 ENUMERATED { + rf4, rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024}, + ... +} + +TMGI-r9 ::= SEQUENCE { + plmn-Id-r9 CHOICE { + plmn-Index-r9 INTEGER (1..maxPLMN-r11), + explicitValue-r9 PLMN-Identity + }, + serviceId-r9 OCTET STRING (SIZE (3)) +} + + + +SC-MTCH-InfoList-r13 ::= SEQUENCE (SIZE (0..maxSC-MTCH-r13)) OF SC-MTCH-Info-r13 + +SC-MTCH-Info-r13 ::= SEQUENCE { + mbmsSessionInfo-r13 MBMSSessionInfo-r13, + g-RNTI-r13 BIT STRING(SIZE(16)), + sc-mtch-schedulingInfo-r13 SC-MTCH-SchedulingInfo-r13 OPTIONAL, -- Need OP + sc-mtch-neighbourCell-r13 BIT STRING (SIZE(maxNeighCell-SCPTM-r13)) OPTIONAL, -- Need OP + ..., + [[ p-a-r13 ENUMERATED { + dB-6, dB-4dot77, dB-3, dB-1dot77, + dB0, dB1, dB2, dB3} OPTIONAL -- Need ON + ]] +} + +MBMSSessionInfo-r13 ::= SEQUENCE { + tmgi-r13 TMGI-r9, + sessionId-r13 OCTET STRING (SIZE (1)) OPTIONAL -- Need OR +} + +SC-MTCH-SchedulingInfo-r13::= SEQUENCE { + onDurationTimerSCPTM-r13 ENUMERATED { + psf1, psf2, psf3, psf4, psf5, psf6, + psf8, psf10, psf20, psf30, psf40, + psf50, psf60, psf80, psf100, + psf200}, + drx-InactivityTimerSCPTM-r13 ENUMERATED { + psf0, psf1, psf2, psf4, psf8, + psf10, psf20, psf40, + psf80, psf160, ps320, + psf640, psf960, + psf1280, psf1920, psf2560}, + schedulingPeriodStartOffsetSCPTM-r13 CHOICE { + sf10 INTEGER(0..9), + sf20 INTEGER(0..19), + sf32 INTEGER(0..31), + sf40 INTEGER(0..39), + sf64 INTEGER(0..63), + sf80 INTEGER(0..79), + sf128 INTEGER(0..127), + sf160 INTEGER(0..159), + sf256 INTEGER(0..255), + sf320 INTEGER(0..319), + sf512 INTEGER(0..511), + sf640 INTEGER(0..639), + sf1024 INTEGER(0..1023), + sf2048 INTEGER(0..2048), + sf4096 INTEGER(0..4096), + sf8192 INTEGER(0..8192) + }, + ... +} + + +SCPTM-NeighbourCellList-r13 ::= SEQUENCE (SIZE (1..maxNeighCell-SCPTM-r13)) OF PCI-ARFCN-r13 + +PCI-ARFCN-r13 ::= SEQUENCE { + physCellId-r13 PhysCellId, + carrierFreq-r13 ARFCN-ValueEUTRA-r9 OPTIONAL +} + + +SL-CommConfig-r12 ::= SEQUENCE { + commTxResources-r12 CHOICE { + release NULL, + setup CHOICE { + scheduled-r12 SEQUENCE { + sl-RNTI-r12 C-RNTI, + mac-MainConfig-r12 MAC-MainConfigSL-r12, + sc-CommTxConfig-r12 SL-CommResourcePool-r12, + mcs-r12 INTEGER (0..28) OPTIONAL -- Need OP + }, + ue-Selected-r12 SEQUENCE { + -- Pool for normal usage + commTxPoolNormalDedicated-r12 SEQUENCE { + poolToReleaseList-r12 SL-TxPoolToReleaseList-r12 OPTIONAL, -- Need ON + poolToAddModList-r12 SL-CommTxPoolToAddModList-r12 OPTIONAL -- Need ON + } + } + } + } OPTIONAL, -- Need ON + ..., + [[ commTxResources-v1310 CHOICE { + release NULL, + setup CHOICE { + scheduled-v1310 SEQUENCE { + logicalChGroupInfoList-r13 LogicalChGroupInfoList-r13, + multipleTx-r13 BOOLEAN + }, + ue-Selected-v1310 SEQUENCE { + commTxPoolNormalDedicatedExt-r13 SEQUENCE { + poolToReleaseListExt-r13 SL-TxPoolToReleaseListExt-r13 OPTIONAL, -- Need ON + poolToAddModListExt-r13 SL-CommTxPoolToAddModListExt-r13 OPTIONAL -- Need ON + } + } + } + } OPTIONAL, -- Need ON + commTxAllowRelayDedicated-r13 BOOLEAN OPTIONAL -- Need ON + ]] +} + +LogicalChGroupInfoList-r13 ::= SEQUENCE (SIZE (1..maxLCG-r13)) OF SL-PriorityList-r13 + +SL-CommTxPoolToAddModList-r12 ::= SEQUENCE (SIZE (1..maxSL-TxPool-r12)) OF SL-CommTxPoolToAddMod-r12 + +SL-CommTxPoolToAddModListExt-r13 ::= SEQUENCE (SIZE (1..maxSL-TxPool-v1310)) OF SL-CommTxPoolToAddModExt-r13 + +SL-CommTxPoolToAddMod-r12 ::= SEQUENCE { + poolIdentity-r12 SL-TxPoolIdentity-r12, + pool-r12 SL-CommResourcePool-r12 +} + +SL-CommTxPoolToAddModExt-r13 ::= SEQUENCE { + poolIdentity-v1310 SL-TxPoolIdentity-v1310, + pool-r13 SL-CommResourcePool-r12 +} + +MAC-MainConfigSL-r12 ::= SEQUENCE { + periodic-BSR-TimerSL PeriodicBSR-Timer-r12 OPTIONAL, -- Need ON + retx-BSR-TimerSL RetxBSR-Timer-r12 +} + + +SL-CommTxPoolList-r12 ::= SEQUENCE (SIZE (1..maxSL-TxPool-r12)) OF SL-CommResourcePool-r12 + +SL-CommTxPoolListExt-r13 ::= SEQUENCE (SIZE (1..maxSL-TxPool-v1310)) OF SL-CommResourcePool-r12 + +SL-CommTxPoolListV2X-r14 ::= SEQUENCE (SIZE (1..maxSL-V2X-TxPool-r14)) OF SL-CommResourcePoolV2X-r14 + +SL-CommRxPoolList-r12 ::= SEQUENCE (SIZE (1..maxSL-RxPool-r12)) OF SL-CommResourcePool-r12 + +SL-CommRxPoolListV2X-r14 ::= SEQUENCE (SIZE (1..maxSL-V2X-RxPool-r14)) OF SL-CommResourcePoolV2X-r14 + +SL-CommResourcePool-r12 ::= SEQUENCE { + sc-CP-Len-r12 SL-CP-Len-r12, + sc-Period-r12 SL-PeriodComm-r12, + sc-TF-ResourceConfig-r12 SL-TF-ResourceConfig-r12, + data-CP-Len-r12 SL-CP-Len-r12, + dataHoppingConfig-r12 SL-HoppingConfigComm-r12, + ue-SelectedResourceConfig-r12 SEQUENCE { + data-TF-ResourceConfig-r12 SL-TF-ResourceConfig-r12, + trpt-Subset-r12 SL-TRPT-Subset-r12 OPTIONAL -- Need OP + } OPTIONAL, -- Need OR + rxParametersNCell-r12 SEQUENCE { + tdd-Config-r12 TDD-Config OPTIONAL, -- Need OP + syncConfigIndex-r12 INTEGER (0..15) + } OPTIONAL, -- Need OR + txParameters-r12 SEQUENCE { + sc-TxParameters-r12 SL-TxParameters-r12, + dataTxParameters-r12 SL-TxParameters-r12 + } OPTIONAL, -- Cond Tx + ..., + [[ priorityList-r13 SL-PriorityList-r13 OPTIONAL -- Cond Tx + ]] + +} + +SL-CommResourcePoolV2X-r14 ::= SEQUENCE { + sl-OffsetIndicator-r14 SL-OffsetIndicator-r12 OPTIONAL, -- Need OR + sl-Subframe-r14 SubframeBitmapSL-r14, + adjacencyPSCCH-PSSCH-r14 BOOLEAN, + sizeSubchannel-r14 ENUMERATED { + n4, n5, n6, n8, n9, n10, n12, n15, n16, n18, n20, n25, n30, + n48, n50, n72, n75, n96, n100, spare13, spare12, spare11, + spare10, spare9, spare8, spare7, spare6, spare5, spare4, + spare3, spare2, spare1}, + numSubchannel-r14 ENUMERATED {n1, n3, n5, n10, n15, n20, spare2, spare1}, + startRB-Subchannel-r14 INTEGER (0..99), + startRB-PSCCH-Pool-r14 INTEGER (0..99) OPTIONAL, -- Need OR + rxParametersNCell-r14 SEQUENCE { + tdd-Config-r14 TDD-Config OPTIONAL, -- Need OP + syncConfigIndex-r14 INTEGER (0..15) + } OPTIONAL, -- Need OR + dataTxParameters-r14 SL-TxParameters-r12 OPTIONAL, -- Cond Tx + zoneID-r14 INTEGER (0..7) OPTIONAL, -- Need OR, + ... +} + +SL-TRPT-Subset-r12 ::= BIT STRING (SIZE (3..5)) + + +SL-CP-Len-r12 ::= ENUMERATED {normal, extended} + + +SL-DiscConfig-r12 ::= SEQUENCE { + discTxResources-r12 CHOICE { + release NULL, + setup CHOICE { + scheduled-r12 SEQUENCE { + discTxConfig-r12 SL-DiscResourcePool-r12 OPTIONAL, -- Need ON + discTF-IndexList-r12 SL-TF-IndexPairList-r12 OPTIONAL, -- Need ON + discHoppingConfig-r12 SL-HoppingConfigDisc-r12 + OPTIONAL -- Need ON + }, + ue-Selected-r12 SEQUENCE { + discTxPoolDedicated-r12 SEQUENCE { + poolToReleaseList-r12 SL-TxPoolToReleaseList-r12 OPTIONAL, -- Need ON + poolToAddModList-r12 SL-DiscTxPoolToAddModList-r12 OPTIONAL -- Need ON + } OPTIONAL -- Need ON + } + } + } OPTIONAL, -- Need ON + ..., + [[ discTF-IndexList-v1260 CHOICE { + release NULL, + setup SEQUENCE { + discTF-IndexList-r12b SL-TF-IndexPairList-r12b + } + } OPTIONAL -- Need ON + ]], + [[ discTxResourcesPS-r13 CHOICE { + release NULL, + setup CHOICE { + scheduled-r13 SL-DiscTxConfigScheduled-r13, + ue-Selected-r13 SEQUENCE { + discTxPoolPS-Dedicated-r13 SL-DiscTxPoolDedicated-r13 + } + } + } OPTIONAL, -- Need ON + discTxInterFreqInfo-r13 CHOICE { + release NULL, + setup SEQUENCE { + discTxCarrierFreq-r13 ARFCN-ValueEUTRA-r9 OPTIONAL, -- Need OR + discTxRefCarrierDedicated-r13 SL-DiscTxRefCarrierDedicated-r13 OPTIONAL, -- Need OR + discTxInfoInterFreqListAdd-r13 SL-DiscTxInfoInterFreqListAdd-r13 OPTIONAL -- Need ON + } + } OPTIONAL, -- Need ON + gapRequestsAllowedDedicated-r13 BOOLEAN OPTIONAL, -- Need ON + discRxGapConfig-r13 CHOICE { + release NULL, + setup SL-GapConfig-r13 + } OPTIONAL, -- Need ON + discTxGapConfig-r13 CHOICE { + release NULL, + setup SL-GapConfig-r13 + } OPTIONAL, -- Need ON + discSysInfoToReportConfig-r13 CHOICE { + release NULL, + setup SL-DiscSysInfoToReportFreqList-r13 + } OPTIONAL -- Need ON + ]] +} + +SL-DiscSysInfoToReportFreqList-r13 ::= SEQUENCE (SIZE (1..maxFreq)) OF ARFCN-ValueEUTRA-r9 + +SL-DiscTxInfoInterFreqListAdd-r13 ::= SEQUENCE { + discTxFreqToAddModList-r13 SEQUENCE (SIZE (1..maxFreq)) OF SL-DiscTxResourceInfoPerFreq-r13 OPTIONAL, -- Need ON + discTxFreqToReleaseList-r13 SEQUENCE (SIZE (1..maxFreq)) OF ARFCN-ValueEUTRA-r9 OPTIONAL, -- Need ON + ... +} + +SL-DiscTxResourceInfoPerFreq-r13 ::= SEQUENCE { + discTxCarrierFreq-r13 ARFCN-ValueEUTRA-r9, + discTxResources-r13 SL-DiscTxResource-r13 OPTIONAL, -- Need OR + discTxResourcesPS-r13 SL-DiscTxResource-r13 OPTIONAL, -- Need OR + discTxRefCarrierDedicated-r13 SL-DiscTxRefCarrierDedicated-r13 OPTIONAL, -- Need OR + discCellSelectionInfo-r13 CellSelectionInfoNFreq-r13 OPTIONAL, -- Need OR + ... +} + +SL-DiscTxResource-r13 ::= CHOICE { + release NULL, + setup CHOICE { + scheduled-r13 SL-DiscTxConfigScheduled-r13, + ue-Selected-r13 SL-DiscTxPoolDedicated-r13 + } +} + +SL-DiscTxPoolToAddModList-r12 ::= SEQUENCE (SIZE (1..maxSL-TxPool-r12)) OF SL-DiscTxPoolToAddMod-r12 + +SL-DiscTxPoolToAddMod-r12 ::= SEQUENCE { + poolIdentity-r12 SL-TxPoolIdentity-r12, + pool-r12 SL-DiscResourcePool-r12 +} + +SL-DiscTxConfigScheduled-r13 ::= SEQUENCE { + discTxConfig-r13 SL-DiscResourcePool-r12 OPTIONAL, -- Need ON + discTF-IndexList-r13 SL-TF-IndexPairList-r12b OPTIONAL, -- Need ON + discHoppingConfig-r13 SL-HoppingConfigDisc-r12 OPTIONAL,-- Need ON + ... +} + +SL-DiscTxPoolDedicated-r13 ::= SEQUENCE { + poolToReleaseList-r13 SL-TxPoolToReleaseList-r12 OPTIONAL, -- Need ON + poolToAddModList-r13 SL-DiscTxPoolToAddModList-r12 OPTIONAL -- Need ON +} + +SL-TF-IndexPairList-r12 ::= SEQUENCE (SIZE (1..maxSL-TF-IndexPair-r12)) OF SL-TF-IndexPair-r12 + +SL-TF-IndexPair-r12 ::= SEQUENCE { + discSF-Index-r12 INTEGER (1.. 200) OPTIONAL, -- Need ON + discPRB-Index-r12 INTEGER (1.. 50) OPTIONAL -- Need ON +} + +SL-TF-IndexPairList-r12b ::= SEQUENCE (SIZE (1..maxSL-TF-IndexPair-r12)) OF SL-TF-IndexPair-r12b + +SL-TF-IndexPair-r12b ::= SEQUENCE { + discSF-Index-r12b INTEGER (0..209) OPTIONAL, -- Need ON + discPRB-Index-r12b INTEGER (0..49) OPTIONAL -- Need ON +} + +SL-DiscTxRefCarrierDedicated-r13 ::= CHOICE { + pCell NULL, + sCell SCellIndex-r10 +} + + +SL-DiscTxPoolList-r12 ::= SEQUENCE (SIZE (1..maxSL-TxPool-r12)) OF SL-DiscResourcePool-r12 + +SL-DiscRxPoolList-r12 ::= SEQUENCE (SIZE (1..maxSL-RxPool-r12)) OF SL-DiscResourcePool-r12 + +SL-DiscResourcePool-r12 ::= SEQUENCE { + cp-Len-r12 SL-CP-Len-r12, + discPeriod-r12 ENUMERATED {rf32, rf64, rf128, + rf256, rf512, rf1024, rf16-v1310, spare}, + numRetx-r12 INTEGER (0..3), + numRepetition-r12 INTEGER (1..50), + tf-ResourceConfig-r12 SL-TF-ResourceConfig-r12, + txParameters-r12 SEQUENCE { + txParametersGeneral-r12 SL-TxParameters-r12, + ue-SelectedResourceConfig-r12 SEQUENCE { + poolSelection-r12 CHOICE { + rsrpBased-r12 SL-PoolSelectionConfig-r12, + random-r12 NULL + }, + txProbability-r12 ENUMERATED {p25, p50, p75, p100} + } OPTIONAL -- Need OR + } OPTIONAL, -- Cond Tx + rxParameters-r12 SEQUENCE { + tdd-Config-r12 TDD-Config OPTIONAL, -- Need OR + syncConfigIndex-r12 INTEGER (0..15) + } OPTIONAL, -- Need OR + ..., + [[ discPeriod-v1310 CHOICE { + release NULL, + setup ENUMERATED {rf4, rf6, rf7, rf8, + rf12, rf14, rf24, rf28} + } OPTIONAL, -- Need ON + rxParamsAddNeighFreq-r13 CHOICE { + release NULL, + setup SEQUENCE { + physCellId-r13 PhysCellIdList-r13 + } + } OPTIONAL, -- Need ON + txParamsAddNeighFreq-r13 CHOICE { + release NULL, + setup SEQUENCE { + physCellId-r13 PhysCellIdList-r13, + p-Max P-Max OPTIONAL, -- Need OP + tdd-Config-r13 TDD-Config OPTIONAL, -- Cond TDD-OR + tdd-Config-v1130 TDD-Config-v1130 OPTIONAL, -- Cond TDD-OR + freqInfo SEQUENCE { + ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP + ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100} + OPTIONAL, -- Need OP + additionalSpectrumEmission AdditionalSpectrumEmission + }, + referenceSignalPower INTEGER (-60..50), + syncConfigIndex-r13 INTEGER (0..15) OPTIONAL -- Need OR + } + } OPTIONAL -- Need ON + ]] +} + +PhysCellIdList-r13 ::= SEQUENCE (SIZE (1.. maxSL-DiscCells-r13)) OF PhysCellId + +SL-PoolSelectionConfig-r12 ::= SEQUENCE { + threshLow-r12 RSRP-RangeSL2-r12, + threshHigh-r12 RSRP-RangeSL2-r12 +} + + +SL-DiscTxPowerInfoList-r12 ::= SEQUENCE (SIZE (maxSL-DiscPowerClass-r12)) OF SL-DiscTxPowerInfo-r12 + +SL-DiscTxPowerInfo-r12 ::= SEQUENCE { + discMaxTxPower-r12 P-Max, + ... +} + + +SL-GapConfig-r13 ::= SEQUENCE { + gapPatternList-r13 SL-GapPatternList-r13 +} + +SL-GapPatternList-r13 ::= SEQUENCE (SIZE (1..maxSL-GP-r13)) OF SL-GapPattern-r13 + +SL-GapPattern-r13 ::= SEQUENCE { + gapPeriod-r13 ENUMERATED {sf40, sf60, sf70, sf80, sf120, sf140, sf160, + sf240, sf280, sf320, sf640, sf1280, sf2560, sf5120, + sf10240}, + gapOffset-r12 SL-OffsetIndicator-r12, + gapSubframeBitmap-r13 BIT STRING (SIZE (1..10240)), + ... +} + + +SL-GapRequest-r13 ::= SEQUENCE (SIZE (1..maxFreq)) OF SL-GapFreqInfo-r13 + +SL-GapFreqInfo-r13 ::= SEQUENCE { + carrierFreq-r13 ARFCN-ValueEUTRA-r9 OPTIONAL, + gapPatternList-r13 SL-GapPatternList-r13 +} + + +SL-HoppingConfigComm-r12 ::= SEQUENCE { + hoppingParameter-r12 INTEGER (0..504), + numSubbands-r12 ENUMERATED {ns1, ns2, ns4}, + rb-Offset-r12 INTEGER (0..110) +} + +SL-HoppingConfigDisc-r12 ::= SEQUENCE { + a-r12 INTEGER (1..200), + b-r12 INTEGER (1..10), + c-r12 ENUMERATED {n1, n5} +} + + +SL-InterFreqInfoListV2X-r14 ::= SEQUENCE (SIZE (1..maxFreq)) OF SL-InterFreqInfoV2X-r14 + +SL-InterFreqInfoV2X-r14::= SEQUENCE { + v2x-CommCarrierFreq-r14 ARFCN-ValueEUTRA-r9, + typeTxSync-r14 ENUMERATED {gnss, enb} OPTIONAL, -- Need OR + v2x-SchedulingPool-r14 SL-CommResourcePoolV2X-r14 OPTIONAL, -- Need OR + ... +} + + +SL-OffsetIndicator-r12 ::= CHOICE { + small-r12 INTEGER (0..319), + large-r12 INTEGER (0..10239) +} + +SL-OffsetIndicatorSync-r12 ::= INTEGER (0..39) + +SL-OffsetIndicatorSync-v14xy ::= INTEGER (40..159) + + +SL-PeriodComm-r12 ::= ENUMERATED {sf40, sf60, sf70, sf80, sf120, sf140, + sf160, sf240, sf280, sf320, spare6, spare5, + spare4, spare3, spare2, spare} + + +SL-PriorityList-r13 ::= SEQUENCE (SIZE (1..maxSL-Prio-r13)) OF SL-Priority-r13 + +SL-Priority-r13 ::= INTEGER (1..8) + + +SL-PSSCH-TxConfigList-r14 ::= SEQUENCE (SIZE (1..maxPSSCH-TxConfig-r14)) OF SL-PSSCH-TxConfig-r14 + +SL-PSSCH-TxConfig-r14 ::= SEQUENCE { + typeTxSync-r14 ENUMERATED {gnss, enb, ue, spare1} OPTIONAL, -- Need OR + thresUE-Speed-r14 ENUMERATED {kmph60, kmph80, kmph100, kmph120, + kmph140, kmph160, kmph180, kmph200}, + parametersAboveThres-r14 SL-PSSCH-TxParameters-r14, + parametersBelowThres-r14 SL-PSSCH-TxParameters-r14, + ... +} + +SL-PSSCH-TxParameters-r14 ::= SEQUENCE { + minMCS-PSSCH-r14 INTEGER (0..31), + maxMCS-PSSCH-r14 INTEGER (0..31), + minRB-NumberPSSCH-r14 INTEGER (1..100), + maxRB-NumberPSSCH-r14 INTEGER (1..100), + allowedRetxNumberPSSCH-r14 ENUMERATED {n0, n1, both, spare1} +} + + +SL-RestrictResourceReservationPeriodList-r14 ::= SEQUENCE (SIZE (1..maxReservationPeriod-r14)) OF SL-RestrictResourceReservationPeriod-r14 + +SL-RestrictResourceReservationPeriod-r14 ::= ENUMERATED {v0dot2, v0dot5, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, spare4,spare3, spare2, spare1} + + +SLSSID-r12 ::= INTEGER (0..167) + + +SL-SyncConfigList-r12 ::= SEQUENCE (SIZE (1..maxSL-SyncConfig-r12)) OF SL-SyncConfig-r12 + +SL-SyncConfigListV2X-r14 ::= SEQUENCE (SIZE (1.. maxSL-V2X-SyncConfig-r14)) OF SL-SyncConfig-r12 + +SL-SyncConfig-r12 ::= SEQUENCE { + syncCP-Len-r12 SL-CP-Len-r12, + syncOffsetIndicator-r12 SL-OffsetIndicatorSync-r12, + slssid-r12 SLSSID-r12, + txParameters-r12 SEQUENCE { + syncTxParameters-r12 SL-TxParameters-r12, + syncTxThreshIC-r12 RSRP-RangeSL-r12, + syncInfoReserved-r12 BIT STRING (SIZE (19)) OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + rxParamsNCell-r12 SEQUENCE { + physCellId-r12 PhysCellId, + discSyncWindow-r12 ENUMERATED {w1, w2} + } OPTIONAL, -- Need OR + ..., + [[ syncTxPeriodic-r13 ENUMERATED {true} OPTIONAL -- Need OR + ]], + [[ syncOffsetIndicator-v14xy SL-OffsetIndicatorSync-v14xy OPTIONAL -- Need OR + ]] +} + +SL-SyncConfigListNFreq-r13 ::= SEQUENCE (SIZE (1..maxSL-SyncConfig-r12)) OF SL-SyncConfigNFreq-r13 + +SL-SyncConfigNFreq-r13 ::= SEQUENCE { + asyncParameters-r13 SEQUENCE { + syncCP-Len-r13 SL-CP-Len-r12, + syncOffsetIndicator-r13 SL-OffsetIndicatorSync-r12, + slssid-r13 SLSSID-r12 + } OPTIONAL, -- Need OR + txParameters-r13 SEQUENCE { + syncTxParameters-r13 SL-TxParameters-r12, + syncTxThreshIC-r13 RSRP-RangeSL-r12, + syncInfoReserved-r13 BIT STRING (SIZE (19)) OPTIONAL, -- Need OR + syncTxPeriodic-r13 ENUMERATED {true} OPTIONAL -- Need OR + } OPTIONAL, -- Need OR + rxParameters-r13 SEQUENCE { + discSyncWindow-r13 ENUMERATED {w1, w2} + } OPTIONAL, -- Need OR + ... +} + + +SL-DiscSysInfoReport-r13 ::= SEQUENCE { + plmn-IdentityList-r13 PLMN-IdentityList OPTIONAL, + cellIdentity-13 CellIdentity OPTIONAL, + carrierFreqInfo-13 ARFCN-ValueEUTRA-r9 OPTIONAL, + discRxResources-r13 SL-DiscRxPoolList-r12 OPTIONAL, + discTxPoolCommon-r13 SL-DiscTxPoolList-r12 OPTIONAL, + discTxPowerInfo-r13 SL-DiscTxPowerInfoList-r12 OPTIONAL, + discSyncConfig-r13 SL-SyncConfigNFreq-r13 OPTIONAL, + discCellSelectionInfo-r13 SEQUENCE { + q-RxLevMin-r13 Q-RxLevMin, + q-RxLevMinOffset-r13 INTEGER (1..8) OPTIONAL + } OPTIONAL, + cellReselectionInfo-r13 SEQUENCE { + q-Hyst-r13 ENUMERATED { + dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10, + dB12, dB14, dB16, dB18, dB20, dB22, dB24}, + q-RxLevMin-r13 Q-RxLevMin, + t-ReselectionEUTRA-r13 T-Reselection + } OPTIONAL, + tdd-Config-r13 TDD-Config OPTIONAL, + freqInfo-r13 SEQUENCE { + ul-CarrierFreq-r13 ARFCN-ValueEUTRA OPTIONAL, + ul-Bandwidth-r13 ENUMERATED {n6, n15, n25, n50, n75, n100} + OPTIONAL, + additionalSpectrumEmission-r13 AdditionalSpectrumEmission OPTIONAL + } OPTIONAL, + p-Max-r13 P-Max OPTIONAL, + referenceSignalPower-r13 INTEGER (-60..50) OPTIONAL, + ... +} + + +SL-TF-ResourceConfig-r12 ::= SEQUENCE { + prb-Num-r12 INTEGER (1..100), + prb-Start-r12 INTEGER (0..99), + prb-End-r12 INTEGER (0..99), + offsetIndicator-r12 SL-OffsetIndicator-r12, + subframeBitmap-r12 SubframeBitmapSL-r12 +} + +SubframeBitmapSL-r12 ::= CHOICE { + bs4-r12 BIT STRING (SIZE (4)), + bs8-r12 BIT STRING (SIZE (8)), + bs12-r12 BIT STRING (SIZE (12)), + bs16-r12 BIT STRING (SIZE (16)), + bs30-r12 BIT STRING (SIZE (30)), + bs40-r12 BIT STRING (SIZE (40)), + bs42-r12 BIT STRING (SIZE (42)) +} + +SubframeBitmapSL-r14 ::= CHOICE { + bs16-r14 BIT STRING (SIZE (16)), + bs20-r14 BIT STRING (SIZE (20)), + bs100-r14 BIT STRING (SIZE (100)) +} + + +SL-ThresPSSCH-RSRP-List-r14 ::= SEQUENCE (SIZE (1..64)) OF SL-ThresPSSCH-RSRP-r14 + +SL-ThresPSSCH-RSRP-r14 ::= INTEGER (0..66) + + +SL-TxParameters-r12 ::= SEQUENCE { + alpha-r12 Alpha-r12, + p0-r12 P0-SL-r12 +} + +P0-SL-r12 ::= INTEGER (-126..31) + + +SL-TxPoolIdentity-r12 ::= INTEGER (1.. maxSL-TxPool-r12) + +SL-TxPoolIdentity-v1310 ::= INTEGER (maxSL-TxPool-r12Plus1-r13.. maxSL-TxPool-r13) + +SL-V2X-TxPoolIdentity-r14 ::= INTEGER (1.. maxSL-V2X-TxPool-r14) + + +SL-TxPoolToReleaseList-r12 ::= SEQUENCE (SIZE (1..maxSL-TxPool-r12)) OF SL-TxPoolIdentity-r12 + +SL-TxPoolToReleaseListExt-r13 ::= SEQUENCE (SIZE (1..maxSL-TxPool-v1310)) OF SL-TxPoolIdentity-v1310 + + +SL-V2X-ConfigDedicated-r14 ::= SEQUENCE { + commTxResources-r14 CHOICE { + release NULL, + setup CHOICE { + scheduled-r14 SEQUENCE { + sl-D-RNTI-r14 C-RNTI, + mac-MainConfig-r14 MAC-MainConfigSL-r12 OPTIONAL, -- Need OP + v2x-SchedulingPool-r14 SL-CommResourcePoolV2X-r14 OPTIONAL, -- Need OP + mcs-r14 INTEGER (0..31) OPTIONAL, -- Need OP + logicalChGroupInfoList-r14 LogicalChGroupInfoList-r13 + }, + ue-Selected-r14 SEQUENCE { + -- Pool for normal usage + v2x-CommTxPoolNormalDedicated-r14 SEQUENCE { + poolToReleaseList-r14 SL-TxPoolToReleaseListV2X-r14 OPTIONAL, -- Need ON + poolToAddModList-r14 SL-TxPoolToAddModListV2X-r14 OPTIONAL, -- Need ON + v2x-CommTxPoolSensingConfig-r14 SL-CommTxPoolSensingConfig-r14 + OPTIONAL -- Need ON + } + } + } + } OPTIONAL, -- Need ON + v2x-InterFreqInfoList-r14 SL-InterFreqInfoListV2X-r14 OPTIONAL, -- Need ON + ... +} + +SL-TxPoolToAddModListV2X-r14 ::= SEQUENCE { + poolIdentity-r14 SL-V2X-TxPoolIdentity-r14, + pool-r14 SL-CommResourcePoolV2X-r14 +} + +SL-TxPoolToReleaseListV2X-r14 ::= SEQUENCE (SIZE (1.. maxSL-V2X-TxPool-r14)) OF SL-V2X-TxPoolIdentity-r14 + + +SL-ZoneConfig-r14 ::= SEQUENCE { + zoneLength-r14 ENUMERATED { m5, m10, m20, m50, m100, m200, m500, spare1} OPTIONAL, -- Need OR + zoneWidth-r14 ENUMERATED { m5, m10, m20, m50, m100, m200, m500, spare1} OPTIONAL, -- Need OR + zoneIdLongiMod-r14 INTEGER (1..4) OPTIONAL, -- Need OR + zoneIdLatiMod-r14 INTEGER (1..4) OPTIONAL -- Need OR +} + + +maxACDC-Cat-r13 INTEGER ::= 16 -- Maximum number of ACDC categories (per PLMN) +maxAvailNarrowBands-r13 INTEGER ::= 16 -- Maximum number of narrowbands +maxBandComb-r10 INTEGER ::= 128 -- Maximum number of band combinations. +maxBandComb-r11 INTEGER ::= 256 -- Maximum number of additional band combinations. +maxBandComb-r13 INTEGER ::= 384 -- Maximum number of band combinations in Rel-13 +maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps +maxBandwidthClass-r10 INTEGER ::= 16 -- Maximum number of supported CA BW classes per band +maxBandwidthCombSet-r10 INTEGER ::= 32 -- Maximum number of bandwidth combination sets per + -- supported band combination +maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes +maxCE-Level-r13 INTEGER ::= 4 -- Maximum number of CE levels +maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted physical cell identity + -- ranges listed in SIB type 4 and 5 +maxCellHistory-r12 INTEGER ::= 16 -- Maximum number of visited EUTRA cells reported +maxCellInfoGERAN-r9 INTEGER ::= 32 -- Maximum number of GERAN cells for which system in- + -- formation can be provided as redirection assistance +maxCellInfoUTRA-r9 INTEGER ::= 16 -- Maximum number of UTRA cells for which system + -- information can be provided as redirection + -- assistance +maxCombIDC-r11 INTEGER ::= 128 -- Maximum number of reported UL CA combinations +maxCSI-IM-r11 INTEGER ::= 3 -- Maximum number of CSI-IM configurations + -- (per carrier frequency) +maxCSI-IM-r12 INTEGER ::= 4 -- Maximum number of CSI-IM configurations + -- (per carrier frequency) +minCSI-IM-r13 INTEGER ::= 5 -- Minimum number of CSI IM configurations from which + -- REL-13 extension is used +maxCSI-IM-r13 INTEGER ::= 24 -- Maximum number of CSI-IM configurations + -- (per carrier frequency) +maxCSI-IM-v1310 INTEGER ::= 20 -- Maximum number of additional CSI-IM configurations + -- (per carrier frequency) +maxCSI-Proc-r11 INTEGER ::= 4 -- Maximum number of CSI processes (per carrier + -- frequency) +maxCSI-RS-NZP-r11 INTEGER ::= 3 -- Maximum number of CSI RS resource + -- configurations using non-zero Tx power + -- (per carrier frequency) +minCSI-RS-NZP-r13 INTEGER ::= 4 -- Minimum number of CSI RS resource from which + -- REL-13 extension is used +maxCSI-RS-NZP-r13 INTEGER ::= 24 -- Maximum number of CSI RS resource + -- configurations using non-zero Tx power + -- (per carrier frequency) +maxCSI-RS-NZP-v1310 INTEGER ::= 21 -- Maximum number of additional CSI RS resource + -- configurations using non-zero Tx power + -- (per carrier frequency) +maxCSI-RS-ZP-r11 INTEGER ::= 4 -- Maximum number of CSI RS resource + -- configurations using zero Tx power(per carrier + -- frequency) +maxCQI-ProcExt-r11 INTEGER ::= 3 -- Maximum number of additional periodic CQI + -- configurations (per carrier frequency) +maxFreqUTRA-TDD-r10 INTEGER ::= 6 -- Maximum number of UTRA TDD carrier frequencies for + -- which system information can be provided as + -- redirection assistance +maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency + -- cells listed in SIB type 5 +maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency + -- cells listed in SIB type 4 +maxCellListGERAN INTEGER ::= 3 -- Maximum number of lists of GERAN cells +maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the + -- cell lists in a measurement object +maxCellReport INTEGER ::= 8 -- Maximum number of reported cells/CSI-RS resources +maxCSI-RS-Meas-r12 INTEGER ::= 96 -- Maximum number of entries in the CSI-RS list + -- in a measurement object +maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers +maxDS-Duration-r12 INTEGER ::= 5 -- Maximum number of subframes in a discovery signals + -- occasion +maxDS-ZTP-CSI-RS-r12 INTEGER ::= 5 -- Maximum number of zero transmission power CSI-RS for + -- a serving cell concerning discovery signals +maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier frequency +maxEARFCN-Plus1 INTEGER ::= 65536 -- Lowest value extended EARFCN range +maxEARFCN2 INTEGER ::= 262143 -- Highest value extended EARFCN range +maxEPDCCH-Set-r11 INTEGER ::= 2 -- Maximum number of EPDCCH sets +maxFBI INTEGER ::= 64 -- Maximum value of fequency band indicator +maxFBI-Plus1 INTEGER ::= 65 -- Lowest value extended FBI range +maxFBI2 INTEGER ::= 256 -- Highest value extended FBI range +maxFreq INTEGER ::= 8 -- Maximum number of carrier frequencies +maxFreqIDC-r11 INTEGER ::= 32 -- Maximum number of carrier frequencies that are + -- affected by the IDC problems +maxFreqMBMS-r11 INTEGER ::= 5 -- Maximum number of carrier frequencies for which an + -- MBMS capable UE may indicate an interest +maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be + -- provided as part of NACC information +maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups +maxLCG-r13 INTEGER ::= 4 -- Maximum number of logical channel groups +maxLogMeasReport-r10 INTEGER ::= 520 -- Maximum number of logged measurement entries + -- that can be reported by the UE in one message +maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with + -- different offset +maxMBSFN-Area INTEGER ::= 8 +maxMBSFN-Area-1 INTEGER ::= 7 +maxMBMS-ServiceListPerUE-r13 INTEGER ::= 15 -- Maximum number of services which the UE can + -- include in the MBMS interest indication +maxMeasId INTEGER ::= 32 +maxMeasId-Plus1 INTEGER ::= 33 +maxMeasId-r12 INTEGER ::= 64 +maxMultiBands INTEGER ::= 8 -- Maximum number of additional frequency bands + -- that a cell belongs to +maxNS-Pmax-r10 INTEGER ::= 8 -- Maximum number of NS and P-Max values per band +maxNAICS-Entries-r12 INTEGER ::= 8 -- Maximum number of supported NAICS combination(s) +maxNeighCell-r12 INTEGER ::= 8 -- Maximum number of neighbouring cells in NAICS + -- configuration (per carrier frequency) +maxNeighCell-SCPTM-r13 INTEGER ::= 8 -- Maximum number of SCPTM neighbour cells +maxObjectId INTEGER ::= 32 +maxObjectId-Plus1-r13 INTEGER ::= 33 +maxObjectId-r13 INTEGER ::= 64 +maxP-a-PerNeighCell-r12 INTEGER ::= 3 -- Maximum number of power offsets for a neighbour cell + -- in NAICS configuration +maxPageRec INTEGER ::= 16 -- +maxPhysCellIdRange-r9 INTEGER ::= 4 -- Maximum number of physical cell identity ranges +maxPLMN-r11 INTEGER ::= 6 -- Maximum number of PLMNs +maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets +maxPMCH-PerMBSFN INTEGER ::= 15 +maxPSSCH-TxConfig-r14 INTEGER ::= 16 -- Maximum number of PSSCH TX configurations +maxQCI-r13 INTEGER ::= 6 -- Maximum number of QCIs +maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA) +maxRE-MapQCL-r11 INTEGER ::= 4 -- Maximum number of PDSCH RE Mapping configurations + -- (per carrier frequency) +maxReportConfigId INTEGER ::= 32 +maxReservationPeriod-r14 INTEGER ::= 16 -- Maximum number of resource reservation periodicities + -- for sidelink V2X communications +maxRSTD-Freq-r10 INTEGER ::= 3 -- Maximum number of frequency layers for RSTD + -- measurement +maxSAI-MBMS-r11 INTEGER ::= 64 -- Maximum number of MBMS service area identities + -- broadcast per carrier frequency +maxSCell-r10 INTEGER ::= 4 -- Maximum number of SCells +maxSCell-r13 INTEGER ::= 31 -- Highest value of extended number range of SCells +maxSC-MTCH-r13 INTEGER ::= 1023 -- Maximum number of SC-MTCHs in one cell +maxSL-CommRxPoolNFreq-r13 INTEGER ::= 32 -- Maximum number of individual sidelink communication + -- Rx resource pools on neighbouring freq +maxSL-CommRxPoolPreconf-v1310 INTEGER ::= 12 -- Maximum number of additional preconfigured + -- sidelink communication Rx resource pool entries +maxSL-TxPool-r12Plus1-r13 INTEGER ::= 5 -- First additional individual sidelink + -- Tx resource pool +maxSL-TxPool-v1310 INTEGER ::= 4 -- Maximum number of additional sidelink + -- Tx resource pool entries +maxSL-TxPool-r13 INTEGER ::= 8 -- Maximum number of individual sidelink + -- Tx resource pools +maxSL-CommTxPoolPreconf-v1310 INTEGER ::= 7 -- Maximum number of additional preconfigured + -- sidelink Tx resource pool entries +maxSL-Dest-r12 INTEGER ::= 16 -- Maximum number of sidelink destinations +maxSL-DiscCells-r13 INTEGER ::= 16 -- Maximum number of cells with similar sidelink + -- configurations +maxSL-DiscPowerClass-r12 INTEGER ::= 3 -- Maximum number of sidelink power classes +maxSL-DiscRxPoolPreconf-r13 INTEGER ::= 16 -- Maximum number of preconfigured sidelink + -- discovery Rx resource pool entries +maxSL-DiscSysInfoReportFreq-r13 INTEGER ::= 8 -- Maximum number of frequencies to include in a + -- SidelinkUEInformation for SI reporting +maxSL-DiscTxPoolPreconf-r13 INTEGER ::= 4 -- Maximum number of preconfigured sidelink + -- discovery Tx resource pool entries +maxSL-GP-r13 INTEGER ::= 8 -- Maximum number of gap patterns that can be requested + -- for a frequency or assigned +maxSL-Prio-r13 INTEGER ::= 8 -- Maximum number of entries in sidelink priority list +maxSL-RxPool-r12 INTEGER ::= 16 -- Maximum number of individual sidelink Rx resource pools +maxSL-SyncConfig-r12 INTEGER ::= 16 -- Maximum number of sidelink Sync configurations +maxSL-TF-IndexPair-r12 INTEGER ::= 64 -- Maximum number of sidelink Time Freq resource index + -- pairs +maxSL-TxPool-r12 INTEGER ::= 4 -- Maximum number of individual sidelink Tx resource pools +maxSL-V2X-RxPool-r14 INTEGER ::= 16 -- Maximum number of RX resource pools for + -- V2X sidelink communication +maxSL-V2X-RxPoolPreconf-r14 INTEGER ::= 16 -- Maximum number of RX resource pools for + -- V2X sidelink communication +maxSL-V2X-TxPool-r14 INTEGER ::= 8 -- Maximum number of TX resource pools for + -- V2X sidelink communication +maxSL-V2X-TxPoolPreconf-r14 INTEGER ::= 8 -- Maximum number of TX resource pools for + -- V2X sidelink communication +maxSL-V2X-SyncConfig-r14 INTEGER ::= 16 -- Maximum number of sidelink Sync configurations + -- for V2X sidelink communication +maxSTAG-r11 INTEGER ::= 3 -- Maximum number of STAGs +maxServCell-r10 INTEGER ::= 5 -- Maximum number of Serving cells +maxServCell-r13 INTEGER ::= 32 -- Highest value of extended number range of Serving cells +maxServiceCount INTEGER ::= 16 -- Maximum number of MBMS services that can be included + -- in an MBMS counting request and response +maxServiceCount-1 INTEGER ::= 15 +maxSessionPerPMCH INTEGER ::= 29 +maxSessionPerPMCH-1 INTEGER ::= 28 +maxSIB INTEGER ::= 32 -- Maximum number of SIBs +maxSIB-1 INTEGER ::= 31 +maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages +maxSimultaneousBands-r10 INTEGER ::= 64 -- Maximum number of simultaneously aggregated bands +maxSubframePatternIDC-r11 INTEGER ::= 8 -- Maximum number of subframe reservation patterns + -- that the UE can simultaneously recommend to the + -- E-UTRAN for use. +maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies +maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies +maxWLAN-Id-r12 INTEGER ::= 16 -- Maximum number of WLAN identifiers +maxWLAN-Bands-r13 INTEGER ::= 8 -- Maximum number of WLAN bands +maxWLAN-Id-r13 INTEGER ::= 32 -- Maximum number of WLAN identifiers +maxWLAN-Channels-r13 INTEGER ::= 16 -- maximum number of WLAN channels used in + -- WLAN-CarrierInfo +maxWLAN-CarrierInfo-r13 INTEGER ::= 8 -- Maximum number of WLAN Carrier Information + + +END + + +PC5-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + TDD-ConfigSL-r12 +FROM EUTRA-RRC-Definitions; + + +SBCCH-SL-BCH-Message ::= SEQUENCE { + message SBCCH-SL-BCH-MessageType +} + +SBCCH-SL-BCH-MessageType ::= MasterInformationBlock-SL + + +MasterInformationBlock-SL ::= SEQUENCE { + sl-Bandwidth-r12 ENUMERATED { + n6, n15, n25, n50, n75, n100}, + tdd-ConfigSL-r12 TDD-ConfigSL-r12, + directFrameNumber-r12 BIT STRING (SIZE (10)), + directSubframeNumber-r12 INTEGER (0..9), + inCoverage-r12 BOOLEAN, + reserved-r12 BIT STRING (SIZE (19)) +} + + + +END + + +NBIOT-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + RRCConnectionReestablishmentReject, + SecurityModeCommand, + SecurityModeComplete, + SecurityModeFailure, + AdditionalSpectrumEmission, + ARFCN-ValueEUTRA-r9, + CellIdentity, + DedicatedInfoNAS, + DRB-Identity, + InitialUE-Identity, + IntraFreqBlackCellList, + IntraFreqNeighCellList, + maxBands, + maxCellBlack, + maxCellInter, + maxFBI2, + maxFreq, + maxMultiBands, + maxPageRec, + maxPLMN-r11, + maxSIB, + maxSIB-1, + NextHopChainingCount, + PagingUE-Identity, + PLMN-Identity, + P-Max, + PowerRampingParameters, + PreambleTransMax, + PhysCellId, + Q-OffsetRange, + Q-QualMin-r9, + Q-RxLevMin, + ReestabUE-Identity, + RegisteredMME, + ReselectionThreshold, + ResumeIdentity-r13, + RRC-TransactionIdentifier, + RSRP-Range, + ShortMAC-I, + S-TMSI, + SystemInformationBlockType16-r11, + SystemInfoValueTagSI-r13, + TimeAlignmentTimer, + TrackingAreaCode +FROM EUTRA-RRC-Definitions; + + +BCCH-BCH-Message-NB ::= SEQUENCE { + message BCCH-BCH-MessageType-NB +} + + +BCCH-BCH-MessageType-NB::= MasterInformationBlock-NB + + + +BCCH-DL-SCH-Message-NB ::= SEQUENCE { + message BCCH-DL-SCH-MessageType-NB +} + +BCCH-DL-SCH-MessageType-NB ::= CHOICE { + c1 CHOICE { + systemInformation-r13 SystemInformation-NB, + systemInformationBlockType1-r13 SystemInformationBlockType1-NB + }, + messageClassExtension SEQUENCE {} +} + + +PCCH-Message-NB ::= SEQUENCE { + message PCCH-MessageType-NB +} + +PCCH-MessageType-NB ::= CHOICE { + c1 CHOICE { + paging-r13 Paging-NB + }, + messageClassExtension SEQUENCE {} +} + + +DL-CCCH-Message-NB ::= SEQUENCE { + message DL-CCCH-MessageType-NB +} + +DL-CCCH-MessageType-NB ::= CHOICE { + c1 CHOICE { + rrcConnectionReestablishment-r13 RRCConnectionReestablishment-NB, + rrcConnectionReestablishmentReject-r13 RRCConnectionReestablishmentReject, + rrcConnectionReject-r13 RRCConnectionReject-NB, + rrcConnectionSetup-r13 RRCConnectionSetup-NB, + spare4 NULL, spare3 NULL, spare2 NULL, spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + + +DL-DCCH-Message-NB ::= SEQUENCE { + message DL-DCCH-MessageType-NB +} + +DL-DCCH-MessageType-NB ::= CHOICE { + c1 CHOICE { + dlInformationTransfer-r13 DLInformationTransfer-NB, + rrcConnectionReconfiguration-r13 RRCConnectionReconfiguration-NB, + rrcConnectionRelease-r13 RRCConnectionRelease-NB, + securityModeCommand-r13 SecurityModeCommand, + ueCapabilityEnquiry-r13 UECapabilityEnquiry-NB, + rrcConnectionResume-r13 RRCConnectionResume-NB, + spare2 NULL, spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + + + +UL-CCCH-Message-NB ::= SEQUENCE { + message UL-CCCH-MessageType-NB +} + +UL-CCCH-MessageType-NB ::= CHOICE { + c1 CHOICE { + rrcConnectionReestablishmentRequest-r13 RRCConnectionReestablishmentRequest-NB, + rrcConnectionRequest-r13 RRCConnectionRequest-NB, + rrcConnectionResumeRequest-r13 RRCConnectionResumeRequest-NB, + spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + + +UL-DCCH-Message-NB ::= SEQUENCE { + message UL-DCCH-MessageType-NB +} + +UL-DCCH-MessageType-NB ::= CHOICE { + c1 CHOICE { + rrcConnectionReconfigurationComplete-r13 RRCConnectionReconfigurationComplete-NB, + rrcConnectionReestablishmentComplete-r13 RRCConnectionReestablishmentComplete-NB, + rrcConnectionSetupComplete-r13 RRCConnectionSetupComplete-NB, + securityModeComplete-r13 SecurityModeComplete, + securityModeFailure-r13 SecurityModeFailure, + ueCapabilityInformation-r13 UECapabilityInformation-NB, + ulInformationTransfer-r13 ULInformationTransfer-NB, + rrcConnectionResumeComplete-r13 RRCConnectionResumeComplete-NB, + spare8 NULL, spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + + +DLInformationTransfer-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + dlInformationTransfer-r13 DLInformationTransfer-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +DLInformationTransfer-NB-r13-IEs ::= SEQUENCE { + dedicatedInfoNAS-r13 DedicatedInfoNAS, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +MasterInformationBlock-NB ::= SEQUENCE { + systemFrameNumber-MSB-r13 BIT STRING (SIZE (4)), + hyperSFN-LSB-r13 BIT STRING (SIZE (2)), + schedulingInfoSIB1-r13 INTEGER (0..15), + systemInfoValueTag-r13 INTEGER (0..31), + ab-Enabled-r13 BOOLEAN, + operationModeInfo-r13 CHOICE { + inband-SamePCI-r13 Inband-SamePCI-NB-r13, + inband-DifferentPCI-r13 Inband-DifferentPCI-NB-r13, + guardband-r13 Guardband-NB-r13, + standalone-r13 Standalone-NB-r13 + }, + spare BIT STRING (SIZE (11)) +} + +ChannelRasterOffset-NB-r13 ::= ENUMERATED {khz-7dot5, khz-2dot5, khz2dot5, khz7dot5} + +Guardband-NB-r13 ::= SEQUENCE { + rasterOffset-r13 ChannelRasterOffset-NB-r13, + spare BIT STRING (SIZE (3)) +} + +Inband-SamePCI-NB-r13 ::= SEQUENCE { + eutra-CRS-SequenceInfo-r13 INTEGER (0..31) +} + +Inband-DifferentPCI-NB-r13 ::= SEQUENCE { + eutra-NumCRS-Ports-r13 ENUMERATED {same, four}, + rasterOffset-r13 ChannelRasterOffset-NB-r13, + spare BIT STRING (SIZE (2)) +} + +Standalone-NB-r13 ::= SEQUENCE { + spare BIT STRING (SIZE (5)) +} + + +Paging-NB ::= SEQUENCE { + pagingRecordList-r13 PagingRecordList-NB-r13 OPTIONAL, -- Need ON + systemInfoModification-r13 ENUMERATED {true} OPTIONAL, -- Need ON + systemInfoModification-eDRX-r13 ENUMERATED {true} OPTIONAL, -- Need ON + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +PagingRecordList-NB-r13 ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord-NB-r13 + +PagingRecord-NB-r13 ::= SEQUENCE { + ue-Identity-r13 PagingUE-Identity, + ... +} + + +RRCConnectionReconfiguration-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + rrcConnectionReconfiguration-r13 RRCConnectionReconfiguration-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReconfiguration-NB-r13-IEs ::= SEQUENCE { + dedicatedInfoNASList-r13 SEQUENCE (SIZE(1..maxDRB-NB-r13)) OF + DedicatedInfoNAS OPTIONAL, -- Need ON + radioResourceConfigDedicated-r13 RadioResourceConfigDedicated-NB-r13 OPTIONAL, -- Need ON + fullConfig-r13 ENUMERATED {true} OPTIONAL, -- Cond Reestab + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReconfigurationComplete-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcConnectionReconfigurationComplete-r13 RRCConnectionReconfigurationComplete-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReconfigurationComplete-NB-r13-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + + +RRCConnectionReestablishment-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE{ + rrcConnectionReestablishment-r13 RRCConnectionReestablishment-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReestablishment-NB-r13-IEs ::= SEQUENCE { + radioResourceConfigDedicated-r13 RadioResourceConfigDedicated-NB-r13, + nextHopChainingCount-r13 NextHopChainingCount, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReestablishmentComplete-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcConnectionReestablishmentComplete-r13 RRCConnectionReestablishmentComplete-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReestablishmentComplete-NB-r13-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionReestablishmentRequest-NB ::= SEQUENCE { + criticalExtensions CHOICE { + rrcConnectionReestablishmentRequest-r13 + RRCConnectionReestablishmentRequest-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReestablishmentRequest-NB-r13-IEs ::= SEQUENCE { + ue-Identity-r13 ReestabUE-Identity, + reestablishmentCause-r13 ReestablishmentCause-NB-r13, + spare BIT STRING (SIZE (25)) +} + + +ReestablishmentCause-NB-r13 ::= ENUMERATED { + reconfigurationFailure, otherFailure, + spare2, spare1} + + +RRCConnectionReject-NB ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionReject-r13 RRCConnectionReject-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionReject-NB-r13-IEs ::= SEQUENCE { + extendedWaitTime-r13 INTEGER (1..1800), + rrc-SuspendIndication-r13 ENUMERATED {true} OPTIONAL, -- Need ON + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionRelease-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionRelease-r13 RRCConnectionRelease-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionRelease-NB-r13-IEs ::= SEQUENCE { + releaseCause-r13 ReleaseCause-NB-r13, + resumeIdentity-r13 ResumeIdentity-r13 OPTIONAL, -- Need OR + extendedWaitTime-r13 INTEGER (1..1800) OPTIONAL, -- Need ON + redirectedCarrierInfo-r13 RedirectedCarrierInfo-NB-r13 OPTIONAL, -- Need ON + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +ReleaseCause-NB-r13 ::= ENUMERATED {loadBalancingTAUrequired, other, + rrc-Suspend, spare1} + +RedirectedCarrierInfo-NB-r13::= CarrierFreq-NB-r13 + +RRCConnectionRequest-NB ::= SEQUENCE { + criticalExtensions CHOICE { + rrcConnectionRequest-r13 RRCConnectionRequest-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionRequest-NB-r13-IEs ::= SEQUENCE { + ue-Identity-r13 InitialUE-Identity, + establishmentCause-r13 EstablishmentCause-NB-r13, + multiToneSupport-r13 ENUMERATED {true} OPTIONAL, + multiCarrierSupport-r13 ENUMERATED {true} OPTIONAL, + spare BIT STRING (SIZE (22)) +} + + +RRCConnectionResume-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionResume-r13 RRCConnectionResume-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionResume-NB-r13-IEs ::= SEQUENCE { + radioResourceConfigDedicated-r13 RadioResourceConfigDedicated-NB-r13 OPTIONAL, -- Need ON + nextHopChainingCount-r13 NextHopChainingCount, + drb-ContinueROHC-r13 ENUMERATED {true} OPTIONAL, -- Need OP + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionResumeComplete-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcConnectionResumeComplete-r13 RRCConnectionResumeComplete-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionResumeComplete-NB-r13-IEs ::= SEQUENCE { + selectedPLMN-Identity-r13 INTEGER (1..maxPLMN-r11) OPTIONAL, + dedicatedInfoNAS-r13 DedicatedInfoNAS OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionResumeRequest-NB ::= SEQUENCE { + criticalExtensions CHOICE { + rrcConnectionResumeRequest-r13 RRCConnectionResumeRequest-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionResumeRequest-NB-r13-IEs ::= SEQUENCE { + resumeID-r13 ResumeIdentity-r13, + shortResumeMAC-I-r13 ShortMAC-I, + resumeCause-r13 EstablishmentCause-NB-r13, + spare BIT STRING (SIZE (9)) +} + + +RRCConnectionSetup-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + rrcConnectionSetup-r13 RRCConnectionSetup-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionSetup-NB-r13-IEs ::= SEQUENCE { + radioResourceConfigDedicated-r13 RadioResourceConfigDedicated-NB-r13, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +RRCConnectionSetupComplete-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE{ + rrcConnectionSetupComplete-r13 RRCConnectionSetupComplete-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCConnectionSetupComplete-NB-r13-IEs ::= SEQUENCE { + selectedPLMN-Identity-r13 INTEGER (1..maxPLMN-r11), + s-TMSI-r13 S-TMSI OPTIONAL, + registeredMME-r13 RegisteredMME OPTIONAL, + dedicatedInfoNAS-r13 DedicatedInfoNAS, + attachWithoutPDN-Connectivity-r13 ENUMERATED {true} OPTIONAL, + up-CIoT-EPS-Optimisation-r13 ENUMERATED {true} OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SystemInformation-NB ::= SEQUENCE { + criticalExtensions CHOICE { + systemInformation-r13 SystemInformation-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} +SystemInformation-NB-r13-IEs ::= SEQUENCE { + sib-TypeAndInfo-r13 SEQUENCE (SIZE (1..maxSIB)) OF CHOICE { + sib2-r13 SystemInformationBlockType2-NB-r13, + sib3-r13 SystemInformationBlockType3-NB-r13, + sib4-r13 SystemInformationBlockType4-NB-r13, + sib5-r13 SystemInformationBlockType5-NB-r13, + sib14-r13 SystemInformationBlockType14-NB-r13, + sib16-r13 SystemInformationBlockType16-NB-r13, + ... + }, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SystemInformationBlockType1-NB ::= SEQUENCE { + hyperSFN-MSB-r13 BIT STRING (SIZE (8)), + cellAccessRelatedInfo-r13 SEQUENCE { + plmn-IdentityList-r13 PLMN-IdentityList-NB-r13, + trackingAreaCode-r13 TrackingAreaCode, + cellIdentity-r13 CellIdentity, + cellBarred-r13 ENUMERATED {barred, notBarred}, + intraFreqReselection-r13 ENUMERATED {allowed, notAllowed} + }, + cellSelectionInfo-r13 SEQUENCE { + q-RxLevMin-r13 Q-RxLevMin, + q-QualMin-r13 Q-QualMin-r9 + }, + p-Max-r13 P-Max OPTIONAL, -- Need OP + freqBandIndicator-r13 FreqBandIndicator-NB-r13, + freqBandInfo-r13 NS-PmaxList-NB-r13 OPTIONAL, -- Need OR + multiBandInfoList-r13 MultiBandInfoList-NB-r13 OPTIONAL, -- Need OR + downlinkBitmap-r13 DL-Bitmap-NB-r13 OPTIONAL, -- Need OP, + eutraControlRegionSize-r13 ENUMERATED {n1, n2, n3} OPTIONAL, -- Cond inband + nrs-CRS-PowerOffset-r13 ENUMERATED {dB-6, dB-4dot77, dB-3, + dB-1dot77, dB0, dB1, + dB1dot23, dB2, dB3, + dB4, dB4dot23, dB5, + dB6, dB7, dB8, + dB9} OPTIONAL, -- Cond inband-SamePCI + schedulingInfoList-r13 SchedulingInfoList-NB-r13, + si-WindowLength-r13 ENUMERATED {ms160, ms320, ms480, ms640, + ms960, ms1280, ms1600, spare1}, + si-RadioFrameOffset-r13 INTEGER (1..15) OPTIONAL, -- Need OP + systemInfoValueTagList-r13 SystemInfoValueTagList-NB-r13 OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +PLMN-IdentityList-NB-r13 ::= SEQUENCE (SIZE (1..maxPLMN-r11)) OF PLMN-IdentityInfo-NB-r13 + +PLMN-IdentityInfo-NB-r13 ::= SEQUENCE { + plmn-Identity-r13 PLMN-Identity, + cellReservedForOperatorUse-r13 ENUMERATED {reserved, notReserved}, + attachWithoutPDN-Connectivity-r13 ENUMERATED {true} OPTIONAL -- Need OP +} + +SchedulingInfoList-NB-r13 ::= SEQUENCE (SIZE (1..maxSI-Message-NB-r13)) OF SchedulingInfo-NB-r13 + +SchedulingInfo-NB-r13::= SEQUENCE { + si-Periodicity-r13 ENUMERATED {rf64, rf128, rf256, rf512, + rf1024, rf2048, rf4096, spare}, + si-RepetitionPattern-r13 ENUMERATED {every2ndRF, every4thRF, + every8thRF, every16thRF}, + sib-MappingInfo-r13 SIB-MappingInfo-NB-r13, + si-TB-r13 ENUMERATED {b56, b120, b208, b256, b328, b440, b552, b680} +} + +SystemInfoValueTagList-NB-r13 ::= SEQUENCE (SIZE (1.. maxSI-Message-NB-r13)) OF + SystemInfoValueTagSI-r13 + +SIB-MappingInfo-NB-r13 ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type-NB-r13 + +SIB-Type-NB-r13 ::= ENUMERATED { + sibType3-NB-r13, sibType4-NB-r13, sibType5-NB-r13, + sibType14-NB-r13, sibType16-NB-r13, spare3, spare2, spare1} + + + +UECapabilityEnquiry-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + c1 CHOICE { + ueCapabilityEnquiry-r13 UECapabilityEnquiry-NB-r13-IEs, + spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UECapabilityEnquiry-NB-r13-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UECapabilityInformation-NB ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE{ + ueCapabilityInformation-r13 UECapabilityInformation-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +UECapabilityInformation-NB-r13-IEs ::= SEQUENCE { + ue-Capability-Container-r13 UE-Capability-NB-r13, + ue-RadioPagingInfo-r13 UE-RadioPagingInfo-NB-r13, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +ULInformationTransfer-NB ::= SEQUENCE { + criticalExtensions CHOICE { + ulInformationTransfer-r13 ULInformationTransfer-NB-r13-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +ULInformationTransfer-NB-r13-IEs ::= SEQUENCE { + dedicatedInfoNAS-r13 DedicatedInfoNAS, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SystemInformationBlockType2-NB-r13 ::= SEQUENCE { + radioResourceConfigCommon-r13 RadioResourceConfigCommonSIB-NB-r13, + ue-TimersAndConstants-r13 UE-TimersAndConstants-NB-r13, + freqInfo-r13 SEQUENCE { + ul-CarrierFreq-r13 CarrierFreq-NB-r13 OPTIONAL,-- Need OP + additionalSpectrumEmission-r13 AdditionalSpectrumEmission + }, + timeAlignmentTimerCommon-r13 TimeAlignmentTimer, + multiBandInfoList-r13 SEQUENCE (SIZE (1..maxMultiBands)) OF AdditionalSpectrumEmission OPTIONAL,-- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + +SystemInformationBlockType3-NB-r13 ::= SEQUENCE { + cellReselectionInfoCommon-r13 SEQUENCE { + q-Hyst-r13 ENUMERATED { + dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10, + dB12, dB14, dB16, dB18, dB20, dB22, dB24 + } + }, + cellReselectionServingFreqInfo-r13 SEQUENCE { + s-NonIntraSearch-r13 ReselectionThreshold + }, + intraFreqCellReselectionInfo-r13 SEQUENCE { + q-RxLevMin-r13 Q-RxLevMin, + q-QualMin-r13 Q-QualMin-r9 OPTIONAL, -- Need OP + p-Max-r13 P-Max OPTIONAL, -- Need OP + s-IntraSearchP-r13 ReselectionThreshold, + t-Reselection-r13 T-Reselection-NB-r13 + }, + freqBandInfo-r13 NS-PmaxList-NB-r13 OPTIONAL, -- Need OR + multiBandInfoList-r13 SEQUENCE (SIZE (1..maxMultiBands)) OF + NS-PmaxList-NB-r13 OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + +SystemInformationBlockType4-NB-r13 ::= SEQUENCE { + intraFreqNeighCellList-r13 IntraFreqNeighCellList OPTIONAL, -- Need OR + intraFreqBlackCellList-r13 IntraFreqBlackCellList OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + + +SystemInformationBlockType5-NB-r13 ::= SEQUENCE { + interFreqCarrierFreqList-r13 InterFreqCarrierFreqList-NB-r13, + t-Reselection-r13 T-Reselection-NB-r13, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + + +InterFreqCarrierFreqList-NB-r13 ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo-NB-r13 + + +InterFreqCarrierFreqInfo-NB-r13 ::= SEQUENCE { + dl-CarrierFreq-r13 CarrierFreq-NB-r13, + q-RxLevMin-r13 Q-RxLevMin, + q-QualMin-r13 Q-QualMin-r9 OPTIONAL, -- Need OP + p-Max-r13 P-Max OPTIONAL, -- Need OP + q-OffsetFreq-r13 Q-OffsetRange DEFAULT dB0, + interFreqNeighCellList-r13 InterFreqNeighCellList-NB-r13 OPTIONAL, -- Need OR + interFreqBlackCellList-r13 InterFreqBlackCellList-NB-r13 OPTIONAL, -- Need OR + multiBandInfoList-r13 MultiBandInfoList-NB-r13 OPTIONAL, -- Need OR + ... +} + +InterFreqNeighCellList-NB-r13 ::= SEQUENCE (SIZE (1..maxCellInter)) OF PhysCellId + + +InterFreqBlackCellList-NB-r13 ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellId + + + +SystemInformationBlockType14-NB-r13 ::= SEQUENCE { + ab-Param-r13 CHOICE { + ab-Common-r13 AB-Config-NB-r13, + ab-PerPLMN-List-r13 SEQUENCE (SIZE (1..maxPLMN-r11)) OF AB-ConfigPLMN-NB-r13 + } OPTIONAL, -- Need OR + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +AB-ConfigPLMN-NB-r13 ::= SEQUENCE { + ab-Config-r13 AB-Config-NB-r13 OPTIONAL -- Need OR +} + +AB-Config-NB-r13 ::= SEQUENCE { + ab-Category-r13 ENUMERATED {a, b, c}, + ab-BarringBitmap-r13 BIT STRING (SIZE(10)), + ab-BarringExceptionData-r13 ENUMERATED {true} OPTIONAL, -- Need OP + ab-BarringForSpecialAC-r13 BIT STRING (SIZE(5)) +} + + +SystemInformationBlockType16-NB-r13 ::= SystemInformationBlockType16-r11 + + +CarrierConfigDedicated-NB-r13 ::= SEQUENCE { + dl-CarrierConfig-r13 DL-CarrierConfigDedicated-NB-r13, + ul-CarrierConfig-r13 UL-CarrierConfigDedicated-NB-r13 +} + +DL-CarrierConfigDedicated-NB-r13 ::= SEQUENCE { + dl-CarrierFreq-r13 CarrierFreq-NB-r13, + downlinkBitmapNonAnchor-r13 CHOICE { + useNoBitmap-r13 NULL, + useAnchorBitmap-r13 NULL, + explicitBitmapConfiguration-r13 DL-Bitmap-NB-r13, + spare NULL + } OPTIONAL, -- Need ON + dl-GapNonAnchor-r13 CHOICE { + useNoGap-r13 NULL, + useAnchorGapConfig-r13 NULL, + explicitGapConfiguration-r13 DL-GapConfig-NB-r13, + spare NULL + } OPTIONAL, -- Need ON + inbandCarrierInfo-r13 SEQUENCE { + samePCI-Indicator-r13 CHOICE { + samePCI-r13 SEQUENCE { + indexToMidPRB-r13 INTEGER (-55..54) + }, + differentPCI-r13 SEQUENCE { + eutra-NumCRS-Ports-r13 ENUMERATED {same, four} + } + } OPTIONAL, -- Cond anchor-guardband + eutraControlRegionSize-r13 ENUMERATED {n1, n2, n3} + } OPTIONAL, -- Cond non-anchor-inband + ..., + [[ nrs-PowerOffsetNonAnchor-v1330 ENUMERATED {dB-12, dB-10, dB-8, dB-6, + dB-4, dB-2, dB0, dB3} + OPTIONAL -- Need ON + ]] +} + +UL-CarrierConfigDedicated-NB-r13 ::= SEQUENCE { + ul-CarrierFreq-r13 CarrierFreq-NB-r13 OPTIONAL, -- Need OP + ... +} + + +CarrierFreq-NB-r13 ::= SEQUENCE { + carrierFreq-r13 ARFCN-ValueEUTRA-r9, + carrierFreqOffset-r13 ENUMERATED { + v-10, v-9, v-8, v-7, v-6, v-5, v-4, v-3, v-2, v-1, v-0dot5, + v0, v1, v2, v3, v4, v5, v6, v7, v8, v9 + } OPTIONAL -- Need ON +} + + +DL-Bitmap-NB-r13 ::= CHOICE { + subframePattern10-r13 BIT STRING (SIZE (10)), + subframePattern40-r13 BIT STRING (SIZE (40)) +} + + + +DL-GapConfig-NB-r13 ::= SEQUENCE { + dl-GapThreshold-r13 ENUMERATED {n32, n64, n128, n256}, + dl-GapPeriodicity-r13 ENUMERATED {sf64, sf128, sf256, sf512}, + dl-GapDurationCoeff-r13 ENUMERATED {oneEighth, oneFourth, threeEighth, oneHalf} +} + + +LogicalChannelConfig-NB-r13 ::= SEQUENCE { + priority-r13 INTEGER (1..16) OPTIONAL, -- Cond UL + logicalChannelSR-Prohibit-r13 BOOLEAN OPTIONAL, -- Need ON + ... +} + + +MAC-MainConfig-NB-r13 ::= SEQUENCE { + ul-SCH-Config-r13 SEQUENCE { + periodicBSR-Timer-r13 PeriodicBSR-Timer-NB-r13 OPTIONAL, -- Need ON + retxBSR-Timer-r13 RetxBSR-Timer-NB-r13 + } OPTIONAL, -- Need ON + drx-Config-r13 DRX-Config-NB-r13 OPTIONAL, -- Need ON + timeAlignmentTimerDedicated-r13 TimeAlignmentTimer, + logicalChannelSR-Config-r13 CHOICE { + release NULL, + setup SEQUENCE { + logicalChannelSR-ProhibitTimer-r13 ENUMERATED { + pp2, pp8, pp32, pp128, pp512, + pp1024, pp2048, spare} + } + } OPTIONAL, -- Need ON + ... +} + +PeriodicBSR-Timer-NB-r13 ::= ENUMERATED { + pp2, pp4, pp8, pp16, pp64, pp128, infinity, spare} + +RetxBSR-Timer-NB-r13 ::= ENUMERATED { + pp4, pp16, pp64, pp128, pp256, pp512, infinity, spare} + +DRX-Config-NB-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + onDurationTimer-r13 ENUMERATED { + pp1, pp2, pp3, pp4, pp8, pp16, pp32, spare}, + drx-InactivityTimer-r13 ENUMERATED { + pp0, pp1, pp2, pp3, pp4, pp8, pp16, pp32}, + drx-RetransmissionTimer-r13 ENUMERATED { + pp0, pp1, pp2, pp4, pp6, pp8, pp16, pp24, + pp33, spare7, spare6, spare5, + spare4, spare3, spare2, spare1}, + drx-Cycle-r13 ENUMERATED { + sf256, sf512, sf1024, sf1536, sf2048, sf3072, + sf4096, sf4608, sf6144, sf7680, sf8192, sf9216, + spare4, spare3, spare2, spare1}, + drx-StartOffset-r13 INTEGER (0..255), + drx-ULRetransmissionTimer-r13 ENUMERATED { + pp0, pp1, pp2, pp4, pp6, pp8, pp16, pp24, + pp33, pp40, pp64, pp80, pp96, + pp112, pp128, pp160, pp320} + } +} + + + +NPDCCH-ConfigDedicated-NB-r13 ::= SEQUENCE { + npdcch-NumRepetitions-r13 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, r128, + r256, r512, r1024, r2048, + spare4, spare3, spare2, spare1}, + npdcch-StartSF-USS-r13 ENUMERATED {v1dot5, v2, v4, v8, v16, v32, v48, v64}, + npdcch-Offset-USS-r13 ENUMERATED {zero, oneEighth, oneFourth, threeEighth} +} + + + +NPDSCH-ConfigCommon-NB-r13 ::= SEQUENCE { + nrs-Power-r13 INTEGER (-60..50) +} + + +NPRACH-ConfigSIB-NB-r13 ::= SEQUENCE { + nprach-CP-Length-r13 ENUMERATED {us66dot7, us266dot7}, + rsrp-ThresholdsPrachInfoList-r13 RSRP-ThresholdsNPRACH-InfoList-NB-r13 OPTIONAL, -- need OR + nprach-ParametersList-r13 NPRACH-ParametersList-NB-r13 +} + +NPRACH-ConfigSIB-NB-v1330 ::= SEQUENCE { + nprach-ParametersList-v1330 NPRACH-ParametersList-NB-v1330 +} + +NPRACH-ParametersList-NB-r13 ::= SEQUENCE (SIZE (1.. maxNPRACH-Resources-NB-r13)) OF NPRACH-Parameters-NB-r13 + +NPRACH-ParametersList-NB-v1330 ::= SEQUENCE (SIZE (1.. maxNPRACH-Resources-NB-r13)) OF NPRACH-Parameters-NB-v1330 + +NPRACH-Parameters-NB-r13::= SEQUENCE { + nprach-Periodicity-r13 ENUMERATED {ms40, ms80, ms160, ms240, + ms320, ms640, ms1280, ms2560}, + nprach-StartTime-r13 ENUMERATED {ms8, ms16, ms32, ms64, + ms128, ms256, ms512, ms1024}, + nprach-SubcarrierOffset-r13 ENUMERATED {n0, n12, n24, n36, n2, n18, n34, spare1}, + nprach-NumSubcarriers-r13 ENUMERATED {n12, n24, n36, n48}, + nprach-SubcarrierMSG3-RangeStart-r13 ENUMERATED {zero, oneThird, twoThird, one}, + maxNumPreambleAttemptCE-r13 ENUMERATED {n3, n4, n5, n6, n7, n8, n10, spare1}, + numRepetitionsPerPreambleAttempt-r13 ENUMERATED {n1, n2, n4, n8, n16, n32, n64, n128}, + npdcch-NumRepetitions-RA-r13 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, r128, + r256, r512, r1024, r2048, + spare4, spare3, spare2, spare1}, + npdcch-StartSF-CSS-RA-r13 ENUMERATED {v1dot5, v2, v4, v8, v16, v32, v48, v64}, + npdcch-Offset-RA-r13 ENUMERATED {zero, oneEighth, oneFourth, threeEighth} +} + +NPRACH-Parameters-NB-v1330 ::= SEQUENCE { + nprach-NumCBRA-StartSubcarriers-r13 ENUMERATED {n8, n10, n11, n12, n20, n22, n23, n24, + n32, n34, n35, n36, n40, n44, n46, n48} +} + +RSRP-ThresholdsNPRACH-InfoList-NB-r13 ::= SEQUENCE (SIZE(1..2)) OF RSRP-Range + + +NPUSCH-ConfigCommon-NB-r13 ::= SEQUENCE { + ack-NACK-NumRepetitions-Msg4-r13 SEQUENCE (SIZE(1.. maxNPRACH-Resources-NB-r13)) OF + ACK-NACK-NumRepetitions-NB-r13, + srs-SubframeConfig-r13 ENUMERATED { + sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7, + sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15 + } OPTIONAL, -- Need OR + dmrs-Config-r13 SEQUENCE { + threeTone-BaseSequence-r13 INTEGER (0..12) OPTIONAL, -- Need OP + threeTone-CyclicShift-r13 INTEGER (0..2), + sixTone-BaseSequence-r13 INTEGER (0..14) OPTIONAL, -- Need OP + sixTone-CyclicShift-r13 INTEGER (0..3), + twelveTone-BaseSequence-r13 INTEGER (0..30) OPTIONAL -- Need OP + } OPTIONAL, -- Need OR + ul-ReferenceSignalsNPUSCH-r13 UL-ReferenceSignalsNPUSCH-NB-r13 +} + +UL-ReferenceSignalsNPUSCH-NB-r13 ::= SEQUENCE { + groupHoppingEnabled-r13 BOOLEAN, + groupAssignmentNPUSCH-r13 INTEGER (0..29) +} + +NPUSCH-ConfigDedicated-NB-r13 ::= SEQUENCE { + ack-NACK-NumRepetitions-r13 ACK-NACK-NumRepetitions-NB-r13 OPTIONAL, -- Need ON + npusch-AllSymbols-r13 BOOLEAN OPTIONAL, -- Cond SRS + groupHoppingDisabled-r13 ENUMERATED {true} OPTIONAL -- Need OR +} + +ACK-NACK-NumRepetitions-NB-r13 ::= ENUMERATED {r1, r2, r4, r8, r16, r32, r64, r128} + + + +PDCP-Config-NB-r13 ::= SEQUENCE { + discardTimer-r13 ENUMERATED { + ms5120, ms10240, ms20480, ms40960, + ms81920, infinity, spare2, spare1 + } OPTIONAL, -- Cond Setup + headerCompression-r13 CHOICE { + notUsed NULL, + rohc SEQUENCE { + maxCID-r13 INTEGER (1..16383) DEFAULT 15, + profiles-r13 SEQUENCE { + profile0x0002 BOOLEAN, + profile0x0003 BOOLEAN, + profile0x0004 BOOLEAN, + profile0x0006 BOOLEAN, + profile0x0102 BOOLEAN, + profile0x0103 BOOLEAN, + profile0x0104 BOOLEAN + }, + ... + } + }, + ... +} + + +PhysicalConfigDedicated-NB-r13 ::= SEQUENCE { + carrierConfigDedicated-r13 CarrierConfigDedicated-NB-r13 OPTIONAL, -- Need ON + npdcch-ConfigDedicated-r13 NPDCCH-ConfigDedicated-NB-r13 OPTIONAL, -- Need ON + npusch-ConfigDedicated-r13 NPUSCH-ConfigDedicated-NB-r13 OPTIONAL, -- Need ON + uplinkPowerControlDedicated-r13 UplinkPowerControlDedicated-NB-r13 OPTIONAL, -- Need ON + ... +} + + + +RACH-ConfigCommon-NB-r13 ::= SEQUENCE { + preambleTransMax-CE-r13 PreambleTransMax, + powerRampingParameters-r13 PowerRampingParameters, + rach-InfoList-r13 RACH-InfoList-NB-r13, + connEstFailOffset-r13 INTEGER (0..15) OPTIONAL, -- Need OP + ... +} + +RACH-InfoList-NB-r13 ::= SEQUENCE (SIZE (1.. maxNPRACH-Resources-NB-r13)) OF RACH-Info-NB-r13 + +RACH-Info-NB-r13 ::= SEQUENCE { + ra-ResponseWindowSize-r13 ENUMERATED { + pp2, pp3, pp4, pp5, pp6, pp7, pp8, pp10}, + mac-ContentionResolutionTimer-r13 ENUMERATED { + pp1, pp2, pp3, pp4, pp8, pp16, pp32, pp64} +} + + +RadioResourceConfigCommonSIB-NB-r13 ::= SEQUENCE { + rach-ConfigCommon-r13 RACH-ConfigCommon-NB-r13, + bcch-Config-r13 BCCH-Config-NB-r13, + pcch-Config-r13 PCCH-Config-NB-r13, + nprach-Config-r13 NPRACH-ConfigSIB-NB-r13, + npdsch-ConfigCommon-r13 NPDSCH-ConfigCommon-NB-r13, + npusch-ConfigCommon-r13 NPUSCH-ConfigCommon-NB-r13, + dl-Gap-r13 DL-GapConfig-NB-r13 OPTIONAL, -- Need OP + uplinkPowerControlCommon-r13 UplinkPowerControlCommon-NB-r13, + ..., + [[ nprach-Config-v1330 NPRACH-ConfigSIB-NB-v1330 OPTIONAL -- Need OR + ]] +} + +BCCH-Config-NB-r13 ::= SEQUENCE { + modificationPeriodCoeff-r13 ENUMERATED {n16, n32, n64, n128} +} + + +PCCH-Config-NB-r13 ::= SEQUENCE { + defaultPagingCycle-r13 ENUMERATED {rf128, rf256, rf512, rf1024}, + nB-r13 ENUMERATED { + fourT, twoT, oneT, halfT, quarterT, one8thT, + one16thT, one32ndT, one64thT, + one128thT, one256thT, one512thT, one1024thT, + spare3, spare2, spare1}, + npdcch-NumRepetitionPaging-r13 ENUMERATED { + r1, r2, r4, r8, r16, r32, r64, r128, + r256, r512, r1024, r2048, + spare4, spare3, spare2, spare1} +} + + +RadioResourceConfigDedicated-NB-r13 ::= SEQUENCE { + srb-ToAddModList-r13 SRB-ToAddModList-NB-r13 OPTIONAL, -- Need ON + drb-ToAddModList-r13 DRB-ToAddModList-NB-r13 OPTIONAL, -- Need ON + drb-ToReleaseList-r13 DRB-ToReleaseList-NB-r13 OPTIONAL, -- Need ON + mac-MainConfig-r13 CHOICE { + explicitValue-r13 MAC-MainConfig-NB-r13, + defaultValue-r13 NULL + } OPTIONAL, -- Need ON + physicalConfigDedicated-r13 PhysicalConfigDedicated-NB-r13 OPTIONAL, -- Need ON + rlf-TimersAndConstants-r13 RLF-TimersAndConstants-NB-r13 OPTIONAL, -- Need ON + ... +} + +SRB-ToAddModList-NB-r13 ::= SEQUENCE (SIZE (1)) OF SRB-ToAddMod-NB-r13 + +SRB-ToAddMod-NB-r13 ::= SEQUENCE { + rlc-Config-r13 CHOICE { + explicitValue RLC-Config-NB-r13, + defaultValue NULL + } OPTIONAL, -- Cond Setup + logicalChannelConfig-r13 CHOICE { + explicitValue LogicalChannelConfig-NB-r13, + defaultValue NULL + } OPTIONAL, -- Cond Setup + ... +} + +DRB-ToAddModList-NB-r13 ::= SEQUENCE (SIZE (1..maxDRB-NB-r13)) OF DRB-ToAddMod-NB-r13 + +DRB-ToAddMod-NB-r13 ::= SEQUENCE { + eps-BearerIdentity-r13 INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup + drb-Identity-r13 DRB-Identity, + pdcp-Config-r13 PDCP-Config-NB-r13 OPTIONAL, -- Cond Setup + rlc-Config-r13 RLC-Config-NB-r13 OPTIONAL, -- Cond Setup + logicalChannelIdentity-r13 INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup + logicalChannelConfig-r13 LogicalChannelConfig-NB-r13 OPTIONAL, -- Cond Setup + ... +} + +DRB-ToReleaseList-NB-r13 ::= SEQUENCE (SIZE (1..maxDRB-NB-r13)) OF DRB-Identity + + +RLC-Config-NB-r13 ::= CHOICE { + am SEQUENCE { + ul-AM-RLC-r13 UL-AM-RLC-NB-r13, + dl-AM-RLC-r13 DL-AM-RLC-NB-r13 + }, + ... +} + + +UL-AM-RLC-NB-r13 ::= SEQUENCE { + t-PollRetransmit-r13 T-PollRetransmit-NB-r13, + maxRetxThreshold-r13 ENUMERATED {t1, t2, t3, t4, t6, t8, t16, t32} +} + +DL-AM-RLC-NB-r13 ::= SEQUENCE { + enableStatusReportSN-Gap-r13 ENUMERATED {true} OPTIONAL +} + +T-PollRetransmit-NB-r13 ::= ENUMERATED { + ms250, ms500, ms1000, ms2000, ms3000, ms4000, + ms6000, ms10000, ms15000, ms25000, ms40000, ms60000, + ms90000, ms120000, ms180000, spare1} + + + + +RLF-TimersAndConstants-NB-r13 ::= CHOICE { + release NULL, + setup SEQUENCE { + t301-r13 ENUMERATED { + ms2500, ms4000, ms6000, ms10000, + ms15000, ms25000, ms40000, ms60000}, + t310-r13 ENUMERATED { + ms0, ms200, ms500, ms1000, ms2000, ms4000, ms8000}, + n310-r13 ENUMERATED { + n1, n2, n3, n4, n6, n8, n10, n20}, + t311-r13 ENUMERATED { + ms1000, ms3000, ms5000, ms10000, ms15000, + ms20000, ms30000}, + n311-r13 ENUMERATED { + n1, n2, n3, n4, n5, n6, n8, n10}, + ... + } +} + + + +UplinkPowerControlCommon-NB-r13 ::= SEQUENCE { + p0-NominalNPUSCH-r13 INTEGER (-126..24), + alpha-r13 ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1}, + deltaPreambleMsg3-r13 INTEGER (-1..6) +} + +UplinkPowerControlDedicated-NB-r13 ::= SEQUENCE { + p0-UE-NPUSCH-r13 INTEGER (-8..7) +} + + +FreqBandIndicator-NB-r13 ::= INTEGER (1.. maxFBI2) + + +MultiBandInfoList-NB-r13 ::= SEQUENCE (SIZE (1..maxMultiBands)) OF MultiBandInfo-NB-r13 + +MultiBandInfo-NB-r13 ::= SEQUENCE { + freqBandIndicator-r13 FreqBandIndicator-NB-r13 OPTIONAL, -- Need OR + freqBandInfo-r13 NS-PmaxList-NB-r13 OPTIONAL -- Need OR +} + + +NS-PmaxList-NB-r13 ::= SEQUENCE (SIZE (1..maxNS-Pmax-NB-r13)) OF NS-PmaxValue-NB-r13 + +NS-PmaxValue-NB-r13 ::= SEQUENCE { + additionalPmax-r13 P-Max OPTIONAL, -- Need OR + additionalSpectrumEmission-r13 AdditionalSpectrumEmission +} + + +T-Reselection-NB-r13 ::= ENUMERATED {s0, s3, s6, s9, s12, s15, s18, s21} + + +EstablishmentCause-NB-r13 ::= ENUMERATED { + mt-Access, mo-Signalling, mo-Data, mo-ExceptionData, + delayTolerantAccess-v1330, spare3, spare2, spare1} + + +UE-Capability-NB-r13 ::= SEQUENCE { + accessStratumRelease-r13 AccessStratumRelease-NB-r13, + ue-Category-NB-r13 ENUMERATED {nb1} OPTIONAL, + multipleDRB-r13 ENUMERATED {supported} OPTIONAL, + pdcp-Parameters-r13 PDCP-Parameters-NB-r13 OPTIONAL, + phyLayerParameters-r13 PhyLayerParameters-NB-r13, + rf-Parameters-r13 RF-Parameters-NB-r13, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +AccessStratumRelease-NB-r13 ::= ENUMERATED {rel13, spare7, spare6, spare5, spare4, spare3, spare2, spare1, ...} + +PDCP-Parameters-NB-r13 ::= SEQUENCE { + supportedROHC-Profiles-r13 SEQUENCE { + profile0x0002 BOOLEAN, + profile0x0003 BOOLEAN, + profile0x0004 BOOLEAN, + profile0x0006 BOOLEAN, + profile0x0102 BOOLEAN, + profile0x0103 BOOLEAN, + profile0x0104 BOOLEAN + }, + maxNumberROHC-ContextSessions-r13 ENUMERATED {cs2, cs4, cs8, cs12} DEFAULT cs2, + ... +} + +PhyLayerParameters-NB-r13 ::= SEQUENCE { + multiTone-r13 ENUMERATED {supported} OPTIONAL, + multiCarrier-r13 ENUMERATED {supported} OPTIONAL + } + +RF-Parameters-NB-r13 ::= SEQUENCE { + supportedBandList-r13 SupportedBandList-NB-r13, + multiNS-Pmax-r13 ENUMERATED {supported} OPTIONAL +} + +SupportedBandList-NB-r13 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBand-NB-r13 + +SupportedBand-NB-r13 ::= SEQUENCE { + band-r13 FreqBandIndicator-NB-r13, + powerClassNB-20dBm-r13 ENUMERATED {supported} OPTIONAL +} + + + +UE-RadioPagingInfo-NB-r13 ::= SEQUENCE { + ue-Category-NB-r13 ENUMERATED {nb1} OPTIONAL, + ... +} + + +UE-TimersAndConstants-NB-r13 ::= SEQUENCE { + t300-r13 ENUMERATED { + ms2500, ms4000, ms6000, ms10000, + ms15000, ms25000, ms40000, ms60000}, + t301-r13 ENUMERATED { + ms2500, ms4000, ms6000, ms10000, + ms15000, ms25000, ms40000, ms60000}, + t310-r13 ENUMERATED { + ms0, ms200, ms500, ms1000, ms2000, ms4000, ms8000}, + n310-r13 ENUMERATED { + n1, n2, n3, n4, n6, n8, n10, n20}, + t311-r13 ENUMERATED { + ms1000, ms3000, ms5000, ms10000, ms15000, + ms20000, ms30000}, + n311-r13 ENUMERATED { + n1, n2, n3, n4, n5, n6, n8, n10}, + ... +} + + +maxNPRACH-Resources-NB-r13 INTEGER ::= 3 -- Maximum number of NPRACH resources for NB-IoT +maxDRB-NB-r13 INTEGER ::= 2 -- Maximum number of Data Radio Bearers for NB-IoT +maxNS-Pmax-NB-r13 INTEGER ::= 4 -- Maximum number of NS and P-Max values per band +maxSI-Message-NB-r13 INTEGER ::= 8 -- Maximum number of SI messages for NB-IoT + + +END + + +EUTRA-UE-Variables DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + AbsoluteTimeInfo-r10, + AreaConfiguration-r10, + AreaConfiguration-v1130, + CarrierFreqGERAN, + CellIdentity, + ConnEstFailReport-r11, + SpeedStateScaleFactors, + C-RNTI, + LoggingDuration-r10, + LoggingInterval-r10, + LogMeasInfo-r10, + MeasCSI-RS-Id-r12, + MeasId, + MeasId-v1250, + MeasIdToAddModList, + MeasIdToAddModListExt-r12, + MeasIdToAddModList-v1310, + MeasIdToAddModListExt-v1310, + MeasObjectToAddModList, + MeasObjectToAddModList-v9e0, + MeasObjectToAddModListExt-r13, + MeasScaleFactor-r12, + MobilityStateParameters, + NeighCellConfig, + PhysCellId, + PhysCellIdCDMA2000, + PhysCellIdGERAN, + PhysCellIdUTRA-FDD, + PhysCellIdUTRA-TDD, + PLMN-Identity, + PLMN-IdentityList3-r11, + QuantityConfig, + ReportConfigToAddModList, + RLF-Report-r9, + TargetMBSFN-AreaList-r12, + TraceReference-r10, + VisitedCellInfoList-r12, + maxCellMeas, + maxCSI-RS-Meas-r12, + maxMeasId, + maxMeasId-r12, + UL-DelayConfig-r13, + WLAN-CarrierInfo-r13, + WLAN-Identifiers-r12, + WLAN-Id-List-r13, + WLAN-Status-r13 + + +FROM EUTRA-RRC-Definitions; + + +VarConnEstFailReport-r11 ::= SEQUENCE { + connEstFailReport-r11 ConnEstFailReport-r11, + plmn-Identity-r11 PLMN-Identity +} + + +VarLogMeasConfig-r10 ::= SEQUENCE { + areaConfiguration-r10 AreaConfiguration-r10 OPTIONAL, + loggingDuration-r10 LoggingDuration-r10, + loggingInterval-r10 LoggingInterval-r10 +} + +VarLogMeasConfig-r11 ::= SEQUENCE { + areaConfiguration-r10 AreaConfiguration-r10 OPTIONAL, + areaConfiguration-v1130 AreaConfiguration-v1130 OPTIONAL, + loggingDuration-r10 LoggingDuration-r10, + loggingInterval-r10 LoggingInterval-r10 +} + +VarLogMeasConfig-r12 ::= SEQUENCE { + areaConfiguration-r10 AreaConfiguration-r10 OPTIONAL, + areaConfiguration-v1130 AreaConfiguration-v1130 OPTIONAL, + loggingDuration-r10 LoggingDuration-r10, + loggingInterval-r10 LoggingInterval-r10, + targetMBSFN-AreaList-r12 TargetMBSFN-AreaList-r12 OPTIONAL +} + + +VarLogMeasReport-r10 ::= SEQUENCE { + traceReference-r10 TraceReference-r10, + traceRecordingSessionRef-r10 OCTET STRING (SIZE (2)), + tce-Id-r10 OCTET STRING (SIZE (1)), + plmn-Identity-r10 PLMN-Identity, + absoluteTimeInfo-r10 AbsoluteTimeInfo-r10, + logMeasInfoList-r10 LogMeasInfoList2-r10 +} + +VarLogMeasReport-r11 ::= SEQUENCE { + traceReference-r10 TraceReference-r10, + traceRecordingSessionRef-r10 OCTET STRING (SIZE (2)), + tce-Id-r10 OCTET STRING (SIZE (1)), + plmn-IdentityList-r11 PLMN-IdentityList3-r11, + absoluteTimeInfo-r10 AbsoluteTimeInfo-r10, + logMeasInfoList-r10 LogMeasInfoList2-r10 +} + +LogMeasInfoList2-r10 ::= SEQUENCE (SIZE (1..maxLogMeas-r10)) OF LogMeasInfo-r10 + + +VarMeasConfig ::= SEQUENCE { + -- Measurement identities + measIdList MeasIdToAddModList OPTIONAL, + measIdListExt-r12 MeasIdToAddModListExt-r12 OPTIONAL, + measIdList-v1310 MeasIdToAddModList-v1310 OPTIONAL, + measIdListExt-v1310 MeasIdToAddModListExt-v1310 OPTIONAL, + -- Measurement objects + measObjectList MeasObjectToAddModList OPTIONAL, + measObjectListExt-r13 MeasObjectToAddModListExt-r13 OPTIONAL, + measObjectList-v9i0 MeasObjectToAddModList-v9e0 OPTIONAL, + -- Reporting configurations + reportConfigList ReportConfigToAddModList OPTIONAL, + -- Other parameters + quantityConfig QuantityConfig OPTIONAL, + measScaleFactor-r12 MeasScaleFactor-r12 OPTIONAL, + s-Measure INTEGER (-140..-44) OPTIONAL, + speedStatePars CHOICE { + release NULL, + setup SEQUENCE { + mobilityStateParameters MobilityStateParameters, + timeToTrigger-SF SpeedStateScaleFactors + } + } OPTIONAL, + allowInterruptions-r11 BOOLEAN OPTIONAL +} + + +VarMeasReportList ::= SEQUENCE (SIZE (1..maxMeasId)) OF VarMeasReport +VarMeasReportList-r12 ::= SEQUENCE (SIZE (1..maxMeasId-r12)) OF VarMeasReport + +VarMeasReport ::= SEQUENCE { + -- List of measurement that have been triggered + measId MeasId, + measId-v1250 MeasId-v1250 OPTIONAL, + cellsTriggeredList CellsTriggeredList OPTIONAL, + csi-RS-TriggeredList-r12 CSI-RS-TriggeredList-r12 OPTIONAL, + numberOfReportsSent INTEGER +} + +CellsTriggeredList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CHOICE { + physCellIdEUTRA PhysCellId, + physCellIdUTRA CHOICE { + fdd PhysCellIdUTRA-FDD, + tdd PhysCellIdUTRA-TDD + }, + physCellIdGERAN SEQUENCE { + carrierFreq CarrierFreqGERAN, + physCellId PhysCellIdGERAN + }, + physCellIdCDMA2000 PhysCellIdCDMA2000, + wlan-Identifiers-r13 WLAN-Identifiers-r12 +} + +CSI-RS-TriggeredList-r12 ::= SEQUENCE (SIZE (1..maxCSI-RS-Meas-r12)) OF MeasCSI-RS-Id-r12 + +VarMobilityHistoryReport-r12 ::= VisitedCellInfoList-r12 + + +VarRLF-Report-r10 ::= SEQUENCE { + rlf-Report-r10 RLF-Report-r9, + plmn-Identity-r10 PLMN-Identity +} + +VarRLF-Report-r11 ::= SEQUENCE { + rlf-Report-r10 RLF-Report-r9, + plmn-IdentityList-r11 PLMN-IdentityList3-r11 +} + + +VarShortMAC-Input ::= SEQUENCE { + cellIdentity CellIdentity, + physCellId PhysCellId, + c-RNTI C-RNTI +} + +VarShortResumeMAC-Input-r13 ::= SEQUENCE { + cellIdentity-r13 CellIdentity, + physCellId-r13 PhysCellId, + c-RNTI-r13 C-RNTI, + resumeDiscriminator-r13 BIT STRING(SIZE(1)) +} + + +VarWLAN-MobilityConfig ::= SEQUENCE { + wlan-MobilitySet-r13 WLAN-Id-List-r13 OPTIONAL, + successReportRequested ENUMERATED {true} OPTIONAL +} + + +VarWLAN-Status-r13 ::= SEQUENCE { + status-r13 WLAN-Status-r13 +} + + +maxLogMeas-r10 INTEGER ::= 4060-- Maximum number of logged measurement entries + -- that can be stored by the UE + + +END + + +NBIOT-UE-Variables DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + VarShortMAC-Input, + VarShortResumeMAC-Input-r13 + +FROM EUTRA-UE-Variables; + +VarShortMAC-Input-NB-r13 ::= VarShortMAC-Input + +VarShortResumeMAC-Input-NB-r13 ::= VarShortResumeMAC-Input-r13 + + + +END + + +EUTRA-Sidelink-Preconf DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + AdditionalSpectrumEmission, + ARFCN-ValueEUTRA-r9, + FilterCoefficient, + maxFreq, + maxSL-TxPool-r12, + maxSL-CommRxPoolPreconf-v1310, + maxSL-CommTxPoolPreconf-v1310, + maxSL-DiscRxPoolPreconf-r13, + maxSL-DiscTxPoolPreconf-r13, + maxSL-V2X-RxPoolPreconf-r14, + maxSL-V2X-TxPoolPreconf-r14, + P-Max, + ReselectionInfoRelay-r13, + SL-CommTxPoolSensingConfig-r14, + SL-CP-Len-r12, + SL-HoppingConfigComm-r12, + SL-OffsetIndicator-r12, + SL-OffsetIndicatorSync-r12, + SL-OffsetIndicatorSync-v14xy, + SL-PeriodComm-r12, + RSRP-RangeSL3-r12, + SL-PriorityList-r13, + SL-TF-ResourceConfig-r12, + SL-TRPT-Subset-r12, + SL-TxParameters-r12, + SL-ZoneConfig-r14, + P0-SL-r12, + TDD-ConfigSL-r12, + SubframeBitmapSL-r14 +FROM EUTRA-RRC-Definitions; + + +SL-Preconfiguration-r12 ::= SEQUENCE { + preconfigGeneral-r12 SL-PreconfigGeneral-r12, + preconfigSync-r12 SL-PreconfigSync-r12, + preconfigComm-r12 SL-PreconfigCommPoolList4-r12, + ..., + [[ preconfigComm-v1310 SEQUENCE { + commRxPoolList-r13 SL-PreconfigCommRxPoolList-r13, + commTxPoolList-r13 SL-PreconfigCommTxPoolList-r13 OPTIONAL + } OPTIONAL, + preconfigDisc-r13 SEQUENCE { + discRxPoolList-r13 SL-PreconfigDiscRxPoolList-r13, + discTxPoolList-r13 SL-PreconfigDiscTxPoolList-r13 OPTIONAL + } OPTIONAL, + preconfigRelay-r13 SL-PreconfigRelay-r13 OPTIONAL + ]] + +} + +SL-PreconfigGeneral-r12 ::= SEQUENCE { + -- PDCP configuration + rohc-Profiles-r12 SEQUENCE { + profile0x0001-r12 BOOLEAN, + profile0x0002-r12 BOOLEAN, + profile0x0004-r12 BOOLEAN, + profile0x0006-r12 BOOLEAN, + profile0x0101-r12 BOOLEAN, + profile0x0102-r12 BOOLEAN, + profile0x0104-r12 BOOLEAN + }, + -- Physical configuration + carrierFreq-r12 ARFCN-ValueEUTRA-r9, + maxTxPower-r12 P-Max, + additionalSpectrumEmission-r12 AdditionalSpectrumEmission, + sl-bandwidth-r12 ENUMERATED {n6, n15, n25, n50, n75, n100}, + tdd-ConfigSL-r12 TDD-ConfigSL-r12, + reserved-r12 BIT STRING (SIZE (19)), + ... +} + +SL-PreconfigSync-r12 ::= SEQUENCE { + syncCP-Len-r12 SL-CP-Len-r12, + syncOffsetIndicator1-r12 SL-OffsetIndicatorSync-r12, + syncOffsetIndicator2-r12 SL-OffsetIndicatorSync-r12, + syncTxParameters-r12 P0-SL-r12, + syncTxThreshOoC-r12 RSRP-RangeSL3-r12, + filterCoefficient-r12 FilterCoefficient, + syncRefMinHyst-r12 ENUMERATED {dB0, dB3, dB6, dB9, dB12}, + syncRefDiffHyst-r12 ENUMERATED {dB0, dB3, dB6, dB9, dB12, dBinf}, + ..., + [[ syncTxPeriodic-r13 ENUMERATED {true} OPTIONAL + ]], + [[ syncOffsetIndicator1-v14xy SL-OffsetIndicatorSync-v14xy OPTIONAL, + syncOffsetIndicator2-v14xy SL-OffsetIndicatorSync-v14xy OPTIONAL + ]] +} + +SL-PreconfigCommPoolList4-r12 ::= SEQUENCE (SIZE (1..maxSL-TxPool-r12)) OF SL-PreconfigCommPool-r12 + +SL-PreconfigCommRxPoolList-r13 ::= SEQUENCE (SIZE (1..maxSL-CommRxPoolPreconf-v1310)) OF SL-PreconfigCommPool-r12 + +SL-PreconfigCommTxPoolList-r13 ::= SEQUENCE (SIZE (1..maxSL-CommTxPoolPreconf-v1310)) OF SL-PreconfigCommPool-r12 + +SL-PreconfigCommPool-r12 ::= SEQUENCE { +-- This IE is same as SL-CommResourcePool with rxParametersNCell absent + sc-CP-Len-r12 SL-CP-Len-r12, + sc-Period-r12 SL-PeriodComm-r12, + sc-TF-ResourceConfig-r12 SL-TF-ResourceConfig-r12, + sc-TxParameters-r12 P0-SL-r12, + data-CP-Len-r12 SL-CP-Len-r12, + data-TF-ResourceConfig-r12 SL-TF-ResourceConfig-r12, + dataHoppingConfig-r12 SL-HoppingConfigComm-r12, + dataTxParameters-r12 P0-SL-r12, + trpt-Subset-r12 SL-TRPT-Subset-r12, + ..., + [[ priorityList-r13 SL-PriorityList-r13 OPTIONAL -- For Tx + ]] +} + +SL-PreconfigDiscRxPoolList-r13 ::= SEQUENCE (SIZE (1..maxSL-DiscRxPoolPreconf-r13)) OF SL-PreconfigDiscPool-r13 + +SL-PreconfigDiscTxPoolList-r13 ::= SEQUENCE (SIZE (1..maxSL-DiscTxPoolPreconf-r13)) OF SL-PreconfigDiscPool-r13 + +SL-PreconfigDiscPool-r13 ::= SEQUENCE { +-- This IE is same as SL-DiscResourcePool with rxParameters absent + cp-Len-r13 SL-CP-Len-r12, + discPeriod-r13 ENUMERATED {rf4, rf6, rf7, rf8, rf12, rf14, rf16, rf24, rf28, + rf32, rf64, rf128, rf256, rf512, rf1024, spare}, + numRetx-r13 INTEGER (0..3), + numRepetition-r13 INTEGER (1..50), + tf-ResourceConfig-r13 SL-TF-ResourceConfig-r12, + txParameters-r13 SEQUENCE { + txParametersGeneral-r13 P0-SL-r12, + txProbability-r13 ENUMERATED {p25, p50, p75, p100} + } OPTIONAL, + ... +} + +SL-PreconfigRelay-r13 ::= SEQUENCE { + reselectionInfoOoC-r13 ReselectionInfoRelay-r13 +} + + +SL-V2X-Preconfiguration-r14 ::= SEQUENCE (SIZE (1..maxFreq)) OF SL-V2X-PreconfigFreqInfo-r14 + +SL-V2X-PreconfigFreqInfo-r14 ::= SEQUENCE { + v2x-CommPreconfigGeneral-r14 SL-PreconfigGeneral-r12, + v2x-CommPreconfigSync-r14 SL-PreconfigSync-r12, + v2x-CommRxPoolList-r14 SL-PreconfigV2X-RxPoolList-r14, + v2x-CommTxPoolList-r14 SL-PreconfigV2X-TxPoolList-r14, + v2x-ResourceSelectionConfig-r14 SL-CommTxPoolSensingConfig-r14 OPTIONAL, + zoneConfig-r14 SL-ZoneConfig-r14 OPTIONAL, + ... +} + +SL-PreconfigV2X-RxPoolList-r14 ::= SEQUENCE (SIZE (1..maxSL-V2X-RxPoolPreconf-r14)) OF SL-V2X-PreconfigCommPool-r14 + +SL-PreconfigV2X-TxPoolList-r14 ::= SEQUENCE (SIZE (1..maxSL-V2X-TxPoolPreconf-r14)) OF SL-V2X-PreconfigCommPool-r14 + +SL-V2X-PreconfigCommPool-r14 ::= SEQUENCE { +-- This IE is same as SL-V2X-CommResourcePool with rxParametersNCell absent + sl-OffsetIndicator-r14 SL-OffsetIndicator-r12 OPTIONAL, + sl-Subframe-r14 SubframeBitmapSL-r14, + adjacencyPSCCH-PSSCH-r14 BOOLEAN, + sizeSubchannel-r14 ENUMERATED { + n4, n5, n6, n8, n9, n10, n12, n15, n16, n18, n20, n25, n30, + n48, n50, n72, n75, n96, n100, spare13, spare12, spare11, + spare10, spare9, spare8, spare7, spare6, spare5, spare4, + spare3, spare2, spare1}, + numSubchannel-r14 ENUMERATED {n1, n3, n5, n10, n15, n20, spare2, spare1}, + startRB-Subchannel-r14 INTEGER (0..99), + startRB-PSCCH-Pool-r14 INTEGER (0..99) OPTIONAL, + dataTxParameters-r14 SL-TxParameters-r12 OPTIONAL, + zoneID-r14 INTEGER (0..7) OPTIONAL, + ... +} + +END + + +EUTRA-InterNodeDefinitions DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + AntennaInfoCommon, + AntennaInfoDedicated-v10i0, + ARFCN-ValueEUTRA, + ARFCN-ValueEUTRA-v9e0, + ARFCN-ValueEUTRA-r9, + CellIdentity, + C-RNTI, + DL-DCCH-Message, + DRB-Identity, + DRB-ToReleaseList, + FreqBandIndicator-r11, + InDeviceCoexIndication-r11, + MasterInformationBlock, + maxBands, + maxFreq, + maxDRB, + maxSCell-r10, + maxSCell-r13, + maxServCell-r10, + maxServCell-r13, + MBMSInterestIndication-r11, + MeasConfig, + MeasGapConfig, + MeasResultForRSSI-r13, + OtherConfig-r9, + PhysCellId, + P-Max, + PowerCoordinationInfo-r12, + SidelinkUEInformation-r12, + SL-CommConfig-r12, + SL-DiscConfig-r12, + RadioResourceConfigDedicated, + RCLWI-Configuration-r13, + RSRP-Range, + RSRQ-Range, + RSRQ-Range-v1250, + RS-SINR-Range-r13, + SCellToAddModList-r10, + SCellToAddModListExt-r13, + SCG-ConfigPartSCG-r12, + SecurityAlgorithmConfig, + SCellIndex-r10, + SCellIndex-r13, + SCellToReleaseList-r10, + SCellToReleaseListExt-r13, + ServCellIndex-r10, + ServCellIndex-r13, + ShortMAC-I, + MeasResultSSTD-r13, + SL-V2X-ConfigDedicated-r14, + SystemInformationBlockType1, + SystemInformationBlockType1-v890-IEs, + SystemInformationBlockType2, + UEAssistanceInformation-r11, + UECapabilityInformation, + UE-CapabilityRAT-ContainerList, + UE-RadioPagingInfo-r12, + WLANConnectionStatusReport-r13, + WLAN-OffloadConfig-r12 +FROM EUTRA-RRC-Definitions; + + +HandoverCommand ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + handoverCommand-r8 HandoverCommand-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +HandoverCommand-r8-IEs ::= SEQUENCE { + handoverCommandMessage OCTET STRING (CONTAINING DL-DCCH-Message), + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +HandoverPreparationInformation ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + handoverPreparationInformation-r8 HandoverPreparationInformation-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +HandoverPreparationInformation-r8-IEs ::= SEQUENCE { + ue-RadioAccessCapabilityInfo UE-CapabilityRAT-ContainerList, + as-Config AS-Config OPTIONAL, -- Cond HO + rrm-Config RRM-Config OPTIONAL, + as-Context AS-Context OPTIONAL, -- Cond HO + nonCriticalExtension HandoverPreparationInformation-v920-IEs OPTIONAL +} + +HandoverPreparationInformation-v920-IEs ::= SEQUENCE { + ue-ConfigRelease-r9 ENUMERATED { + rel9, rel10, rel11, rel12, v10j0, v11e0, + v1280, rel13, ...} OPTIONAL, -- Cond HO2 + nonCriticalExtension HandoverPreparationInformation-v9d0-IEs OPTIONAL +} + +HandoverPreparationInformation-v9d0-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING (CONTAINING HandoverPreparationInformation-v9j0-IEs) OPTIONAL, + nonCriticalExtension HandoverPreparationInformation-v9e0-IEs OPTIONAL +} + +-- Late non-critical extensions: +HandoverPreparationInformation-v9j0-IEs ::= SEQUENCE { + -- Following field is only for pre REL-10 late non-critical extensions + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension HandoverPreparationInformation-v10j0-IEs OPTIONAL +} + +HandoverPreparationInformation-v10j0-IEs ::= SEQUENCE { + as-Config-v10j0 AS-Config-v10j0 OPTIONAL, + -- Following field is only for late non-critical extensions from REL-10 + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- Regular non-critical extensions: +HandoverPreparationInformation-v9e0-IEs ::= SEQUENCE { + as-Config-v9e0 AS-Config-v9e0 OPTIONAL, -- Cond HO2 + nonCriticalExtension HandoverPreparationInformation-v1130-IEs OPTIONAL +} + +HandoverPreparationInformation-v1130-IEs ::= SEQUENCE { + as-Context-v1130 AS-Context-v1130 OPTIONAL, -- Cond HO2 + nonCriticalExtension HandoverPreparationInformation-v1250-IEs OPTIONAL +} + +HandoverPreparationInformation-v1250-IEs ::= SEQUENCE { + ue-SupportedEARFCN-r12 ARFCN-ValueEUTRA-r9 OPTIONAL, -- Cond HO3 + as-Config-v1250 AS-Config-v1250 OPTIONAL, -- Cond HO2 + nonCriticalExtension HandoverPreparationInformation-v1320-IEs OPTIONAL +} + +HandoverPreparationInformation-v1320-IEs ::= SEQUENCE { + as-Config-v1320 AS-Config-v1320 OPTIONAL, -- Cond HO2 + as-Context-v1320 AS-Context-v1320 OPTIONAL, -- Cond HO2 + nonCriticalExtension HandoverPreparationInformation-v14x0-IEs OPTIONAL +} + +HandoverPreparationInformation-v14x0-IEs ::= SEQUENCE { + as-Config-v14x0 AS-Config-v14x0 OPTIONAL, -- Cond HO2 + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SCG-Config-r12 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + scg-Config-r12 SCG-Config-r12-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +SCG-Config-r12-IEs ::= SEQUENCE { + scg-RadioConfig-r12 SCG-ConfigPartSCG-r12 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +SCG-ConfigInfo-r12 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + scg-ConfigInfo-r12 SCG-ConfigInfo-r12-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +SCG-ConfigInfo-r12-IEs ::= SEQUENCE { + radioResourceConfigDedMCG-r12 RadioResourceConfigDedicated OPTIONAL, + sCellToAddModListMCG-r12 SCellToAddModList-r10 OPTIONAL, + measGapConfig-r12 MeasGapConfig OPTIONAL, + powerCoordinationInfo-r12 PowerCoordinationInfo-r12 OPTIONAL, + scg-RadioConfig-r12 SCG-ConfigPartSCG-r12 OPTIONAL, + eutra-CapabilityInfo-r12 OCTET STRING (CONTAINING UECapabilityInformation) OPTIONAL, + scg-ConfigRestrictInfo-r12 SCG-ConfigRestrictInfo-r12 OPTIONAL, + mbmsInterestIndication-r12 OCTET STRING (CONTAINING + MBMSInterestIndication-r11) OPTIONAL, + measResultServCellListSCG-r12 MeasResultServCellListSCG-r12 OPTIONAL, + drb-ToAddModListSCG-r12 DRB-InfoListSCG-r12 OPTIONAL, + drb-ToReleaseListSCG-r12 DRB-ToReleaseList OPTIONAL, + sCellToAddModListSCG-r12 SCellToAddModListSCG-r12 OPTIONAL, + sCellToReleaseListSCG-r12 SCellToReleaseList-r10 OPTIONAL, + p-Max-r12 P-Max OPTIONAL, + nonCriticalExtension SCG-ConfigInfo-v1310-IEs OPTIONAL +} + +SCG-ConfigInfo-v1310-IEs ::= SEQUENCE { + measResultSSTD-r13 MeasResultSSTD-r13 OPTIONAL, sCellToAddModListMCG-Ext-r13 SCellToAddModListExt-r13 OPTIONAL, + measResultServCellListSCG-Ext-r13 MeasResultServCellListSCG-Ext-r13 OPTIONAL, + sCellToAddModListSCG-Ext-r13 SCellToAddModListSCG-Ext-r13 OPTIONAL, + sCellToReleaseListSCG-Ext-r13 SCellToReleaseListExt-r13 OPTIONAL, + nonCriticalExtension SCG-ConfigInfo-v1330-IEs OPTIONAL +} + +SCG-ConfigInfo-v1330-IEs ::= SEQUENCE { + measResultListRSSI-SCG-r13 MeasResultListRSSI-SCG-r13 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +DRB-InfoListSCG-r12 ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-InfoSCG-r12 + +DRB-InfoSCG-r12 ::= SEQUENCE { + eps-BearerIdentity-r12 INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup + drb-Identity-r12 DRB-Identity, + drb-Type-r12 ENUMERATED {split, scg} OPTIONAL, -- Cond DRB-Setup + ... +} + +SCellToAddModListSCG-r12 ::= SEQUENCE (SIZE (1..maxSCell-r10)) OF Cell-ToAddMod-r12 + +SCellToAddModListSCG-Ext-r13 ::= SEQUENCE (SIZE (1..maxSCell-r13)) OF Cell-ToAddMod-r12 + +Cell-ToAddMod-r12 ::= SEQUENCE { + sCellIndex-r12 SCellIndex-r10, + cellIdentification-r12 SEQUENCE { + physCellId-r12 PhysCellId, + dl-CarrierFreq-r12 ARFCN-ValueEUTRA-r9 + } OPTIONAL, -- Cond SCellAdd + measResultCellToAdd-r12 SEQUENCE { + rsrpResult-r12 RSRP-Range, + rsrqResult-r12 RSRQ-Range + } OPTIONAL, -- Cond SCellAdd2 + ..., + [[ sCellIndex-r13 SCellIndex-r13 OPTIONAL, + measResultCellToAdd-v1310 SEQUENCE { + rs-sinr-Result-r13 RS-SINR-Range-r13 + } OPTIONAL -- Cond SCellAdd2 + ]] +} + +MeasResultServCellListSCG-r12 ::= SEQUENCE (SIZE (1..maxServCell-r10)) OF MeasResultServCellSCG-r12 + +MeasResultServCellListSCG-Ext-r13 ::= SEQUENCE (SIZE (1..maxServCell-r13)) OF MeasResultServCellSCG-r12 + +MeasResultServCellSCG-r12 ::= SEQUENCE { + servCellId-r12 ServCellIndex-r10, + measResultSCell-r12 SEQUENCE { + rsrpResultSCell-r12 RSRP-Range, + rsrqResultSCell-r12 RSRQ-Range + }, + ..., + [[ servCellId-r13 ServCellIndex-r13 OPTIONAL, + measResultSCell-v1310 SEQUENCE { + rs-sinr-ResultSCell-r13 RS-SINR-Range-r13 + } OPTIONAL + ]] +} + +MeasResultListRSSI-SCG-r13 ::= SEQUENCE (SIZE (1..maxServCell-r13)) OF MeasResultRSSI-SCG-r13 + +MeasResultRSSI-SCG-r13 ::= SEQUENCE { + servCellId-r13 ServCellIndex-r13, + measResultForRSSI-r13 MeasResultForRSSI-r13 +} + +SCG-ConfigRestrictInfo-r12 ::= SEQUENCE { + maxSCH-TB-BitsDL-r12 INTEGER (1..100), + maxSCH-TB-BitsUL-r12 INTEGER (1..100) +} + + +UEPagingCoverageInformation ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + uePagingCoverageInformation-r13 UEPagingCoverageInformation-r13-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEPagingCoverageInformation-r13-IEs ::= SEQUENCE { + mpdcch-NumRepetition-r13 INTEGER (1..256) OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UERadioAccessCapabilityInformation ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + ueRadioAccessCapabilityInformation-r8 + UERadioAccessCapabilityInformation-r8-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UERadioAccessCapabilityInformation-r8-IEs ::= SEQUENCE { + ue-RadioAccessCapabilityInfo OCTET STRING (CONTAINING UECapabilityInformation), + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UERadioPagingInformation ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + ueRadioPagingInformation-r12 UERadioPagingInformation-r12-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UERadioPagingInformation-r12-IEs ::= SEQUENCE { + ue-RadioPagingInfo-r12 OCTET STRING (CONTAINING UE-RadioPagingInfo-r12), + nonCriticalExtension UERadioPagingInformation-v1310-IEs OPTIONAL +} + +UERadioPagingInformation-v1310-IEs ::= SEQUENCE { + supportedBandListEUTRAForPaging-r13 SEQUENCE (SIZE (1..maxBands)) OF FreqBandIndicator-r11 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL + +} + + +AS-Config ::= SEQUENCE { + sourceMeasConfig MeasConfig, + sourceRadioResourceConfig RadioResourceConfigDedicated, + sourceSecurityAlgorithmConfig SecurityAlgorithmConfig, + sourceUE-Identity C-RNTI, + sourceMasterInformationBlock MasterInformationBlock, + sourceSystemInformationBlockType1 SystemInformationBlockType1(WITH COMPONENTS + {..., nonCriticalExtension ABSENT}), + sourceSystemInformationBlockType2 SystemInformationBlockType2, + antennaInfoCommon AntennaInfoCommon, + sourceDl-CarrierFreq ARFCN-ValueEUTRA, + ..., + [[ sourceSystemInformationBlockType1Ext OCTET STRING (CONTAINING + SystemInformationBlockType1-v890-IEs) OPTIONAL, + sourceOtherConfig-r9 OtherConfig-r9 + -- sourceOtherConfig-r9 should have been optional. A target eNB compliant with this transfer + -- syntax should support receiving an AS-Config not including this extension addition group + -- e.g. from a legacy source eNB + ]], + [[ sourceSCellConfigList-r10 SCellToAddModList-r10 OPTIONAL + ]], + [[ sourceConfigSCG-r12 SCG-Config-r12 OPTIONAL + ]] +} + +AS-Config-v9e0 ::= SEQUENCE { + sourceDl-CarrierFreq-v9e0 ARFCN-ValueEUTRA-v9e0 +} + +AS-Config-v10j0 ::= SEQUENCE { + antennaInfoDedicatedPCell-v10i0 AntennaInfoDedicated-v10i0 OPTIONAL +} + +AS-Config-v1250 ::= SEQUENCE { + sourceWlan-OffloadConfig-r12 WLAN-OffloadConfig-r12 OPTIONAL, + sourceSL-CommConfig-r12 SL-CommConfig-r12 OPTIONAL, + sourceSL-DiscConfig-r12 SL-DiscConfig-r12 OPTIONAL +} + +AS-Config-v1320 ::= SEQUENCE { + sourceSCellConfigList-r13 SCellToAddModListExt-r13 OPTIONAL, + sourceRCLWI-Configuration-r13 RCLWI-Configuration-r13 OPTIONAL +} + +AS-Config-v14x0 ::= SEQUENCE { + sourceSL-V2X-CommConfig-r14 SL-V2X-ConfigDedicated-r14 OPTIONAL +} + + +AS-Context ::= SEQUENCE { + reestablishmentInfo ReestablishmentInfo OPTIONAL -- Cond HO +} + +AS-Context-v1130 ::= SEQUENCE { + idc-Indication-r11 OCTET STRING (CONTAINING + InDeviceCoexIndication-r11) OPTIONAL, -- Cond HO2 + mbmsInterestIndication-r11 OCTET STRING (CONTAINING + MBMSInterestIndication-r11) OPTIONAL, -- Cond HO2 + powerPrefIndication-r11 OCTET STRING (CONTAINING + UEAssistanceInformation-r11) OPTIONAL, -- Cond HO2 + ..., + [[ sidelinkUEInformation-r12 OCTET STRING (CONTAINING + SidelinkUEInformation-r12) OPTIONAL -- Cond HO2 + ]] +} + +AS-Context-v1320 ::= SEQUENCE { + wlanConnectionStatusReport-r13 OCTET STRING (CONTAINING + WLANConnectionStatusReport-r13) OPTIONAL -- Cond HO2 +} + + +ReestablishmentInfo ::= SEQUENCE { + sourcePhysCellId PhysCellId, + targetCellShortMAC-I ShortMAC-I, + additionalReestabInfoList AdditionalReestabInfoList OPTIONAL, + ... +} + +AdditionalReestabInfoList ::= SEQUENCE ( SIZE (1..maxReestabInfo) ) OF AdditionalReestabInfo + +AdditionalReestabInfo ::= SEQUENCE{ + cellIdentity CellIdentity, + key-eNodeB-Star Key-eNodeB-Star, + shortMAC-I ShortMAC-I +} + +Key-eNodeB-Star ::= BIT STRING (SIZE (256)) + + +RRM-Config ::= SEQUENCE { + ue-InactiveTime ENUMERATED { + s1, s2, s3, s5, s7, s10, s15, s20, + s25, s30, s40, s50, min1, min1s20c, min1s40, + min2, min2s30, min3, min3s30, min4, min5, min6, + min7, min8, min9, min10, min12, min14, min17, min20, + min24, min28, min33, min38, min44, min50, hr1, + hr1min30, hr2, hr2min30, hr3, hr3min30, hr4, hr5, hr6, + hr8, hr10, hr13, hr16, hr20, day1, day1hr12, day2, + day2hr12, day3, day4, day5, day7, day10, day14, day19, + day24, day30, dayMoreThan30} OPTIONAL, + ..., + [[ candidateCellInfoList-r10 CandidateCellInfoList-r10 OPTIONAL + ]] +} + +CandidateCellInfoList-r10 ::= SEQUENCE (SIZE (1..maxFreq)) OF CandidateCellInfo-r10 + +CandidateCellInfo-r10 ::= SEQUENCE { + -- cellIdentification + physCellId-r10 PhysCellId, + dl-CarrierFreq-r10 ARFCN-ValueEUTRA, + -- available measurement results + rsrpResult-r10 RSRP-Range OPTIONAL, + rsrqResult-r10 RSRQ-Range OPTIONAL, + ..., + [[ dl-CarrierFreq-v1090 ARFCN-ValueEUTRA-v9e0 OPTIONAL + ]], + [[ rsrqResult-v1250 RSRQ-Range-v1250 OPTIONAL + ]], + [[ rs-sinr-Result-r13 RS-SINR-Range-r13 OPTIONAL + ]] +} + + +maxReestabInfo INTEGER ::= 32 -- Maximum number of KeNB* and shortMAC-I forwarded + -- at handover for re-establishment preparation + + +END + + +NBIOT-InterNodeDefinitions DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + C-RNTI, + PhysCellId, + SecurityAlgorithmConfig, + ShortMAC-I +FROM EUTRA-RRC-Definitions + + AdditionalReestabInfoList +FROM EUTRA-InterNodeDefinitions + + CarrierFreq-NB-r13, + RadioResourceConfigDedicated-NB-r13, + UE-Capability-NB-r13, + UE-RadioPagingInfo-NB-r13 +FROM NBIOT-RRC-Definitions; + + +HandoverPreparationInformation-NB ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + handoverPreparationInformation-r13 HandoverPreparationInformation-NB-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +HandoverPreparationInformation-NB-IEs ::= SEQUENCE { + ue-RadioAccessCapabilityInfo-r13 UE-Capability-NB-r13, + as-Config-r13 AS-Config-NB, + rrm-Config-r13 RRM-Config-NB OPTIONAL, + as-Context-r13 AS-Context-NB OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UEPagingCoverageInformation-NB ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + uePagingCoverageInformation-r13 UEPagingCoverageInformation-NB-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEPagingCoverageInformation-NB-IEs ::= SEQUENCE { +-- the possible value(s) can differ from those sent on Uu + npdcch-NumRepetitionPaging-r13 INTEGER (1..2048) OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UERadioAccessCapabilityInformation-NB ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + ueRadioAccessCapabilityInformation-r13 + UERadioAccessCapabilityInformation-NB-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UERadioAccessCapabilityInformation-NB-IEs ::= SEQUENCE { + ue-RadioAccessCapabilityInfo-r13 OCTET STRING (CONTAINING UE-Capability-NB-r13), + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +UERadioPagingInformation-NB ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + ueRadioPagingInformation-r13 UERadioPagingInformation-NB-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UERadioPagingInformation-NB-IEs ::= SEQUENCE { + ue-RadioPagingInfo-r13 OCTET STRING (CONTAINING UE-RadioPagingInfo-NB-r13), + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +AS-Config-NB ::= SEQUENCE { + sourceRadioResourceConfig-r13 RadioResourceConfigDedicated-NB-r13, + sourceSecurityAlgorithmConfig-r13 SecurityAlgorithmConfig, + sourceUE-Identity-r13 C-RNTI, + sourceDl-CarrierFreq-r13 CarrierFreq-NB-r13, + ... +} + + +AS-Context-NB ::= SEQUENCE { + reestablishmentInfo-r13 ReestablishmentInfo-NB OPTIONAL, + ... +} + + +ReestablishmentInfo-NB ::= SEQUENCE { + sourcePhysCellId-r13 PhysCellId, + targetCellShortMAC-I-r13 ShortMAC-I, + additionalReestabInfoList-r13 AdditionalReestabInfoList OPTIONAL, + ... +} + + + + +RRM-Config-NB ::= SEQUENCE { + ue-InactiveTime ENUMERATED { + s1, s2, s3, s5, s7, s10, s15, s20, + s25, s30, s40, s50, min1, min1s20, min1s40, + min2, min2s30, min3, min3s30, min4, min5, min6, + min7, min8, min9, min10, min12, min14, min17, min20, + min24, min28, min33, min38, min44, min50, hr1, + hr1min30, hr2, hr2min30, hr3, hr3min30, hr4, hr5, hr6, + hr8, hr10, hr13, hr16, hr20, day1, day1hr12, day2, + day2hr12, day3, day4, day5, day7, day10, day14, day19, + day24, day30, dayMoreThan30} OPTIONAL, + ... +} + + +END + + diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h index 47f8a0080a..0a2043fd4e 100644 --- a/openair2/RRC/LITE/defs.h +++ b/openair2/RRC/LITE/defs.h @@ -61,7 +61,7 @@ #include "RRCConnectionReestablishmentRequest.h" #include "BCCH-DL-SCH-Message.h" #include "BCCH-BCH-Message.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "MCCH-Message.h" #include "MBSFNAreaConfiguration-r9.h" #include "SCellToAddMod-r10.h" @@ -71,8 +71,59 @@ #include "UE-EUTRA-Capability.h" #include "MeasResults.h" +/* correct Rel(8|10)/Rel14 differences + * the code is in favor of Rel14, those defines do the translation + */ +#if !defined(Rel14) +# define CipheringAlgorithm_r12_t e_SecurityAlgorithmConfig__cipheringAlgorithm +# define CipheringAlgorithm_r12_eea0 SecurityAlgorithmConfig__cipheringAlgorithm_eea0 +# define CipheringAlgorithm_r12_eea1 SecurityAlgorithmConfig__cipheringAlgorithm_eea1 +# define CipheringAlgorithm_r12_eea2 SecurityAlgorithmConfig__cipheringAlgorithm_eea2 +# define CipheringAlgorithm_r12_spare1 SecurityAlgorithmConfig__cipheringAlgorithm_spare1 +# define Alpha_r12_al0 UplinkPowerControlCommon__alpha_al0 +# define Alpha_r12_al04 UplinkPowerControlCommon__alpha_al04 +# define Alpha_r12_al05 UplinkPowerControlCommon__alpha_al05 +# define Alpha_r12_al06 UplinkPowerControlCommon__alpha_al06 +# define Alpha_r12_al07 UplinkPowerControlCommon__alpha_al07 +# define Alpha_r12_al08 UplinkPowerControlCommon__alpha_al08 +# define Alpha_r12_al09 UplinkPowerControlCommon__alpha_al09 +# define Alpha_r12_al1 UplinkPowerControlCommon__alpha_al1 +# define PreambleTransMax_n3 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3 +# define PreambleTransMax_n4 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4 +# define PreambleTransMax_n5 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5 +# define PreambleTransMax_n6 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6 +# define PreambleTransMax_n7 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7 +# define PreambleTransMax_n8 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8 +# define PreambleTransMax_n10 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10 +# define PreambleTransMax_n20 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20 +# define PreambleTransMax_n50 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50 +# define PreambleTransMax_n100 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100 +# define PreambleTransMax_n200 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200 +# define PeriodicBSR_Timer_r12_sf5 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf5 +# define PeriodicBSR_Timer_r12_sf10 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf10 +# define PeriodicBSR_Timer_r12_sf16 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf16 +# define PeriodicBSR_Timer_r12_sf20 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf20 +# define PeriodicBSR_Timer_r12_sf32 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf32 +# define PeriodicBSR_Timer_r12_sf40 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf40 +# define PeriodicBSR_Timer_r12_sf64 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64 +# define PeriodicBSR_Timer_r12_sf80 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf80 +# define PeriodicBSR_Timer_r12_sf128 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf128 +# define PeriodicBSR_Timer_r12_sf160 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf160 +# define PeriodicBSR_Timer_r12_sf320 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf320 +# define PeriodicBSR_Timer_r12_sf640 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf640 +# define PeriodicBSR_Timer_r12_sf1280 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf1280 +# define PeriodicBSR_Timer_r12_sf2560 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf2560 +# define PeriodicBSR_Timer_r12_infinity MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity +# define RetxBSR_Timer_r12_sf320 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320 +# define RetxBSR_Timer_r12_sf640 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf640 +# define RetxBSR_Timer_r12_sf1280 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf1280 +# define RetxBSR_Timer_r12_sf2560 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560 +# define RetxBSR_Timer_r12_sf5120 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf5120 +# define RetxBSR_Timer_r12_sf10240 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240 +#endif + // This corrects something generated by asn1c which is different between Rel8 and Rel10 -#ifndef Rel10 +#if !defined(Rel10) && !defined(Rel14) #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member SystemInformation_r8_IEs_sib_TypeAndInfo_Member #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib2 #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib3 @@ -86,7 +137,7 @@ #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib11 #endif /* -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib12_v920 #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib13_v920 #endif @@ -194,7 +245,7 @@ typedef struct UE_RRC_INFO_s { uint8_t SIB1systemInfoValueTag; uint32_t SIStatus; uint32_t SIcnt; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA #endif uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 @@ -301,7 +352,7 @@ typedef struct HANDOVER_INFO_UE_s { typedef struct eNB_RRC_UE_s { uint8_t primaryCC_id; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) SCellToAddMod_r10_t sCell_config[2]; #endif SRB_ToAddModList_t* SRB_configList; @@ -329,7 +380,7 @@ typedef struct eNB_RRC_UE_s { uint8_t kenb[32]; #endif /* Used integrity/ciphering algorithms */ - e_SecurityAlgorithmConfig__cipheringAlgorithm ciphering_algorithm; + CipheringAlgorithm_r12_t ciphering_algorithm; e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; uint8_t Status; @@ -400,7 +451,7 @@ typedef struct { SystemInformationBlockType1_t *sib1; SystemInformationBlockType2_t *sib2; SystemInformationBlockType3_t *sib3; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) SystemInformationBlockType13_r9_t *sib13; uint8_t MBMS_flag; uint8_t num_mbsfn_sync_area; @@ -489,7 +540,7 @@ typedef struct UE_RRC_INST_s { SystemInformationBlockType10_t *sib10[NB_CNX_UE]; SystemInformationBlockType11_t *sib11[NB_CNX_UE]; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) uint8_t MBMS_flag; uint8_t *MCCH_MESSAGE[NB_CNX_UE]; uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; @@ -535,7 +586,7 @@ typedef struct UE_RRC_INST_s { #endif /* Used integrity/ciphering algorithms */ - e_SecurityAlgorithmConfig__cipheringAlgorithm ciphering_algorithm; + CipheringAlgorithm_r12_t ciphering_algorithm; e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; } UE_RRC_INST; diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index d89c4501cf..cedf5a11f5 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -53,7 +53,7 @@ #include "DL-DCCH-Message.h" #include "BCCH-DL-SCH-Message.h" #include "PCCH-Message.h" -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) #include "MCCH-Message.h" #endif #include "MeasConfig.h" @@ -145,7 +145,7 @@ static uint8_t check_trigger_meas_event( Q_OffsetRange_t ofn, Q_OffsetRange_t ocn, Hysteresis_t hys, Q_OffsetRange_t ofs, Q_OffsetRange_t ocs, long a3_offset, TimeToTrigger_t ttt); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); #endif @@ -256,7 +256,7 @@ static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType9_t) ); UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType10_t) ); UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType11_t) ); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType12_r9_t) ); UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType13_r9_t) ); #endif @@ -268,7 +268,7 @@ static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt = 0; } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) //----------------------------------------------------------------------------- #if 0 static void init_MCCH_UE(module_id_t ue_mod_idP, uint8_t eNB_index) @@ -328,8 +328,8 @@ char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_ UE_rrc_inst[ctxt.module_id].Srb1[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].Srb2[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].HandoverInfoUe.measFlag=1; - UE_rrc_inst[ctxt.module_id].ciphering_algorithm = SecurityAlgorithmConfig__cipheringAlgorithm_eea0; -#ifdef Rel10 + UE_rrc_inst[ctxt.module_id].ciphering_algorithm = CipheringAlgorithm_r12_eea0; +#if defined(Rel10) || defined(Rel14) UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920; #else UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved; @@ -821,7 +821,7 @@ rrc_ue_process_measConfig( rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -838,7 +838,7 @@ rrc_ue_process_measConfig( NULL, NULL, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -1270,7 +1270,7 @@ rrc_ue_process_radioResourceConfigDedicated( kRRCenc, kRRCint, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,(PMCH_InfoList_r9_t *)NULL #endif ,NULL); @@ -1280,7 +1280,7 @@ rrc_ue_process_radioResourceConfigDedicated( radioResourceConfigDedicated->srb_ToAddModList, (DRB_ToAddModList_t*)NULL, (DRB_ToReleaseList_t*)NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,(PMCH_InfoList_r9_t *)NULL #endif ); @@ -1319,7 +1319,7 @@ rrc_ue_process_radioResourceConfigDedicated( rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -1336,7 +1336,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -1377,7 +1377,7 @@ rrc_ue_process_radioResourceConfigDedicated( rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -1394,7 +1394,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -1450,7 +1450,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, kUPenc -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,(PMCH_InfoList_r9_t *)NULL #endif , UE_rrc_inst[ctxt_pP->module_id].defaultDRB); @@ -1460,7 +1460,7 @@ rrc_ue_process_radioResourceConfigDedicated( (SRB_ToAddModList_t*)NULL, radioResourceConfigDedicated->drb_ToAddModList, (DRB_ToReleaseList_t*)NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,(PMCH_InfoList_r9_t *)NULL #endif ); @@ -1484,7 +1484,7 @@ rrc_ue_process_radioResourceConfigDedicated( rrc_mac_config_req(ctxt_pP->module_id,0,ENB_FLAG_NO,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif @@ -1501,7 +1501,7 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -1555,26 +1555,26 @@ rrc_ue_process_securityModeCommand( ctxt_pP->module_id,ctxt_pP->frame,eNB_index); switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) { - case SecurityAlgorithmConfig__cipheringAlgorithm_eea0: + case CipheringAlgorithm_r12_eea0: LOG_I(RRC,"[UE %d] Security algorithm is set to eea0\n", ctxt_pP->module_id); - securityMode= SecurityAlgorithmConfig__cipheringAlgorithm_eea0; + securityMode= CipheringAlgorithm_r12_eea0; break; - case SecurityAlgorithmConfig__cipheringAlgorithm_eea1: + case CipheringAlgorithm_r12_eea1: LOG_I(RRC,"[UE %d] Security algorithm is set to eea1\n",ctxt_pP->module_id); - securityMode= SecurityAlgorithmConfig__cipheringAlgorithm_eea1; + securityMode= CipheringAlgorithm_r12_eea1; break; - case SecurityAlgorithmConfig__cipheringAlgorithm_eea2: + case CipheringAlgorithm_r12_eea2: LOG_I(RRC,"[UE %d] Security algorithm is set to eea2\n", ctxt_pP->module_id); - securityMode = SecurityAlgorithmConfig__cipheringAlgorithm_eea2; + securityMode = CipheringAlgorithm_r12_eea2; break; default: LOG_I(RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id); - securityMode = SecurityAlgorithmConfig__cipheringAlgorithm_spare1; + securityMode = CipheringAlgorithm_r12_spare1; break; } @@ -2000,18 +2000,18 @@ rrc_ue_process_mobilityControlInfo( NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption - #ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,NULL - #endif +#endif ,NULL); rrc_rlc_config_asn1_req(NB_eNB_INST+ue_mod_idP, frameP,0,eNB_index, NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList drb2release_list // DRB_ToReleaseList - #ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,NULL - #endif +#endif ,NULL); */ @@ -2046,7 +2046,7 @@ rrc_ue_process_mobilityControlInfo( eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -2063,7 +2063,7 @@ rrc_ue_process_mobilityControlInfo( NULL, NULL, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL @@ -2416,7 +2416,7 @@ rrc_ue_decode_dcch( case DL_DCCH_MessageType__c1_PR_counterCheck: break; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) case DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9: break; @@ -2431,7 +2431,9 @@ rrc_ue_decode_dcch( case DL_DCCH_MessageType__c1_PR_spare1: case DL_DCCH_MessageType__c1_PR_spare2: case DL_DCCH_MessageType__c1_PR_spare3: +#if !defined(Rel14) case DL_DCCH_MessageType__c1_PR_spare4: +#endif break; default: @@ -2900,7 +2902,7 @@ static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ rrc_mac_config_req(ctxt_pP->module_id, 0, ENB_FLAG_NO, 0, eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -2917,7 +2919,7 @@ static int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ NULL, NULL, (MBSFN_SubframeConfigList_t *)NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL @@ -3174,7 +3176,7 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 ) LOG_I( RRC, "radioResourceConfigCommon.ul_CyclicPrefixLength : %ld\n", sib2->radioResourceConfigCommon.ul_CyclicPrefixLength ); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) // UplinkPowerControlCommon_v1020 // ... #endif @@ -3206,7 +3208,7 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 ) LOG_I( RRC, "timeAlignmentTimerCommon : %ld\n", sib2->timeAlignmentTimerCommon ); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (sib2->lateNonCriticalExtension) { LOG_I( RRC, "lateNonCriticalExtension : %p\n", sib2->lateNonCriticalExtension ); @@ -3475,7 +3477,7 @@ static void dump_sib5( SystemInformationBlockType5_t *sib5 ) } } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (ifcfInfo->ext1 && ifcfInfo->ext1->q_QualMin_r9) LOG_I(RRC," Q_QualMin_r9 : %ld\n",*ifcfInfo->ext1->q_QualMin_r9); @@ -3488,7 +3490,7 @@ static void dump_sib5( SystemInformationBlockType5_t *sib5 ) } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) static void dump_sib13( SystemInformationBlockType13_r9_t *sib13 ) { LOG_I( RRC, "[UE] Dumping SIB13\n" ); @@ -3536,7 +3538,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in rrc_mac_config_req(ctxt_pP->module_id, 0, ENB_FLAG_NO, 0, eNB_index, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->radioResourceConfigCommon, (struct PhysicalConfigDedicated *)NULL, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, #endif (MeasObjectToAddMod_t **)NULL, @@ -3552,7 +3554,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,0, (MBSFN_AreaInfoList_r9_t *)NULL, (PMCH_InfoList_r9_t *)NULL @@ -3563,7 +3565,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in #endif ); // After SI is received, prepare RRCConnectionRequest -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option #endif @@ -3694,7 +3696,7 @@ static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_in } break; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2048) == 0) { @@ -4103,7 +4105,7 @@ static uint8_t check_trigger_meas_event( return 0; } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) //----------------------------------------------------------------------------- int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t* const Sdu, const uint8_t Sdu_len, const uint8_t mbsfn_sync_area ) { @@ -4177,7 +4179,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i rrc_mac_config_req(ue_mod_idP,0,ENB_FLAG_NO,0,eNB_index, (RadioResourceConfigCommonSIB_t *)NULL, (struct PhysicalConfigDedicated *)NULL, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -4194,7 +4196,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i NULL, NULL, (MBSFN_SubframeConfigList_t *)NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *)NULL, @@ -4220,7 +4222,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ,&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) #endif ,NULL); @@ -4229,7 +4231,7 @@ static void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_i NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList NULL,// DRB_ToReleaseList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) &(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) #endif ); @@ -4336,7 +4338,7 @@ void *rrc_ue_task( void *args_p ) RRC_MAC_CCCH_DATA_IND (msg_p).enb_index); break; -# ifdef Rel10 +# if defined(Rel10) || defined(Rel14) case RRC_MAC_MCCH_DATA_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, msg_name, diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index b039ecd8de..3f7fa3067c 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -265,7 +265,7 @@ openair_rrc_top_init( UE_rrc_inst[module_id].UECapability_size = UECap->sdu_size; } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) LOG_I(RRC,"[UE] eMBMS active state is %d \n", eMBMS_active); for (module_id=0; module_idmodule_id].carrier[CC_id].systemInformation, &eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib2, &eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib3 -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , &eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib13, eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].MBMS_flag #endif @@ -281,7 +281,7 @@ init_SI( eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. ul_ReferenceSignalsPUSCH.cyclicShift); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) if (eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].MBMS_flag > 0) { for (i = 0; i < eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count; i++) { @@ -326,7 +326,7 @@ init_SI( (RadioResourceConfigCommonSIB_t *) & eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib2->radioResourceConfigCommon, (struct PhysicalConfigDedicated *)NULL, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -341,7 +341,7 @@ init_SI( eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib2->freqInfo.ul_Bandwidth, &eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission, (MBSFN_SubframeConfigList_t*) eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib2->mbsfn_SubframeConfigList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].MBMS_flag, (MBSFN_AreaInfoList_r9_t*) & eNB_rrc_inst[ctxt_pP->module_id].carrier[CC_id].sib13->mbsfn_AreaInfoList_r9, @@ -359,7 +359,7 @@ init_SI( } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) /*------------------------------------------------------------------------------*/ static void init_MCCH( @@ -422,7 +422,7 @@ init_MCCH( rrc_mac_config_req(enb_mod_idP, CC_id, ENB_FLAG_YES, 0, 0, (RadioResourceConfigCommonSIB_t *) NULL, (struct PhysicalConfigDedicated *)NULL, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -433,7 +433,7 @@ init_MCCH( (MeasGapConfig_t *) NULL, (TDD_Config_t *) NULL, NULL, (uint8_t *) NULL, (uint16_t *) NULL, NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -# ifdef Rel10 +# if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, @@ -473,7 +473,7 @@ static void init_MBMS( NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -# ifdef Rel10 +# if defined(Rel10) || defined(Rel14) , &(eNB_rrc_inst[enb_mod_idP].carrier[CC_id].mcch_message->pmch_InfoList_r9) # endif ,NULL); @@ -693,7 +693,7 @@ rrc_eNB_free_mem_UE_context( PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); #endif @@ -1369,7 +1369,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , (SCellToAddMod_r10_t*)NULL #endif ); @@ -1469,7 +1469,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; MeasIdToAddModList_t *MeasId_list = NULL; MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; -#if Rel10 +#if defined(Rel10) || defined(Rel14) long *sr_ProhibitTimer_r9 = NULL; // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); //uint8_t sCellIndexToAdd = 0; @@ -1671,9 +1671,9 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons *maxHARQ_Tx = MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; periodicBSR_Timer = CALLOC(1, sizeof(long)); - *periodicBSR_Timer = MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64; + *periodicBSR_Timer = PeriodicBSR_Timer_r12_sf64; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = RetxBSR_Timer_r12_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE mac_MainConfig->timeAlignmentTimerDedicated = TimeAlignmentTimer_infinity; @@ -1689,7 +1689,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR mac_MainConfig->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); @@ -1756,7 +1756,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons //feedback mode needs to be set as well //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable printf("setting cqi reporting mode to rm31\n"); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportModeAperiodic_rm31; #else *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI @@ -2102,7 +2102,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons (RSRP_Range_t*)rsrp, (C_RNTI_t*)cba_RNTI, (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , (SCellToAddMod_r10_t*)NULL #endif ); @@ -2173,7 +2173,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( uint8_t size; uint8_t buffer[100]; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) uint8_t sCellIndexToAdd = 0; //one SCell so far // uint8_t sCellIndexToAdd; @@ -2207,7 +2207,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( (C_RNTI_t*)NULL, (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , ue_context_pP->ue_context.sCell_config #endif ); @@ -2264,7 +2264,7 @@ rrc_eNB_process_MeasurementReport( measResult.rsrqResult)); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) LOG_I(RRC, "RSRP of Source %ld\n", measResults2->measResultPCell.rsrpResult); LOG_I(RRC, "RSRQ of Source %ld\n", measResults2->measResultPCell.rsrqResult); #else @@ -2531,7 +2531,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( // HandoverCommand_t handoverCommand; //uint8_t sourceModId = // get_adjacent_cell_mod_id(ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId); -#if Rel10 +#if defined(Rel10) || defined(Rel14) long *sr_ProhibitTimer_r9; #endif @@ -2779,7 +2779,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 0, (RadioResourceConfigCommonSIB_t*) NULL, ue_context_pP->ue_context.physicalConfigDedicated, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -2796,7 +2796,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA @@ -2899,10 +2899,10 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; periodicBSR_Timer = CALLOC(1, sizeof(long)); - *periodicBSR_Timer = MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64; + *periodicBSR_Timer = PeriodicBSR_Timer_r12_sf64; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = RetxBSR_Timer_r12_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE @@ -2917,7 +2917,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR mac_MainConfig->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); @@ -3279,7 +3279,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( rrc_pdcp_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, (DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , (PMCH_InfoList_r9_t *) NULL #endif ,NULL); @@ -3287,7 +3287,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( rrc_rlc_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, (DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , (PMCH_InfoList_r9_t *) NULL #endif ); @@ -3318,7 +3318,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( NULL, NULL, dedicatedInfoNASList -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , NULL // SCellToAddMod_r10_t #endif ); @@ -3353,7 +3353,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 0, (RadioResourceConfigCommonSIB_t *) NULL, ue_context_pP->ue_context.physicalConfigDedicated, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -3365,7 +3365,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( (TDD_Config_t *) NULL, (MobilityControlInfo_t *) mobilityInfo, (uint8_t *) NULL, (uint16_t *) NULL, NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA @@ -3521,7 +3521,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( kRRCenc, kRRCint, kUPenc -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , (PMCH_InfoList_r9_t *) NULL #endif ,NULL); @@ -3531,7 +3531,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( SRB_configList, // NULL, //LG-RK 14/05/2014 SRB_configList, DRB_configList, (DRB_ToReleaseList_t *) NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , (PMCH_InfoList_r9_t *) NULL #endif ); @@ -3651,7 +3651,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( 0, (RadioResourceConfigCommonSIB_t *) NULL, ue_context_pP->ue_context.physicalConfigDedicated, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -3664,7 +3664,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( NULL, (uint8_t *) NULL, (uint16_t *) NULL, NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA @@ -3699,7 +3699,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( 0, (RadioResourceConfigCommonSIB_t *) NULL, ue_context_pP->ue_context.physicalConfigDedicated, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -3710,7 +3710,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (MeasGapConfig_t *) NULL, (TDD_Config_t *) NULL, NULL, (uint8_t *) NULL, (uint16_t *) NULL, NULL, NULL, NULL, NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA @@ -3794,7 +3794,7 @@ rrc_eNB_generate_RRCConnectionSetup( 0, (RadioResourceConfigCommonSIB_t *) NULL, ue_context_pP->ue_context.physicalConfigDedicated, -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) (SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif @@ -3807,7 +3807,7 @@ rrc_eNB_generate_RRCConnectionSetup( NULL, (uint8_t *) NULL, (uint16_t *) NULL, NULL, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL #endif #ifdef CBA @@ -3923,11 +3923,15 @@ while ( eNB_rrc_inst == NULL ) { LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) // This has to come from some top-level configuration // only CC_id 0 is logged +#if defined(Rel10) LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel10 RRC detected, MBMS flag %d\n", +#else + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel14 RRC detected, MBMS flag %d\n", +#endif PROTOCOL_RRC_CTXT_ARGS(&ctxt), eNB_rrc_inst[ctxt.module_id].carrier[0].MBMS_flag); @@ -3966,7 +3970,7 @@ while ( eNB_rrc_inst == NULL ) { ); } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { switch (eNB_rrc_inst[ctxt.module_id].carrier[CC_id].MBMS_flag) { @@ -4349,7 +4353,7 @@ rrc_eNB_decode_ccch( NULL, NULL, NULL -# ifdef Rel10 +# if defined(Rel10) || defined(Rel14) , (PMCH_InfoList_r9_t *) NULL # endif ,NULL); @@ -4358,7 +4362,7 @@ rrc_eNB_decode_ccch( ue_context_p->ue_context.SRB_configList, (DRB_ToAddModList_t*) NULL, (DRB_ToReleaseList_t*) NULL -# ifdef Rel10 +# if defined(Rel10) || defined(Rel14) , (PMCH_InfoList_r9_t *) NULL # endif ); @@ -4871,7 +4875,7 @@ rrc_eNB_decode_dcch( break; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) case UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: T(T_ENB_RRC_UE_INFORMATION_RESPONSE_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c index 8984eb933c..3642d02a1c 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c @@ -69,7 +69,7 @@ static const uint16_t S1AP_ENCRYPTION_EEA2_MASK = 0x4000; static const uint16_t S1AP_INTEGRITY_EIA1_MASK = 0x8000; static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x4000; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) # define INTEGRITY_ALGORITHM_NONE SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920 #else #ifdef EXMIMO_IOT @@ -228,21 +228,21 @@ rrc_eNB_get_ue_context_from_s1ap_ids( *\param algorithms The bit mask of available algorithms received from S1AP. *\return the selected algorithm. */ -static e_SecurityAlgorithmConfig__cipheringAlgorithm rrc_eNB_select_ciphering(uint16_t algorithms) +static CipheringAlgorithm_r12_t rrc_eNB_select_ciphering(uint16_t algorithms) { //#warning "Forced return SecurityAlgorithmConfig__cipheringAlgorithm_eea0, to be deleted in future" - return SecurityAlgorithmConfig__cipheringAlgorithm_eea0; + return CipheringAlgorithm_r12_eea0; if (algorithms & S1AP_ENCRYPTION_EEA2_MASK) { - return SecurityAlgorithmConfig__cipheringAlgorithm_eea2; + return CipheringAlgorithm_r12_eea2; } if (algorithms & S1AP_ENCRYPTION_EEA1_MASK) { - return SecurityAlgorithmConfig__cipheringAlgorithm_eea1; + return CipheringAlgorithm_r12_eea1; } - return SecurityAlgorithmConfig__cipheringAlgorithm_eea0; + return CipheringAlgorithm_r12_eea0; } /*! \fn e_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms) @@ -279,7 +279,7 @@ rrc_eNB_process_security( ) { boolean_t changed = FALSE; - e_SecurityAlgorithmConfig__cipheringAlgorithm cipheringAlgorithm; + CipheringAlgorithm_r12_t cipheringAlgorithm; e_SecurityAlgorithmConfig__integrityProtAlgorithm integrityProtAlgorithm; /* Save security parameters */ diff --git a/openair2/RRC/LITE/vars.h b/openair2/RRC/LITE/vars.h index 5431504738..71b00b278c 100644 --- a/openair2/RRC/LITE/vars.h +++ b/openair2/RRC/LITE/vars.h @@ -80,7 +80,7 @@ struct LogicalChannelConfig__ul_SpecificParameters LCSRB2 = {3, }; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) struct LogicalChannelConfig__ext1 logicalChannelSR_Mask_r9_ext1 = { logicalChannelSR_Mask_r9: &logicalChannelSR_Mask_r9 }; @@ -88,14 +88,14 @@ struct LogicalChannelConfig__ext1 logicalChannelSR_Mask_r9_ext1 = { // These are the default SRB configurations from 36.331 (Chapter 9, p. 176-179 in v8.6) LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB1 -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , ext1: &logicalChannelSR_Mask_r9_ext1 #endif }; LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB2 -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) , ext1: &logicalChannelSR_Mask_r9_ext1 #endif diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index f1b3944a16..fd6b67c334 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -929,7 +929,7 @@ l2l1_task (void *args_p) } } -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) for (RN_id=oai_emulation.info.first_rn_local; RN_id= 46) {// only generate when UE can receive MTCH (need to control this value) for (service_id = 0; service_id < 2 ; service_id++) { //maxServiceCount for (session_id = 0; session_id < 2; session_id++) { // maxSessionPerPMCH From 774452bbbba32df8b6bca3886a1c5b993dc74447 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 11:50:56 +0100 Subject: [PATCH 429/571] compilation warning removal this variable does not seem to be used, to be removed? --- openair1/SCHED/phy_procedures_lte_ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index a94847f83f..1d87ba0c41 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1823,7 +1823,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin uint8_t pucch_ack_payload[2]; - uint8_t n2_pucch; + uint8_t n2_pucch = -1; uint16_t pucch_resource; ANFBmode_t bundling_flag; PUCCH_FMT_t format; From 11856c6b00f96ff6b4e7c4e29440833a0c7db53f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 11:53:34 +0100 Subject: [PATCH 430/571] compilation warning removal: allocate_REs set but not used I removed this variable entirely because it's not used. Maybe the bug is that it's not used after being set? To be checked and fixed at some point. --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index e24edb8d68..0c3434b7d8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2015,6 +2015,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, int16_t qam16_table_a1[4],qam64_table_a1[8],qam16_table_b1[4],qam64_table_b1[8]; int16_t *qam_table_s0=NULL,*qam_table_s1=NULL; +#if 0 + /* TODO: variable to be removed? */ int (*allocate_REs)(PHY_VARS_eNB*, int **, uint32_t*, @@ -2036,6 +2038,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, uint8_t, int *, int *); +#endif int P1_SHIFT[13],P2_SHIFT[13]; int offset,nushiftmod3; @@ -2242,7 +2245,10 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, re_offset = frame_parms->first_carrier_offset; symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe_offset*nsymb)); +#if 0 + /* TODO: remove this code? */ allocate_REs = allocate_REs_in_RB; +#endif switch (mod_order0) { case 2: @@ -2251,15 +2257,21 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, case 4: if (pilots) { qam_table_s0 = qam16_table_b0; +#if 0 + /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_pilots_16QAM_siso : allocate_REs_in_RB; +#endif } else { qam_table_s0 = qam16_table_a0; +#if 0 + /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_no_pilots_16QAM_siso : allocate_REs_in_RB; +#endif } break; @@ -2267,15 +2279,21 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, case 6: if (pilots) { qam_table_s0 = qam64_table_b0; +#if 0 + /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_pilots_64QAM_siso : allocate_REs_in_RB; +#endif } else { qam_table_s0 = qam64_table_a0; +#if 0 + /* TODO: remove this code? */ allocate_REs = (dlsch0->harq_processes[harq_pid]->mimo_mode == SISO) ? allocate_REs_in_RB_no_pilots_64QAM_siso : allocate_REs_in_RB; +#endif } break; @@ -2284,7 +2302,10 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, switch (mod_order1) { case 2: qam_table_s1 = NULL; +#if 0 + /* TODO: remove this code? */ allocate_REs = allocate_REs_in_RB; +#endif break; case 4: if (pilots) { From 8dd8a97c343743dc40dbf5b282028f8e427d9775 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 11:55:32 +0100 Subject: [PATCH 431/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 0c3434b7d8..f05e4570a6 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -584,7 +584,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, int first_layer0; //= dlsch0_harq->first_layer; - int Nlayers0; // = dlsch0_harq->Nlayers; + int Nlayers0 = -1; // = dlsch0_harq->Nlayers; uint8_t mod_order0=0; // = get_Qm(dlsch0_harq->mcs); uint8_t mod_order1=0; //=2; uint8_t precoder_index0,precoder_index1; From 216cd0bf02887625b1a011403088ad7f71da0a30 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 11:56:34 +0100 Subject: [PATCH 432/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index f05e4570a6..2f10a2fdc8 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -578,7 +578,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, { uint8_t *x0 = NULL; - MIMO_mode_t mimo_mode; + MIMO_mode_t mimo_mode = -1; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; From 2291f4ebec1e706b9ccf0f49608482fbbab28cea Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 11:58:01 +0100 Subject: [PATCH 433/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 2f10a2fdc8..1633cc176c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2045,7 +2045,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, uint8_t get_pmi_temp; - MIMO_mode_t mimo_mode; + MIMO_mode_t mimo_mode = -1; uint8_t mprime=0,Ns; int8_t lprime=-1; int aa=0; From d8627b5e3f796ffa53a06578ea0d58d7430a0aca Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 11:59:27 +0100 Subject: [PATCH 434/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 1633cc176c..1bff935555 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2004,7 +2004,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, uint32_t i,i2,jj,jj2,re_allocated,symbol_offset; uint16_t l,rb,re_offset; uint32_t rb_alloc_ind; - uint32_t *rb_alloc; //=dlsch0_harq->rb_alloc; + uint32_t *rb_alloc = NULL; //=dlsch0_harq->rb_alloc; uint8_t pilots=0; uint8_t skip_dc,skip_half; From bf3a4f646479609b621eb65082fbd6d416ab35ba Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:00:04 +0100 Subject: [PATCH 435/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 1bff935555..941e1b37c2 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2000,7 +2000,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, uint8_t nsymb; uint8_t harq_pid; //= dlsch0->current_harq_pid; LTE_DL_eNB_HARQ_t *dlsch0_harq; - LTE_DL_eNB_HARQ_t *dlsch1_harq; //= dlsch1->harq_processes[harq_pid]; + LTE_DL_eNB_HARQ_t *dlsch1_harq = NULL; //= dlsch1->harq_processes[harq_pid]; uint32_t i,i2,jj,jj2,re_allocated,symbol_offset; uint16_t l,rb,re_offset; uint32_t rb_alloc_ind; From e82c6764f937f6fd73d7836269dbb017d7a0bf18 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:00:23 +0100 Subject: [PATCH 436/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 941e1b37c2..2e38574d45 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1999,7 +1999,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, uint8_t nsymb; uint8_t harq_pid; //= dlsch0->current_harq_pid; - LTE_DL_eNB_HARQ_t *dlsch0_harq; + LTE_DL_eNB_HARQ_t *dlsch0_harq = NULL; LTE_DL_eNB_HARQ_t *dlsch1_harq = NULL; //= dlsch1->harq_processes[harq_pid]; uint32_t i,i2,jj,jj2,re_allocated,symbol_offset; uint16_t l,rb,re_offset; From 1789b3de599e27865964a4a89f018fa24d30229d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:00:58 +0100 Subject: [PATCH 437/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 2e38574d45..a344d2b208 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1998,7 +1998,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; uint8_t nsymb; - uint8_t harq_pid; //= dlsch0->current_harq_pid; + uint8_t harq_pid = -1; //= dlsch0->current_harq_pid; LTE_DL_eNB_HARQ_t *dlsch0_harq = NULL; LTE_DL_eNB_HARQ_t *dlsch1_harq = NULL; //= dlsch1->harq_processes[harq_pid]; uint32_t i,i2,jj,jj2,re_allocated,symbol_offset; From a3f7ceb3958c81d9d419a217d5f1d92549ede0e8 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:02:08 +0100 Subject: [PATCH 438/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index cb1129f8cb..e7f98cea1a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -123,8 +123,8 @@ int rx_pdsch(PHY_VARS_UE *ue, int32_t **rxdataF_comp_ptr; int32_t **dl_ch_mag_ptr; - int32_t codeword_TB0; - int32_t codeword_TB1; + int32_t codeword_TB0 = -1; + int32_t codeword_TB1 = -1; From 3ce5f507554228b72c38d206841282e6025afcae Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:03:56 +0100 Subject: [PATCH 439/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/proto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 409c41da4f..26398c085d 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1899,7 +1899,7 @@ uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_subba int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb); -//uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands); +uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands); uint64_t pmi2hex_2Ar1(uint32_t pmi); From 048f07f67f812e0902365cc475736bfa80d7f201 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:07:51 +0100 Subject: [PATCH 440/571] compilation warning removal --- openair1/PHY/LTE_TRANSPORT/if5_tools.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index 399ebc4da2..b4fc0722d1 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -56,7 +56,9 @@ void send_IF5(PHY_VARS_eNB *eNB, openair0_timestamp proc_timestamp, int subframe LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; int32_t *tx_buffer=NULL; +#ifdef DEBUG_DL_MOBIPASS int8_t dummy_buffer[fp->samples_per_tti*2]; +#endif void *alaw_buffer = eNB->ifbuffer.tx[subframe&1]; uint16_t *data_block = NULL; uint16_t *j = NULL; @@ -262,8 +264,10 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; uint16_t packet_id=0, i=0, element_id=0; - int8_t dummy_buffer_rx[fp->samples_per_tti*2]; +#ifdef DEBUG_UL_MOBIPASS + //int8_t dummy_buffer_rx[fp->samples_per_tti*2]; uint8_t rxe; +#endif int32_t spp_eth = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_packet; int32_t spsf = (int32_t) eNB->ifdevice.openair0_cfg->samples_per_frame/10; @@ -390,14 +394,16 @@ void recv_IF5(PHY_VARS_eNB *eNB, openair0_timestamp *proc_timestamp, int subfram uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength]; +#ifdef DEBUG_UL_MOBIPASS int lower_offset = 0; int upper_offset = 70000; +#endif int subframe_skip = 0; int reset_flag = 0; int32_t *rx_buffer=NULL; __m128i *data_block=NULL, *data_block_head=NULL; __m128i *rxp128; - __m128i r0, r1; + __m128i r0; //rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); From 7514e7139a7c36f0f8bd76446591ee73fcd4b9a1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:08:31 +0100 Subject: [PATCH 441/571] compilation warning removal --- openair1/PHY/MODULATION/beamforming.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index d2336f6187..91489b83c5 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -47,7 +47,7 @@ int beam_precoding(int32_t **txdataF, int aa) { uint8_t p; - uint16_t re=0; + //uint16_t re=0; int slot_offset_F; slot_offset_F = slot*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7); From 92ee6017cd5610ef5e06f10a9f59c16b5b151dae Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:09:09 +0100 Subject: [PATCH 442/571] compilation warning removal --- openair1/PHY/INIT/lte_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index d2a814c175..0b27cdc84d 100755 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -1213,7 +1213,7 @@ int phy_init_lte_ue(PHY_VARS_UE *ue, } - const size_t num = 7*2*fp->N_RB_DL*12+4; + //const size_t num = 7*2*fp->N_RB_DL*12+4; for (k=0;k<8;k++) { //harq_pid for (l=0;l<8;l++) { //round pdsch_vars_th0[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); From aaac4894c93a3e35455020cc96115f7a377d4584 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:17:08 +0100 Subject: [PATCH 443/571] compilation warning removal --- targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c index 3b6db934b6..9420ae1c88 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -139,7 +139,7 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam IF4p5_header_t *test_header = (IF4p5_header_t*)(buff[0]); int block_cnt=0; - int again_cnt=0; + //int again_cnt=0; packet_size = max(UDP_IF4p5_PRACH_SIZE_BYTES, max(UDP_IF4p5_PULFFT_SIZE_BYTES(nblocks), UDP_IF4p5_PDLFFT_SIZE_BYTES(nblocks))); while(bytes_received == -1) { From b3d9e198996f54967015e634b9d2fc48034c487e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:21:04 +0100 Subject: [PATCH 444/571] compilation warning removal --- targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c index 9420ae1c88..9f6c01afed 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -410,7 +410,7 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi eth->pck_seq_num_cur = *(uint16_t *)buff2; if ( ( eth->pck_seq_num_cur != (eth->pck_seq_num_prev + 1) ) && !((eth->pck_seq_num_prev==MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame)) && (eth->pck_seq_num_cur==1 )) && !((eth->pck_seq_num_prev==1) && (eth->pck_seq_num_cur==1))) { //#if DEBUG - printf("Out of order packet received: current_packet=%d previous_packet=%d timestamp=%llu\n",eth->pck_seq_num_cur,eth->pck_seq_num_prev,*timestamp); + printf("Out of order packet received: current_packet=%d previous_packet=%d timestamp=%"PRId64"\n",eth->pck_seq_num_cur,eth->pck_seq_num_prev,*timestamp); //#endif } VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,eth->pck_seq_num_cur); @@ -448,7 +448,7 @@ int eth_set_dev_conf_udp(openair0_device *device) { if (sendto(eth->sockfd,msg,msg_len,0,(struct sockaddr *)ð->dest_addr,eth->addr_len)==-1) { perror("ETHERNET: sendto conf_udp"); - printf("addr_len : %d, msg_len %d\n",eth->addr_len,msg_len); + printf("addr_len : %d, msg_len %zd\n",eth->addr_len,msg_len); exit(0); } From 71fde414777c2dd1be3aed1e049756a2336a2a4a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:21:45 +0100 Subject: [PATCH 445/571] compilation warning removal --- targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c index 7278c2727d..4cf04064b1 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -418,7 +418,6 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { // Read nblocks info from packet itself - int nblocks = nsamps; int bytes_received=0; eth_state_t *eth = (eth_state_t*)device->priv; From d2098da06c6582df94305de6631fabf0d4aeeede Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:27:46 +0100 Subject: [PATCH 446/571] fix targets/COMMON/openairinterface5g_limits.h - LMSSDR was not handled - bad #if usage - bad indentation still not very clean, but better --- targets/COMMON/openairinterface5g_limits.h | 39 ++++++++++++---------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index d9590873e8..d5a3b7f61c 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -1,25 +1,30 @@ #ifndef OPENAIRINTERFACE5G_LIMITS_H_ #define OPENAIRINTERFACE5G_LIMITS_H_ -#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) - #define NUMBER_OF_eNB_MAX 1 - #define NUMBER_OF_UE_MAX 16 - #define NUMBER_OF_CONNECTED_eNB_MAX 3 +#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) +# define NUMBER_OF_eNB_MAX 1 +# define NUMBER_OF_UE_MAX 16 +# define NUMBER_OF_CONNECTED_eNB_MAX 3 #else - #define NUMBER_OF_eNB_MAX 7 - #define NUMBER_OF_UE_MAX 20 - #define NUMBER_OF_CONNECTED_eNB_MAX 3 +# define NUMBER_OF_eNB_MAX 7 +# define NUMBER_OF_UE_MAX 20 +# define NUMBER_OF_CONNECTED_eNB_MAX 3 - #if STANDALONE==1 - #define NUMBER_OF_eNB_MAX 3 - #define NUMBER_OF_UE_MAX 3 - #endif +# if defined(STANDALONE) && STANDALONE==1 +# undef NUMBER_OF_eNB_MAX +# undef NUMBER_OF_UE_MAX +# define NUMBER_OF_eNB_MAX 3 +# define NUMBER_OF_UE_MAX 3 +# endif - #if LARGE_SCALE - #define NUMBER_OF_eNB_MAX 2 - #define NUMBER_OF_UE_MAX 120 - #define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory - #endif +# if defined(LARGE_SCALE) && LARGE_SCALE +# undef NUMBER_OF_eNB_MAX +# undef NUMBER_OF_UE_MAX +# undef NUMBER_OF_CONNECTED_eNB_MAX +# define NUMBER_OF_eNB_MAX 2 +# define NUMBER_OF_UE_MAX 120 +# define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory +# endif #endif -#endif +#endif /* OPENAIRINTERFACE5G_LIMITS_H_ */ From ac437d3d126d901909ee7326c4366fc68d5747d6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:30:06 +0100 Subject: [PATCH 447/571] compilation warning removal --- openair1/SCHED/phy_procedures_lte_ue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 1d87ba0c41..e5ae3c8f38 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -3125,7 +3125,9 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs int subframe_rx = proc->subframe_rx; int frame_rx = proc->frame_rx; int pmch_mcs=-1; +#ifdef Rel10 int CC_id = ue->CC_id; +#endif uint8_t sync_area=255; uint8_t mcch_active; int l; From 6977429706a602176cfac565a43c8e32dcf08aaa Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:32:58 +0100 Subject: [PATCH 448/571] compilation warning removal --- targets/SIMU/USER/oaisim_functions.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index c00bb50401..297156b727 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -91,7 +91,9 @@ extern char smbv_ip[16]; #define K 2 // averaging coefficient #define TARGET_SF_TIME_NS 1000000 // 1ms = 1000000 ns +#ifndef min #define min(a,b) ((a)<(b)?(a):(b)) +#endif int otg_times = 0; int if_times = 0; From 99b521901ce98dff93618175d3dab4c06af6a282 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:33:09 +0100 Subject: [PATCH 449/571] compilation warning removal --- targets/SIMU/USER/oaisim_functions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 297156b727..039b34f5a0 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1016,8 +1016,8 @@ int eNB_trx_stop(openair0_device *device) { int UE_trx_start(openair0_device *device) { return(0); } -int UE_trx_end(openair0_device *device) { - return(0); +void UE_trx_end(openair0_device *device) { + return; } int UE_trx_stop(openair0_device *device) { return(0); From c01d9dc1f04d2f2516e00cb55f5b781d10e78c84 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:34:15 +0100 Subject: [PATCH 450/571] compilation warning removal --- targets/SIMU/USER/oaisim_functions.c | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 039b34f5a0..d022a1f644 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1449,6 +1449,7 @@ void init_openair1(void) } // CC_id } // UE_id + extern void init_UE(int); init_UE(NB_UE_INST); } From cfac326c001e411c7a0dab04be7d11ef01292c61 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:39:11 +0100 Subject: [PATCH 451/571] compilation warning removal --- targets/SIMU/USER/oaisim_functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index d022a1f644..a6fb6e10c4 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1295,7 +1295,7 @@ void init_devices(void){ void init_openair1(void) { - module_id_t UE_id, eNB_id; + module_id_t UE_id, eNB_id = 0; uint8_t CC_id; #if ENABLE_RAL int list_index; From b95ff08295ea6525a1432dbaf19ee9959022b496 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:40:11 +0100 Subject: [PATCH 452/571] compilation warning removal --- targets/SIMU/USER/oaisim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index f1b3944a16..f8a2dc9305 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -472,7 +472,7 @@ l2l1_task (void *args_p) // Framing variables int32_t sf; - char fname[64], vname[64]; + //char fname[64], vname[64]; //#ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) From 4a6e433b2116b25d3637c7d79f93da1624bd0523 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:41:10 +0100 Subject: [PATCH 453/571] compilation warning removal --- targets/SIMU/USER/oaisim.c | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index f8a2dc9305..343ed5475b 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1286,6 +1286,7 @@ main (int argc, char **argv) init_openair2 (); + void init_openair0(void); init_openair0(); init_ocm (); From e268611bec853019cde0f113dcd202dcdc0f6a12 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:45:17 +0100 Subject: [PATCH 454/571] bugfix --- targets/SIMU/USER/oaisim.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 343ed5475b..d18cb8259e 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1384,14 +1384,16 @@ reset_opp_meas_oaisim (void) for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) { reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc); - reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx); + reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0]); + reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[1]); reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_tx); reset_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_demod_stats); reset_meas (&PHY_vars_UE_g[UE_id][0]->rx_dft_stats); reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_channel_estimation_stats); reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_freq_offset_estimation_stats); - reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats); + reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats[0]); + reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats[1]); reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_rate_unmatching_stats); reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_turbo_decoding_stats); reset_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_deinterleaving_stats); @@ -1553,8 +1555,10 @@ print_opp_meas_oaisim (void) print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc, "[UE][total_phy_proc]", &oaisim_stats, &oaisim_stats_f); - print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx, - "[UE][total_phy_proc_rx]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0], + "[UE][total_phy_proc_rx[0]]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[1], + "[UE][total_phy_proc_rx[1]]", &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_demod_stats, "[UE][ofdm_demod]", &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->rx_dft_stats, "[UE][rx_dft]", @@ -1567,8 +1571,10 @@ print_opp_meas_oaisim (void) &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_unscrambling_stats, "[UE][unscrambling]", &oaisim_stats, &oaisim_stats_f); - print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats, - "[UE][decoding]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats[0], + "[UE][decoding[0]]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_decoding_stats[1], + "[UE][decoding[1]]", &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_rate_unmatching_stats, "[UE][rate_unmatching]", &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->dlsch_deinterleaving_stats, From e5c5185eda9054c145fef9266443b82e02195f3d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 12:47:00 +0100 Subject: [PATCH 455/571] compilation warning removal --- targets/SIMU/USER/oaisim.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index d18cb8259e..60221ac201 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1216,7 +1216,10 @@ main (int argc, char **argv) for(int i =0; i Date: Fri, 24 Mar 2017 13:02:42 +0100 Subject: [PATCH 456/571] bugfix: array too short for data 6 numbers (2 hexa digits each) separated by ':' plus ending 0 makes 18 bytes, not 6, let's put 20 --- targets/RT/USER/rrh_gw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/rrh_gw.c b/targets/RT/USER/rrh_gw.c index 4abdaa243d..595cf3a8ce 100644 --- a/targets/RT/USER/rrh_gw.c +++ b/targets/RT/USER/rrh_gw.c @@ -65,7 +65,7 @@ /* local IP/MAC address is detected*/ char rrh_ip[20] = "0.0.0.0"; -unsigned char rrh_mac[6] = "0:0:0:0:0:0"; +unsigned char rrh_mac[20] = "0:0:0:0:0:0"; int rrh_port = 50000; // has to be an option /* log */ From 34c303efb5e48068c30ee6615fcc2353d8b6413b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 13:05:08 +0100 Subject: [PATCH 457/571] compilation warning removal --- targets/RT/USER/rrh_gw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/rrh_gw.c b/targets/RT/USER/rrh_gw.c index 595cf3a8ce..f7b06fa7e2 100644 --- a/targets/RT/USER/rrh_gw.c +++ b/targets/RT/USER/rrh_gw.c @@ -197,7 +197,7 @@ static rrh_module_t new_module (unsigned int id) { openair0_cfg.my_port = rrh_port; LOG_I(RRH,"UDP mode selected for ethernet.\n"); } else if (eth_mode==ETH_RAW_MODE) { - openair0_cfg.my_addr = &rrh_mac[0]; + openair0_cfg.my_addr = (char*)&rrh_mac[0]; openair0_cfg.my_port = rrh_port; LOG_I(RRH,"RAW mode selected for ethernet.\n"); } From 89c60dacfdb29f1849a1424873665425b2186798 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 13:07:21 +0100 Subject: [PATCH 458/571] compilation warning removal --- targets/RT/USER/rrh_gw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/rrh_gw.c b/targets/RT/USER/rrh_gw.c index f7b06fa7e2..a73ed2466b 100644 --- a/targets/RT/USER/rrh_gw.c +++ b/targets/RT/USER/rrh_gw.c @@ -342,7 +342,7 @@ static int get_address(char* if_name, uint8_t flag) { perror("IOCTL:"); exit(-1); } - ether_ntoa_r ((unsigned char *)ifr.ifr_hwaddr.sa_data, rrh_mac); + ether_ntoa_r ((struct ether_addr *)ifr.ifr_hwaddr.sa_data, (char*)rrh_mac); LOG_I(RRH,"%s: MAC address: %s\n",if_name,rrh_mac); } From 7c7022a198eb509527c098e8d764d551cac0565a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 13:08:45 +0100 Subject: [PATCH 459/571] compilation warning removal --- targets/RT/USER/eNB_transport_IQ.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/eNB_transport_IQ.c b/targets/RT/USER/eNB_transport_IQ.c index fb351af6d6..c5ebc7548f 100644 --- a/targets/RT/USER/eNB_transport_IQ.c +++ b/targets/RT/USER/eNB_transport_IQ.c @@ -545,7 +545,7 @@ void *rrh_eNB_tx_thread(void *arg) { struct timespec time_req_1us, time_rem_1us; ssize_t bytes_received; int i; - openair0_timestamp last_hw_counter=0; + //openair0_timestamp last_hw_counter=0; unsigned int samples_per_frame=0,samples_per_subframe=0; unsigned int spp_rf=0, spp_eth=0; uint8_t loopback=0,measurements=0; @@ -634,7 +634,7 @@ void *rrh_eNB_tx_thread(void *arg) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_TS, timestamp_tx&0xffffffff ); - if (dev->devs->type == NONE_DEV) last_hw_counter=hw_counter; + //if (dev->devs->type == NONE_DEV) last_hw_counter=hw_counter; if (loopback ==1 ) { From 60efa62dc8cb6860c703d3d6a20df0f53137a48b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 13:09:35 +0100 Subject: [PATCH 460/571] compilation warning removal --- targets/RT/USER/eNB_transport_IQ.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/RT/USER/eNB_transport_IQ.c b/targets/RT/USER/eNB_transport_IQ.c index c5ebc7548f..b57a201fb5 100644 --- a/targets/RT/USER/eNB_transport_IQ.c +++ b/targets/RT/USER/eNB_transport_IQ.c @@ -539,7 +539,7 @@ void *rrh_eNB_rx_thread(void *arg) { void *rrh_eNB_tx_thread(void *arg) { - struct timespec time0a,time0,time1,time2; + struct timespec time0,time1,time2; rrh_module_t *dev = (rrh_module_t *)arg; struct timespec time_req_1us, time_rem_1us; From bc10722013fc762e6ecb32b4d719187cd5359463 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 14:20:06 +0100 Subject: [PATCH 461/571] warnings removal --- targets/RT/USER/UE_transport_IQ.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/targets/RT/USER/UE_transport_IQ.c b/targets/RT/USER/UE_transport_IQ.c index 8bbb78b4a3..7b56d6d6a8 100644 --- a/targets/RT/USER/UE_transport_IQ.c +++ b/targets/RT/USER/UE_transport_IQ.c @@ -87,7 +87,6 @@ void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag) { int i; int error_code_UE, error_code_proc_UE; - void *tmp; RT_flag_UE=RT_flag; NRT_flag_UE=NRT_flag; @@ -245,8 +244,7 @@ void *rrh_UE_thread(void *arg) { struct sched_param sched_param_UE_rx, sched_param_UE_tx; int16_t i,cmd; //,nsamps,antenna_index; - ssize_t bytes_received; - struct timespec time_req_1us, time_rem_1us; + //struct timespec time_req_1us; pthread_t UE_rx_thread, UE_tx_thread; pthread_attr_t attr_UE_rx, attr_UE_tx; int error_code_UE_rx, error_code_UE_tx; @@ -254,8 +252,8 @@ void *rrh_UE_thread(void *arg) { unsigned int samples_per_frame=0; samples_per_frame= dev->eth_dev.openair0_cfg->samples_per_frame; - time_req_1us.tv_sec = 0; - time_req_1us.tv_nsec = 1000; + //time_req_1us.tv_sec = 0; + //time_req_1us.tv_nsec = 1000; while (rrh_exit==0) { @@ -338,7 +336,7 @@ void *rrh_UE_rx_thread(void *arg) { int trace_cnt=0; unsigned long long max_rx_time=0, min_rx_time=133333, total_rx_time=0, average_rx_time=133333, s_period=0, trial=0; unsigned int samples_per_frame=0; - openair0_timestamp temp, last_hw_counter=0; + openair0_timestamp last_hw_counter=0; antenna_index = 0; nsamps = dev->eth_dev.openair0_cfg->samples_per_packet; @@ -446,7 +444,7 @@ void *rrh_UE_rx_thread(void *arg) { if (s_period++ == PRINTF_PERIOD) { s_period=0; - printf("Average UE RX time : %lu\tMax RX time : %lu\tMin RX time : %lu\n",average_rx_time,max_rx_time,min_rx_time); + printf("Average UE RX time : %llu\tMax RX time : %llu\tMin RX time : %llu\n",average_rx_time,max_rx_time,min_rx_time); } @@ -481,7 +479,6 @@ void *rrh_UE_tx_thread(void *arg) { rrh_module_t *dev = (rrh_module_t *)arg; ssize_t bytes_received; int antenna_index, nsamps; - int trace_cnt=0; unsigned int samples_per_frame=0; antenna_index = 0; @@ -504,7 +501,7 @@ void *rrh_UE_tx_thread(void *arg) { if (NRT_flag_UE==1) { nrt_UE_counter[antenna_index]++; } - printf(" first part size: %d second part size: %d idx=%d \n", + printf(" first part size: %d second part size: %"PRId64" idx=%"PRId64"\n", (int32_t)(((samples_per_frame)<<2)-((timestamp_UE_tx[antenna_index]%(samples_per_frame))<<2)), (nsamps<<2)-((samples_per_frame)<<2)+((timestamp_UE_tx[antenna_index]%(samples_per_frame))<<2), timestamp_UE_tx[antenna_index]%(samples_per_frame)); From 181eb532e10bc022d518e841300f3bc3d3260310 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 14:23:11 +0100 Subject: [PATCH 462/571] bugfix --- targets/RT/USER/rrh_gw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/rrh_gw.c b/targets/RT/USER/rrh_gw.c index a73ed2466b..e73c9ef4eb 100644 --- a/targets/RT/USER/rrh_gw.c +++ b/targets/RT/USER/rrh_gw.c @@ -376,7 +376,7 @@ void *timer_proc(void *arg) { timer_t timerid; struct itimerspec *timer= (struct itimerspec *)arg ; // the timer data structure - struct itimerspec *old_value; + struct itimerspec old_value; #ifdef DEADLINE_SCHEDULER @@ -407,7 +407,7 @@ void *timer_proc(void *arg) { signal(SIGALRM, timer_signal_handler); LOG_I(RRH,"Timer has started!\n"); - timer_settime (timerid, 0, timer, old_value); + timer_settime (timerid, 0, timer, &old_value); while (!rrh_exit) { sleep(1); From dfcbeff0d456e17ba320998f8abd73e8aa4be2dc Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 14:26:16 +0100 Subject: [PATCH 463/571] bugfix/warning removal not sure of this one, to be checked --- targets/RT/USER/UE_transport_IQ.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/targets/RT/USER/UE_transport_IQ.c b/targets/RT/USER/UE_transport_IQ.c index 7b56d6d6a8..05dd2bbf79 100644 --- a/targets/RT/USER/UE_transport_IQ.c +++ b/targets/RT/USER/UE_transport_IQ.c @@ -342,6 +342,9 @@ void *rrh_UE_rx_thread(void *arg) { nsamps = dev->eth_dev.openair0_cfg->samples_per_packet; samples_per_frame = dev->eth_dev.openair0_cfg->samples_per_frame; + /* TODO: check if setting time0 has to be done here */ + clock_gettime(CLOCK_MONOTONIC,&time0); + while (rrh_exit == 0) { if (!UE_rx_started) { UE_rx_started=1; //Set this flag to 1 to indicate that a UE started retrieving data From 676ca5c3a094723eb5ea7667d242155651c91ddf Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 14:40:00 +0100 Subject: [PATCH 464/571] compilation warning removal --- targets/ARCH/EXMIMO/DRIVER/eurecom/exmimo_fw.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/targets/ARCH/EXMIMO/DRIVER/eurecom/exmimo_fw.c b/targets/ARCH/EXMIMO/DRIVER/eurecom/exmimo_fw.c index 993b2db2ee..766bb6eb74 100644 --- a/targets/ARCH/EXMIMO/DRIVER/eurecom/exmimo_fw.c +++ b/targets/ARCH/EXMIMO/DRIVER/eurecom/exmimo_fw.c @@ -193,7 +193,7 @@ int exmimo_assign_shm_vars(int card_id) int exmimo_allocate_rx_tx_buffers(int card_id) { size_t size; - int j,i; + int j; dma_addr_t dma_addr_dummy; // Round up to the next PAGE_SIZE (typ. 4096 bytes) size = (ADAC_BUFFERSZ_PERCHAN_B >> PAGE_SHIFT) + 1; @@ -243,8 +243,6 @@ int exmimo_allocate_rx_tx_buffers(int card_id) */ int exmimo_memory_alloc(int card) { - int i; - if ( bigshm_init( card ) ) { printk("exmimo_memory_alloc(): bigshm_init failed for card %d.\n", card); return -ENOMEM; From 7a6709a24e05e03c849948d0039bd06055099136 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:12:52 +0100 Subject: [PATCH 465/571] warning removal/bug fixes/adding logs in rb_tool.c --- .../NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c b/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c index 5222a4a4b8..24b47fa5db 100644 --- a/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c +++ b/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c @@ -36,7 +36,8 @@ #include #include #include - +#include +#include #include #include @@ -109,7 +110,7 @@ void IAL_NAS_ioctl_init(int inst) { struct nas_msg_statistic_reply *msgrep; - int err,rc; + int err; sprintf(gifr.name, "oai%d",inst); @@ -132,7 +133,6 @@ void IAL_NAS_ioctl_init(int inst) if (err<0) { printf("IOCTL error, err=%d\n",err); - rc = -1; } printf("tx_packets = %u, rx_packets = %u\n", msgrep->tx_packets, msgrep->rx_packets); @@ -151,16 +151,10 @@ void IAL_NAS_ioctl_init(int inst) int main(int argc,char **argv) //--------------------------------------------------------------------------- { - int done = 0, rc = 0, meas_polling_counter = 0; - fd_set readfds; - struct timeval tv; - int i = 0; int err = 0; - char * buffer; int c = 0; int action=0,rbset=0,cxset=0,instset=0,saddr_ipv4set=0,saddr_ipv6set=0,daddr_ipv4set=0,daddr_ipv6set=0,dscpset=0,mpls_outlabelset=0,mpls_inlabelset=0; char rb[100],cx[100],dscp[100],inst[100],mpls_outgoinglabel[100],mpls_incominglabel[100]; - int index = 0; struct nas_msg_rb_establishment_request *msgreq = NULL; struct nas_msg_class_add_request *msgreq_class = NULL; in_addr_t saddr_ipv4,daddr_ipv4; @@ -213,15 +207,21 @@ int main(int argc,char **argv) mpls_inlabelset=1; break; - case 's': - inet_aton(optarg,&saddr_ipv4); + case 's': { + struct in_addr a; + inet_aton(optarg,&a); + saddr_ipv4 = a.s_addr; saddr_ipv4set = 1; break; + } - case 't': - inet_aton(optarg,&daddr_ipv4); + case 't': { + struct in_addr a; + inet_aton(optarg,&a); + daddr_ipv4 = a.s_addr; daddr_ipv4set = 1; break; + } case 'x': printf("IPv6: %s\n",optarg); @@ -303,7 +303,7 @@ int main(int argc,char **argv) if (action == ADD_RB) { gifr.type = NAS_MSG_RB_ESTABLISHMENT_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); - + if (err == -1) perror("ioctl"); if (saddr_ipv4set == 1) { @@ -329,6 +329,7 @@ int main(int argc,char **argv) gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); @@ -340,6 +341,7 @@ int main(int argc,char **argv) msgreq_class->saddr.ipv4 = daddr_ipv4; gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); } if (saddr_ipv6set == 1) { @@ -370,6 +372,7 @@ int main(int argc,char **argv) gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); @@ -380,6 +383,7 @@ int main(int argc,char **argv) memcpy(&msgreq_class->saddr.ipv6,&daddr_ipv6,16); gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); } @@ -411,6 +415,7 @@ int main(int argc,char **argv) gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); @@ -430,12 +435,14 @@ int main(int argc,char **argv) gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); } } else if (action == DEL_RB) { gifr.type = NAS_MSG_RB_RELEASE_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); } From f754e31ead64b5d7a958f424ea52637162902f2e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:17:13 +0100 Subject: [PATCH 466/571] compilation warnings removal --- openair2/NETWORK_DRIVER/MESH/common.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c index 6d10abd380..95e4cf1fc2 100644 --- a/openair2/NETWORK_DRIVER/MESH/common.c +++ b/openair2/NETWORK_DRIVER/MESH/common.c @@ -59,14 +59,14 @@ void nas_COMMON_receive(uint16_t dlen, struct nas_priv *gpriv=netdev_priv(nasdev[inst]); uint32_t odaddr,osaddr; - int i; + //int i; unsigned char protocol; - unsigned char *addr,*daddr,*saddr,*ifaddr,sn; + unsigned char /**addr,*/ *daddr,*saddr,*ifaddr /*,sn*/; - struct udphdr *uh; - struct tcphdr *th; + //struct udphdr *uh; + //struct tcphdr *th; uint16_t *cksum,check; struct iphdr *network_header; @@ -340,7 +340,7 @@ void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct class int i; #endif unsigned int bytes_wrote; - unsigned char j; + //unsigned char j; // Start debug information #ifdef NAS_DEBUG_SEND printk("NAS_COMMON_QOS_SEND - inst %d begin \n",inst); @@ -595,7 +595,7 @@ struct rb_entity *nas_COMMON_search_rb(struct cx_entity *cx, nasRadioBearerId_t struct classifier_entity *nas_COMMON_search_class_for_rb(nasRadioBearerId_t rab_id,struct nas_priv *priv) { - struct rb_entity *rb; + //struct rb_entity *rb; int dscp; struct classifier_entity *rclass; From 4080a63938ad1c75e7f1e37f85ab98aaef9f5a81 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:18:49 +0100 Subject: [PATCH 467/571] compilation warning removal --- openair2/NETWORK_DRIVER/MESH/ioctl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair2/NETWORK_DRIVER/MESH/ioctl.c b/openair2/NETWORK_DRIVER/MESH/ioctl.c index 4045908d93..913fcc1e75 100644 --- a/openair2/NETWORK_DRIVER/MESH/ioctl.c +++ b/openair2/NETWORK_DRIVER/MESH/ioctl.c @@ -739,7 +739,6 @@ void nas_set_msg_imei_reply(struct nas_msg_l2id_reply *msgrep, //--------------------------------------------------------------------------- struct cx_entity *cx; int lcr=0; // Temp lcr->mt =0 - int i; cx=nas_COMMON_search_cx(lcr,priv); From 045132ba6e6695bd4c00f944a13e99448b36add6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:20:56 +0100 Subject: [PATCH 468/571] compilation warning removal --- openair2/NETWORK_DRIVER/MESH/classifier.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/NETWORK_DRIVER/MESH/classifier.c b/openair2/NETWORK_DRIVER/MESH/classifier.c index d477ba3ea9..f47d63008c 100644 --- a/openair2/NETWORK_DRIVER/MESH/classifier.c +++ b/openair2/NETWORK_DRIVER/MESH/classifier.c @@ -605,12 +605,12 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) //--------------------------------------------------------------------------- struct classifier_entity *p, *sp; uint8_t *protocolh,version; - uint8_t protocol, dscp, exp,label; + uint8_t protocol, dscp /*, exp,label*/ ; uint16_t classref; struct cx_entity *cx; - unsigned int i; + //unsigned int i; - unsigned int router_adv = 0; + //unsigned int router_adv = 0; struct net_device *dev=nasdev[inst]; struct nas_priv *gpriv=netdev_priv(dev); From 5345b160fcb2c37ed3ded98085c2af62ad4cac10 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:23:43 +0100 Subject: [PATCH 469/571] compilation warning removal --- openair2/NETWORK_DRIVER/MESH/mesh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/NETWORK_DRIVER/MESH/mesh.c b/openair2/NETWORK_DRIVER/MESH/mesh.c index 9817428c5e..e2cf3bcf0a 100644 --- a/openair2/NETWORK_DRIVER/MESH/mesh.c +++ b/openair2/NETWORK_DRIVER/MESH/mesh.c @@ -387,7 +387,7 @@ void nas_mesh_DC_send_sig_data_request(struct sk_buff *skb, { //--------------------------------------------------------------------------- struct nas_ue_dc_element *p; - char data_type = 'A'; + //char data_type = 'A'; int bytes_wrote=0; // Start debug information @@ -466,7 +466,7 @@ void nas_mesh_DC_send_peer_sig_data_request(struct cx_entity *cx, uint8_t sig_ca struct nas_ue_dc_element *p; uint8_t nas_data[10]; unsigned int nas_length; - char data_type = 'Z'; + //char data_type = 'Z'; int bytes_wrote=0; // Start debug information From d296abb8d0214948d373174bf20699d8c36c868b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:24:35 +0100 Subject: [PATCH 470/571] compilation warning removal --- openair2/NETWORK_DRIVER/MESH/netlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/NETWORK_DRIVER/MESH/netlink.c b/openair2/NETWORK_DRIVER/MESH/netlink.c index 3ce6cf6ebe..8d40a9d965 100644 --- a/openair2/NETWORK_DRIVER/MESH/netlink.c +++ b/openair2/NETWORK_DRIVER/MESH/netlink.c @@ -50,7 +50,7 @@ static struct sock *nas_nl_sk = NULL; static int exit_netlink_thread=0; -static int nas_netlink_rx_thread(void *); +//static int nas_netlink_rx_thread(void *); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) struct netlink_kernel_cfg oai_netlink_cfg; #endif @@ -76,7 +76,7 @@ static void nas_nl_data_ready (struct sk_buff *skb) //nasmesh_unlock(); struct nlmsghdr *nlh = NULL; - int j; + //int j; if (skb) { From 53bb6a8c2c8b4fe6d71fbd259baa9eda4a2c99a1 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:33:51 +0100 Subject: [PATCH 471/571] compilation warning removal --- openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c b/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c index 24b47fa5db..24dfcaf61e 100644 --- a/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c +++ b/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c @@ -157,7 +157,7 @@ int main(int argc,char **argv) char rb[100],cx[100],dscp[100],inst[100],mpls_outgoinglabel[100],mpls_incominglabel[100]; struct nas_msg_rb_establishment_request *msgreq = NULL; struct nas_msg_class_add_request *msgreq_class = NULL; - in_addr_t saddr_ipv4,daddr_ipv4; + in_addr_t saddr_ipv4 = 0,daddr_ipv4 = 0; struct in6_addr saddr_ipv6,daddr_ipv6; unsigned int mpls_outlabel=0,mpls_inlabel=0; From 583123e042d380011f35f1f7e6773d4a9f5b4c60 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:49:19 +0100 Subject: [PATCH 472/571] bugfix/compilation warning removal in dlsim --- openair1/SIMULATION/LTE_PHY/dlsim.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 6acfc646c7..aa8e9360ea 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -270,7 +270,7 @@ void fill_DCI(PHY_VARS_eNB *eNB, int *num_dci) { int k; - int dci_length,dci_length_bytes; + int dci_length = -1,dci_length_bytes = -1; // printf("Generating DCIs for %d users, TM %d, mcs1 %d\n",n_users,transmission_mode,mcs1); for(k=0; kte = dlsch_encoding_2threads; + extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); + extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *); init_td_thread(eNB,NULL); init_te_thread(eNB,NULL); } @@ -2186,6 +2189,7 @@ int main(int argc, char **argv) while ((!feof(input_trch_fd)) && (i>3]+=(1<<(7-(i&7))); From 6448738e9b31eada3f843d3dd6aa38e70c54b32a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 15:53:52 +0100 Subject: [PATCH 473/571] bugfix/compilation warning removal in ulsim --- openair1/SIMULATION/LTE_PHY/ulsim.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 3564f597ef..e23e247006 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -163,8 +163,8 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mc } -extern void eNB_fep_full(PHY_VARS_eNB *eNB); -extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB); +extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); int main(int argc, char **argv) { @@ -196,7 +196,7 @@ int main(int argc, char **argv) int chMod = 0 ; int UE_id = 0; unsigned char nb_rb=25,first_rb=0,mcs=0,round=0,bundling_flag=1; - unsigned char l; + //unsigned char l; unsigned char awgn_flag = 0 ; SCM_t channel_model=Rice1; @@ -245,7 +245,7 @@ int main(int argc, char **argv) int hold_channel=0; channel_desc_t *UE2eNB; - uint8_t control_only_flag = 0; + //uint8_t control_only_flag = 0; int delay = 0; double maxDoppler = 0.0; uint8_t srs_flag = 0; @@ -677,6 +677,8 @@ int main(int argc, char **argv) UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); if (parallel_flag == 1) { + extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); + extern void init_td_thread(PHY_VARS_eNB *, pthread_attr_t *); init_fep_thread(eNB,NULL); init_td_thread(eNB,NULL); } @@ -843,6 +845,7 @@ int main(int argc, char **argv) while (!feof(input_fdUL)) { ret=fscanf(input_fdUL,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2); + if (ret != 2) printf("ERROR: error reading file\n"); if ((i%4)==0) { ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); From b5a03474bf82f40c70adeffe1c63d28017440078 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 16:46:42 +0100 Subject: [PATCH 474/571] remove asn1 compilation fixes that went to asn1c (IMPORTANT: reinstall asn1c!) The files NativeInteger.c.diff and constr_SET_OF.c.diff from asn1c were generating compilation warnings. We had local patches applied on generated files by asn1c. A new version of asn1c has been pushed to https://gitlab.eurecom.fr/oai/asn1c (commit 224dc1f991b7e7ad705ce92e171b942f87b7b7e7) making obsolete the fixes we do here. So we now remove those fixes. ************************* * IMPORTANT BEGIN * ************************* Everyone should update their asn1c installation. The simplest is to do: source oaienv cd cmake_targets ./build_oai -I ************************* * IMPORTANT END * ************************* --- cmake_targets/tools/fix_asn1 | 10 +--------- .../fix_asn1.data/S1AP.rel10.5/NativeInteger.c.diff | 8 -------- .../fix_asn1.data/S1AP.rel10.5/constr_SET_OF.c.diff | 4 ---- .../fix_asn1.data/X2AP.rel11.2/NativeInteger.c.diff | 8 -------- .../fix_asn1.data/X2AP.rel11.2/constr_SET_OF.c.diff | 4 ---- 5 files changed, 1 insertion(+), 33 deletions(-) delete mode 100644 cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/NativeInteger.c.diff delete mode 100644 cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/constr_SET_OF.c.diff delete mode 100644 cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/NativeInteger.c.diff delete mode 100644 cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/constr_SET_OF.c.diff diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1 index 0661d7878d..6d55e1e9bc 100755 --- a/cmake_targets/tools/fix_asn1 +++ b/cmake_targets/tools/fix_asn1 @@ -9,13 +9,6 @@ RRC_Rel10=( X2AP_Rel11_2=( "X2ap-CriticalityDiagnostics-IE-List.h" ae96308b37fcbcbf39da5012e42968135fc5f27b "fix_asn1.data/X2AP.rel11.2/X2ap-CriticalityDiagnostics-IE-List.h.diff" - "NativeInteger.c" 1a55f5402fd363318cf5444ffe1f67530dcf66ff "fix_asn1.data/X2AP.rel11.2/NativeInteger.c.diff" - "constr_SET_OF.c" 808cbbdf19b118c0bdb04e3acf2cbe6e4133be2b "fix_asn1.data/X2AP.rel11.2/constr_SET_OF.c.diff" -) - -S1AP_Rel10_5=( - "NativeInteger.c" 1a55f5402fd363318cf5444ffe1f67530dcf66ff "fix_asn1.data/S1AP.rel10.5/NativeInteger.c.diff" - "constr_SET_OF.c" 808cbbdf19b118c0bdb04e3acf2cbe6e4133be2b "fix_asn1.data/S1AP.rel10.5/constr_SET_OF.c.diff" ) red_color="$(tput setaf 1)" @@ -130,8 +123,7 @@ function patch_s1ap() case "$version" in R10 ) - echo "patching S1AP files release 10.5" - apply_patches "$directory" S1AP_Rel10_5 ${#S1AP_Rel10_5[*]} + #nothing to do anymore (fixes went to asn1c) ;; * ) error unknwon/unhandled S1AP version \'"$version"\' diff --git a/cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/NativeInteger.c.diff b/cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/NativeInteger.c.diff deleted file mode 100644 index 3b51426ad3..0000000000 --- a/cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/NativeInteger.c.diff +++ /dev/null @@ -1,8 +0,0 @@ -283c283 -< int dynamic = 0; ---- -> //int dynamic = 0; -290c290 -< dynamic = 1; ---- -> //dynamic = 1; diff --git a/cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/constr_SET_OF.c.diff b/cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/constr_SET_OF.c.diff deleted file mode 100644 index 3ceaf5e3e5..0000000000 --- a/cmake_targets/tools/fix_asn1.data/S1AP.rel10.5/constr_SET_OF.c.diff +++ /dev/null @@ -1,4 +0,0 @@ -1007c1007 -< (int)nelems, (int)ct ? ct->effective_bits : -1); ---- -> (int)nelems, ct ? ct->effective_bits : -1); diff --git a/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/NativeInteger.c.diff b/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/NativeInteger.c.diff deleted file mode 100644 index 3b51426ad3..0000000000 --- a/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/NativeInteger.c.diff +++ /dev/null @@ -1,8 +0,0 @@ -283c283 -< int dynamic = 0; ---- -> //int dynamic = 0; -290c290 -< dynamic = 1; ---- -> //dynamic = 1; diff --git a/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/constr_SET_OF.c.diff b/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/constr_SET_OF.c.diff deleted file mode 100644 index 3ceaf5e3e5..0000000000 --- a/cmake_targets/tools/fix_asn1.data/X2AP.rel11.2/constr_SET_OF.c.diff +++ /dev/null @@ -1,4 +0,0 @@ -1007c1007 -< (int)nelems, (int)ct ? ct->effective_bits : -1); ---- -> (int)nelems, ct ? ct->effective_bits : -1); From 5db0548af0e913ace01370879f7d6569656ef411 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 16:55:30 +0100 Subject: [PATCH 475/571] bugfix --- openair1/SCHED/phy_mac_stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c index 9a41ae09c5..04a98f69c1 100644 --- a/openair1/SCHED/phy_mac_stub.c +++ b/openair1/SCHED/phy_mac_stub.c @@ -531,7 +531,7 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) } } else { - switch (eNB->frame_parms.N_RB_DL==6) { + switch (eNB->frame_parms.N_RB_DL) { case 6: ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0; ((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0; From 4e3acb6a5dab290853f9e17dece356ea5ac66b32 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 17:18:51 +0100 Subject: [PATCH 476/571] integration fix: disable XER_PRINT This generates too much prints and may disrupt realtime. This has to be off by default. --- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 7c6fbc6894..c5cfbdd2dc 100644 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -99,7 +99,7 @@ int errno; # endif #endif -#define XER_PRINT +//#define XER_PRINT extern Enb_properties_array_t enb_properties; typedef struct xer_sprint_string_s { From af8ce457f3e534eb586ba976a31e87b11d9635b5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 18:01:39 +0100 Subject: [PATCH 477/571] bugfix: fix nos1 compilation --- cmake_targets/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0bfc8b2d13..94a88c095b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1808,6 +1808,7 @@ add_executable(lte-softmodem-nos1 ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR_DIR}/common/utils/system.c ${HW_SOURCE} ${TRANSPORT_SOURCE} ${RTAI_SOURCE} @@ -1950,6 +1951,7 @@ add_executable(oaisim_nos1 ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c + ${OPENAIR_DIR}/common/utils/system.c ${HW_SOURCE} ${TRANSPORT_SOURCE} ${XFORMS_SOURCE} From 5485f131c37ab81417a1f7855fd0925d56ce50bf Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 24 Mar 2017 18:05:11 +0100 Subject: [PATCH 478/571] bugfix: Rel14 was missing --- openair1/SCHED/phy_procedures_lte_ue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 317b098b50..776de2335d 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -2997,7 +2997,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs int subframe_rx = proc->subframe_rx; int frame_rx = proc->frame_rx; int pmch_mcs=-1; -#ifdef Rel10 +#if defined(Rel10) || defined(Rel14) int CC_id = ue->CC_id; #endif uint8_t sync_area=255; From b6991ab2e0b241f6c768d465e01e2a292d5f0542 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 27 Mar 2017 10:19:23 +0200 Subject: [PATCH 479/571] autotest v2: remove nasmesh and ue_ip module kernels before anything else The presence of one or the other may lead to some failure/crash in some situations. --- cmake_targets/autotests/v2/actions/alu_hss.bash | 2 ++ cmake_targets/autotests/v2/actions/execution_compile.bash | 2 ++ cmake_targets/autotests/v2/actions/run_enb.bash | 2 ++ cmake_targets/autotests/v2/actions/start_3276.bash | 2 ++ cmake_targets/autotests/v2/actions/start_bandrich.bash | 2 ++ 5 files changed, 10 insertions(+) diff --git a/cmake_targets/autotests/v2/actions/alu_hss.bash b/cmake_targets/autotests/v2/actions/alu_hss.bash index ded1e352ce..be32fe9eb0 100644 --- a/cmake_targets/autotests/v2/actions/alu_hss.bash +++ b/cmake_targets/autotests/v2/actions/alu_hss.bash @@ -1,2 +1,4 @@ +sudo rmmod nasmesh || true +sudo rmmod ue_ip || true sudo /opt/ltebox/tools/stop_ltebox || true sudo /opt/hss_sim0609/starthss_real diff --git a/cmake_targets/autotests/v2/actions/execution_compile.bash b/cmake_targets/autotests/v2/actions/execution_compile.bash index 530447ebcd..149ebdff85 100644 --- a/cmake_targets/autotests/v2/actions/execution_compile.bash +++ b/cmake_targets/autotests/v2/actions/execution_compile.bash @@ -1,5 +1,7 @@ cd /tmp/oai_test_setup/oai source oaienv +sudo rmmod nasmesh || true +sudo rmmod ue_ip || true cd cmake_targets rm -rf log mkdir -p log diff --git a/cmake_targets/autotests/v2/actions/run_enb.bash b/cmake_targets/autotests/v2/actions/run_enb.bash index 1a4c5368a7..abf7dc0286 100644 --- a/cmake_targets/autotests/v2/actions/run_enb.bash +++ b/cmake_targets/autotests/v2/actions/run_enb.bash @@ -3,6 +3,8 @@ stty isig intr ^C cd /tmp/oai_test_setup/oai source oaienv +sudo rmmod nasmesh || true +sudo rmmod ue_ip || true cd cmake_targets/lte_build_oai/build ulimit -c unlimited sudo rm -f core diff --git a/cmake_targets/autotests/v2/actions/start_3276.bash b/cmake_targets/autotests/v2/actions/start_3276.bash index c6fbdcedd9..380c914d47 100644 --- a/cmake_targets/autotests/v2/actions/start_3276.bash +++ b/cmake_targets/autotests/v2/actions/start_3276.bash @@ -3,6 +3,8 @@ stty isig intr ^C cd /tmp/oai_test_setup/oai source oaienv +sudo rmmod nasmesh || true +sudo rmmod ue_ip || true cd cmake_targets/autotests/v2/actions sudo python start_3276.py diff --git a/cmake_targets/autotests/v2/actions/start_bandrich.bash b/cmake_targets/autotests/v2/actions/start_bandrich.bash index e562dfc29b..7620e89784 100644 --- a/cmake_targets/autotests/v2/actions/start_bandrich.bash +++ b/cmake_targets/autotests/v2/actions/start_bandrich.bash @@ -16,6 +16,8 @@ stty isig intr ^C cd /tmp/oai_test_setup/oai source oaienv +sudo rmmod nasmesh || true +sudo rmmod ue_ip || true cd cmake_targets/autotests/v2/actions python start_bandrich.py From fa0b8668fb49f1577f5bea990b04a95e1b9d9124 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 27 Mar 2017 16:27:56 +0200 Subject: [PATCH 480/571] bugfix: workaround a problem with timestamp and LMSSDR. We have a strange problem with the timestamp of the very first packets received from the LimeSDR that leads to a complete failure of the eNB. A simple workaround is to discard the first RX packet just after a "start" of the device. We also change the value of "tx_sample_advance" to a more reasonable value. The problem of timestamp was "solved" differently in the past and at the time we needed to put a much higher value. This may have to be refined at some point. --- targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index f2d2af55c7..2dec4ff22d 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -45,6 +45,14 @@ lms_device_t* lms_device; lms_stream_t rx_stream; lms_stream_t tx_stream; +/* We have a strange behavior when we just start reading + * from the device (inconsistent values of the timestamp). + * A quick solution is to discard the very first read packet + * after a "start". + * The following global variable "first_rx" serves that purpose. + */ +static int first_rx = 0; + #define RXDCLENGTH 4096 #define NUMBUFF 32 @@ -94,6 +102,10 @@ int trx_lms_read(openair0_device *device, openair0_timestamp *ptimestamp, void * meta.flushPartialPacket = false; int ret; + if (first_rx == 1) { + first_rx = 0; + ret = LMS_RecvStream(&rx_stream,buff[0],nsamps,&meta,50); + } ret = LMS_RecvStream(&rx_stream,buff[0],nsamps,&meta,50); *ptimestamp = meta.timestamp; return ret; @@ -223,6 +235,8 @@ int trx_lms_start(openair0_device *device){ } + first_rx = 1; + rx_stream.channel = 0; rx_stream.fifoSize = 256*1024; rx_stream.throughputVsLatency = 0.1; @@ -355,7 +369,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg){ break; case 15360000: openair0_cfg[0].samples_per_packet = 2048; - openair0_cfg[0].tx_sample_advance = 450; + openair0_cfg[0].tx_sample_advance = 50; /* TODO: to be refined */ openair0_cfg[0].tx_bw = 15.36e6; openair0_cfg[0].rx_bw = 15.36e6; break; From 5dfdec6c259d1c7cca4ba319cf7da072025bd04f Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:11:43 +0800 Subject: [PATCH 481/571] #219 add minimum support for running and building UE and eNB --- cmake_targets/build_ue | 5 +++++ cmake_targets/tools/build_helper | 8 +++++++- cmake_targets/tools/init_nas_s1 | 8 ++++---- cmake_targets/tools/run_ue_s1 | 33 ++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 cmake_targets/build_ue create mode 100644 cmake_targets/tools/run_ue_s1 diff --git a/cmake_targets/build_ue b/cmake_targets/build_ue new file mode 100644 index 0000000000..76b1c96315 --- /dev/null +++ b/cmake_targets/build_ue @@ -0,0 +1,5 @@ +#!/bin/bash +#sudo ./build_oai -c -C -I --install-optional-packages --install-system-files --UE -w USRP -V +#sudo ./build_oai -c -C -I --install-optional-packages --UE -w USRP -V +#sudo ./build_oai -c -C --UE -w USRP -V +sudo ./build_oai -c -C --UE -w USRP diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index ede8ef4196..e3bd2e0782 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -164,7 +164,13 @@ compilations() { } > $dlog/$2.$REL.txt 2>&1 set -e echo_info "Log file for compilation has been written to: $dlog/$2.$REL.txt" - if [ -s $3 ] ; then + +echo "#!/bash/bin" > domake_$2.sh + echo "$SUDO make -j`nproc` $2" >> domake_$2.sh + echo "$SUDO cp $3 $4" >> domake_$2.sh + chmod 775 domake_$2.sh + +if [ -s $3 ] ; then cp $3 $4 echo_success "$2 compiled" check_warnings "$dlog/$2.$REL.txt" diff --git a/cmake_targets/tools/init_nas_s1 b/cmake_targets/tools/init_nas_s1 index 5f27c52837..003a3ae600 100644 --- a/cmake_targets/tools/init_nas_s1 +++ b/cmake_targets/tools/init_nas_s1 @@ -33,7 +33,7 @@ # ####################################### -LTEIF=oip0 +LTEIF=oip1 #OPENAIR_DIR=/home/oai/svn-oai/openair4G load_module() { @@ -48,11 +48,11 @@ load_module() { sudo insmod $1 } -load_module $OPENAIR_DIR/targets/bin/ue_ip.ko +load_module ../../targets/bin/ue_ip.ko if [ "$1" = "UE" ]; then - echo "bring up oip0 interface for UE" - ifconfig oip0 up + echo "bring up $LTEIF interface for UE" + ifconfig $LTEIF up fi ip route flush cache diff --git a/cmake_targets/tools/run_ue_s1 b/cmake_targets/tools/run_ue_s1 new file mode 100644 index 0000000000..56b18d72b9 --- /dev/null +++ b/cmake_targets/tools/run_ue_s1 @@ -0,0 +1,33 @@ +#!/bin/bash + +# Carrier frequency in Hz +#FREQ=2660000000 #FDD +FREQ=2350000000 #TDD +NRB=50 +TA=0 + +#9:trace, 8/7:debug, 6:info, 4:warn, 3:error +LOGLEVEL=6 + +#enable or disable soft scope +#SCOPE='' +SCOPE='-d' + +#enable or disable VCD logging +VCD='' +#VCD='-V' + +ISTDD='-T' +#ISTDD='' + +#use external clock +ECLK="--external-clock" +#ECLK="" + +#UE scan carrier +#ISSCAN="--ue-scan-carrier" +ISSCAN="" + +sudo sh -c './init_nas_s1 UE' +cd ../../targets/bin/ +sudo -E ./lte-softmodem.Rel10 -U -C$FREQ -r$NRB $ISSCAN --ue-txgain 70 --ue-rxgain 80 -A $TA $ECLK -W $ISTDD -g $LOGLEVEL $SCOPE 2>&1 | sudo tee /tmp/UE.log From e6798f5b9638c8e75e0bc426d4bceb372e49da77 Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:11:43 +0800 Subject: [PATCH 482/571] #219 add build option for building eclipse project files --- cmake_targets/build_oai | 33 +++++++++++++++++++++++---------- cmake_targets/build_ue | 1 + 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 119c013832..4f9b154700 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -55,6 +55,8 @@ T_TRACER="False" DISABLE_HARDWARE_DEPENDENCY="False" CMAKE_BUILD_TYPE="" UE_AUTOTEST_TRACE="False" +BUILD_ECLIPSE=0 +CMAKE_CMD='cmake' trap handle_ctrl_c INT gen_nvram_path=$OPENAIR_DIR/targets/bin @@ -141,6 +143,8 @@ Options Disable HW dependency during installation --ue-autotest-trace Enable specific traces for UE autotest framework +--build-eclipse + Build eclipse project files. Paths are auto corrected by fixprj.sh Usage (first build): oaisim (eNB + UE): ./build_oai -I --oaisim -x --install-system-files Eurecom EXMIMO + COTS UE : ./build_oai -I --eNB -x --install-system-files @@ -179,6 +183,7 @@ function main() { GDB=1 CMAKE_BUILD_TYPE="Debug" echo_info "Will Compile with gdb symbols and disable compiler optimization" + CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=Debug" shift;; --eNB) eNB=1 @@ -311,6 +316,11 @@ function main() { UHD_IMAGES_DIR=$2 echo_info "Downloading UHD images in the indicated location" shift 2;; + --build-eclipse) + BUILD_ECLIPSE=1 + CMAKE_CMD="$CMAKE_CMD"' -DCMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT=TRUE -G"Eclipse CDT4 - Unix Makefiles"' + echo_info "Enabling build eclipse project support" + shift 1;; -h | --help) print_help exit 1;; @@ -321,6 +331,9 @@ function main() { esac done + CMAKE_CMD="$CMAKE_CMD .." + echo_info "CMAKE_CMD=$CMAKE_CMD" + ######################################################### # check validity of HW and TP parameters for RRH and eNB ######################################################### @@ -495,7 +508,7 @@ function main() { fi echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$lte_build_dir/build - cmake .. + eval $CMAKE_CMD fi if [ "$eNB" = "1" -o "$UE" = "1" ] ; then @@ -524,7 +537,7 @@ function main() { # mkdir -p $DIR/at_commands/build # cd $DIR/at_commands/build -# cmake .. +# eval $CMAKE_CMD # compilations \ # at_commands at_nas_ue \ # at_nas_ue $dbin/at_nas_ue @@ -533,7 +546,7 @@ function main() { mkdir -p $DIR/nas_sim_tools/build cd $DIR/nas_sim_tools/build - cmake .. + eval $CMAKE_CMD compilations \ nas_sim_tools usim \ usim $dbin/usim @@ -562,7 +575,7 @@ function main() { mkdir -p build cd build rm -f *sim - cmake .. + eval $CMAKE_CMD fi if [ "$SIMUS_PHY" = "1" ] ; then @@ -640,7 +653,7 @@ function main() { [ "$CLEAN" = "1" ] && rm -rf $DIR/$oaisim_build_dir/build mkdir -p $DIR/$oaisim_build_dir/build cd $DIR/$oaisim_build_dir/build - cmake .. + eval $CMAKE_CMD compilations \ $oaisim_build_dir $oaisim_exec \ $oaisim_exec $dbin/$oaisim_exec.$REL @@ -651,7 +664,7 @@ function main() { echo_info "Compiling at_nas_ue" mkdir -p $DIR/at_commands/build cd $DIR/at_commands/build - cmake .. + eval $CMAKE_CMD compilations \ at_commands at_nas_ue \ at_nas_ue $dbin/at_nas_ue @@ -665,7 +678,7 @@ function main() { [ "$CLEAN" = "1" ] && rm -rf $DIR/nas_sim_tools/build mkdir -p $DIR/nas_sim_tools/build cd $DIR/nas_sim_tools/build - cmake .. + eval $CMAKE_CMD compilations \ nas_sim_tools usim \ usim $dbin/usim @@ -722,7 +735,7 @@ function main() { #[ "$CLEAN" = "1" ] && rm -rf $DIR/oaisim_mme_build_oai/build #mkdir -p $DIR/oaisim_mme_build_oai/build #cd $DIR/oaisim_mme_build_oai/build - #cmake .. + #eval $CMAKE_CMD #compilations \ # oaisim_mme_build_oai oaisim_mme \ # oaisim_mme $dbin/oaisim_mme.$REL @@ -752,7 +765,7 @@ function main() { echo "set ( T_TRACER $T_TRACER )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$rrh_build_dir/build - cmake .. + eval $CMAKE_CMD compilations \ rrh_gw rrh_gw \ rrh_gw $dbin/rrh_gw @@ -847,7 +860,7 @@ fi [ "$CLEAN" = "1" ] && rm -rf $OPENAIR_DIR/cmake_targets/doxygen/build mkdir -p $OPENAIR_DIR/cmake_targets/doxygen/build cd $OPENAIR_DIR/cmake_targets/doxygen/build - cmake .. + eval $CMAKE_CMD make doc ) >& $doxygen_log fi diff --git a/cmake_targets/build_ue b/cmake_targets/build_ue index 76b1c96315..9d9ca839d1 100644 --- a/cmake_targets/build_ue +++ b/cmake_targets/build_ue @@ -3,3 +3,4 @@ #sudo ./build_oai -c -C -I --install-optional-packages --UE -w USRP -V #sudo ./build_oai -c -C --UE -w USRP -V sudo ./build_oai -c -C --UE -w USRP +#sudo ./build_oai -c -C --UE -w USRP --build-eclipse From 66c5892c9e658c627a3fc94f5d60ca201bf3916a Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:17:42 +0800 Subject: [PATCH 483/571] #220 fixed incorrec path config for building usim/nvram --- cmake_targets/build_oai | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 119c013832..9c46f4b7b5 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -57,9 +57,6 @@ CMAKE_BUILD_TYPE="" UE_AUTOTEST_TRACE="False" trap handle_ctrl_c INT -gen_nvram_path=$OPENAIR_DIR/targets/bin -conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf - function print_help() { echo_info " This program installs OpenAirInterface Software @@ -394,6 +391,9 @@ function main() { set_openair_env cecho "OPENAIR_DIR = $OPENAIR_DIR" $green + gen_nvram_path=$OPENAIR_DIR/targets/bin + conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf + # for conf files copy in this bash script if [ -d /usr/lib/freeDiameter ]; then export FREEDIAMETER_PREFIX=/usr From 9e78b40d2e9a1a367aa5098e9f39ae1d88f94f73 Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:17:42 +0800 Subject: [PATCH 484/571] #220 fixed minor typo --- cmake_targets/build_oai | 4 ++-- cmake_targets/tools/build_helper | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 2 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 9c46f4b7b5..e1361295df 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -761,9 +761,9 @@ function main() { # build RF device and transport protocol libraries ##################################### - if [ "$eNB" = "1" -o "$RRH" = "1" ] ; then + if [ "$eNB" = "1" -o "$UE" = "1" -o "$RRH" = "1" ] ; then - if [ "$eNB" = "1" ] ; then + if [ "$eNB" = "1" -o "$UE" = "1" ] ; then build_dir=$lte_build_dir else build_dir=$rrh_build_dir diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index ede8ef4196..f0dfe6dfb0 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -127,7 +127,7 @@ clean_all_files() { set_openair_env dir=$OPENAIR_DIR/cmake_targets rm -rf $dir/log $OPENAIR_DIR/targets/bin/* - rm -rf $dir/lte_build_oai $dir/lte-simulators/build + rm -rf $dir/lte_build_oai/build $dir/lte-simulators/build rm -rf $dir/oaisim_build_oai/build $dir/oaisim_build_oai/CMakeLists.txt rm -rf $dir/autotests/bin $dir/autotests/log $dir/autotests/*/build } diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index a9142a9918..2f2be51aaa 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -190,7 +190,7 @@ int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) { eNB = PHY_vars_eNB_g[Mod_idP][CC_id]; for (i=0; idlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) { - MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rnti); + MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rntiP); LOG_E(PHY,"Can't remove UE, not enough memory allocated\n"); return(-1); } else { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index 873e51fbfe..3a9172a1c4 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -91,7 +91,7 @@ rlc_am_send_sdu ( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlc_pP) { -# if TRACE_RLC_UM_PDU +# if TRACE_RLC_AM_PDU char message_string[7000]; size_t message_string_size = 0; #if ENABLE_ITTI From 040957c1d49ceddbbdced4e82bffab4a1cce5046 Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:17:42 +0800 Subject: [PATCH 485/571] #220 fixed incorrect wiresahrk SFN/SF for UL/DL data --- openair2/LAYER2/MAC/ue_procedures.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index c27c0d524e..6bf552ab18 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -353,7 +353,7 @@ ue_send_sdu( if (opt_enabled) { trace_pdu(1, sdu, sdu_len, module_idP, 3, UE_mac_inst[module_idP].crnti, - UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); + frameP, subframeP, 0, 0); LOG_D(OPT,"[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", module_idP, frameP, UE_mac_inst[module_idP].crnti, sdu_len); } @@ -1923,7 +1923,7 @@ if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) if (opt_enabled) { trace_pdu(0, ulsch_buffer, buflen, module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0); LOG_D(OPT,"[UE %d][ULSCH] Frame %d subframe %d trace pdu for rnti %x with size %d\n", - module_idP, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, UE_mac_inst[module_idP].crnti, buflen); + module_idP, frameP, subframe, UE_mac_inst[module_idP].crnti, buflen); } } @@ -2104,7 +2104,7 @@ ue_scheduler( /* if (lcid == DCCH) { LOG_D(MAC,"[UE %d][SR] Frame %d subframe %d Pending data for SRB1=%d for LCGID %d \n", - module_idP, frameP,subframeP,UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], + module_idP, txFrameP,txSubframeP,UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], // UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]); } */ From 4a2f9d2571cacb2f6b50e4290ad2afa7253df339 Mon Sep 17 00:00:00 2001 From: "Wilson W.K. Thong" Date: Tue, 28 Mar 2017 10:17:42 +0800 Subject: [PATCH 486/571] #220 enhance logging to show also thread name --- openair2/UTIL/LOG/log.c | 17 +++++++++++++++++ targets/RT/USER/lte-softmodem.c | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index 9a2d6a96ef..26f3f852c1 100644 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -1032,6 +1032,19 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; } + if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { + #define THREAD_NAME_LEN 16 + static char threadname[THREAD_NAME_LEN]; + if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) + { + perror("pthread_getname_np : "); + } else { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + #undef THREAD_NAME_LEN + } + if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", func); @@ -1287,11 +1300,15 @@ int set_comp_log(int component, int level, int verbosity, int interval) LOG_EMERG); DevCheck((interval > 0) && (interval <= 0xFF), interval, 0, 0xFF); +#if 0 if ((verbosity == LOG_NONE) || (verbosity == LOG_LOW) || (verbosity == LOG_MED) || (verbosity == LOG_FULL) || (verbosity == LOG_HIGH)) { g_log->log_component[component].flag = verbosity; } +#else + g_log->log_component[component].flag = verbosity; +#endif g_log->log_component[component].level = level; g_log->log_component[component].interval = interval; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 2ad68765e3..f3b7907a7c 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1417,7 +1417,7 @@ int main( int argc, char **argv ) { set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); set_comp_log(PHY, LOG_DEBUG, LOG_HIGH, 1); set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RLC, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RLC, LOG_INFO, LOG_HIGH | FLAG_THREAD, 1); set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); From 4fea65a2653b80907064e2077b7c2155b2f81eda Mon Sep 17 00:00:00 2001 From: Vincent Ng Date: Tue, 28 Mar 2017 10:17:42 +0800 Subject: [PATCH 487/571] #220 change the I/Q in soft-scope to be normalized wrt |h| --- openair1/PHY/TOOLS/lte_phy_scope.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index dd057f9975..cea702ef78 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -493,7 +493,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int16_t **chest_f; int16_t *pdsch_llr; int16_t *pdsch_comp; - int8_t *pdcch_llr; + int16_t *pdsch_mag; + int8_t *pdcch_llr; int16_t *pdcch_comp; int8_t *pbch_llr; int16_t *pbch_comp; @@ -571,6 +572,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 0 // pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0 pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0]; + pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag0[0]; // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { @@ -752,8 +754,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, for (k=0; ksymbols_per_tti; k++) { for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { - I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i]; - Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1]; + int j = (2*frame_parms->N_RB_DL*12*k)+4*i; + I[ind] = (pdsch_mag[j ]!=0? 1.0/pdsch_mag[j ]: 0.0) * pdsch_comp[j ]*1.0; + Q[ind] = (pdsch_mag[j+1]!=0? 1.0/pdsch_mag[j+1]: 0.0) * pdsch_comp[j+1]*1.0; ind++; } } From 924c421beb3d6a8833290a711d05114d2071ae63 Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:17:42 +0800 Subject: [PATCH 488/571] #220 add help printout for run options --- openair1/SIMULATION/LTE_PHY/pdcchsim.c | 1 + targets/RT/USER/lte-softmodem.c | 1 + targets/SIMU/USER/oaisim.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index 4c50aaa5d5..2b13449c61 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -653,6 +653,7 @@ int main(int argc, char **argv) printf("-h This message\n"); printf("-a Use AWGN channel and not multipath\n"); printf("-c TDD config\n"); + printf("-S Subframe number (0..9)\n"); printf("-R N_RB_DL\n"); printf("-F use FDD frame\n"); printf("-p Use extended prefix mode\n"); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index f3b7907a7c..848b701133 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -329,6 +329,7 @@ void help (void) { printf(" --external-clock tells hardware to use an external clock reference\n"); printf(" --usim-test use XOR autentication algo in case of test usim mode\n"); printf(" --single-thread-disable. Disables single-thread mode in lte-softmodem\n"); + printf(" -A Set timing_advance\n"); printf(" -C Set the downlink frequency for all component carriers\n"); printf(" -d Enable soft scope and L1 and L2 stats (Xforms)\n"); printf(" -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index c783ebe075..b60e73e37c 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -243,7 +243,7 @@ help (void) printf ("-L [0-1] 0 to disable new link adaptation, 1 to enable new link adapatation\n"); printf ("-m Gives a fixed DL mcs for eNB scheduler\n"); printf ("-M Set the machine ID for Ethernet-based emulation\n"); - printf ("-n Set the number of frames for the simulation\n"); + printf ("-n Set the number of frames for the simulation. 0 for no limit\n"); printf ("-O [enb_conf_file] eNB configuration file name\n"); printf ("-p Set the total number of machine in emulation - valid if M is set\n"); printf ("-P [trace type] Enable protocol analyzer. Possible values for OPT:\n"); From 2660ac0570c46097d5148663decdc5126189acf6 Mon Sep 17 00:00:00 2001 From: "Wilson W.K. Thong" Date: Tue, 28 Mar 2017 10:38:46 +0800 Subject: [PATCH 489/571] #221 fixed RRC crash when parsing the RRCConnectionReconfiguration message with empty neighCellConfig in measObjectEUTRA --- openair2/LAYER2/MAC/config.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 12dbeecf16..ecbe0b68ba 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -332,15 +332,17 @@ rrc_mac_config_req( if (eNB_flagP == 0) { if (measObj!= NULL) { if (measObj[0]!= NULL) { - UE_mac_inst[Mod_idP].n_adj_cells = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.count; - LOG_I(MAC,"Number of adjacent cells %d\n",UE_mac_inst[Mod_idP].n_adj_cells); + if (measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList != NULL) { + UE_mac_inst[Mod_idP].n_adj_cells = measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList->list.count; + LOG_D(MAC,"Number of adjacent cells %d\n",UE_mac_inst[Mod_idP].n_adj_cells); - for (i=0; imeasObject.choice.measObjectEUTRA.cellsToAddModList->list.array[i]->physCellId; - LOG_I(MAC,"Cell %d : Nid_cell %d\n",i,UE_mac_inst[Mod_idP].adj_cell_id[i]); - } + for (i=0; imeasObject.choice.measObjectEUTRA.cellsToAddModList->list.array[i]->physCellId; + LOG_D(MAC,"Cell %d : Nid_cell %d\n",i,UE_mac_inst[Mod_idP].adj_cell_id[i]); + } - mac_xface->phy_config_meas_ue(Mod_idP,0,eNB_index,UE_mac_inst[Mod_idP].n_adj_cells,UE_mac_inst[Mod_idP].adj_cell_id); + mac_xface->phy_config_meas_ue(Mod_idP,0,eNB_index,UE_mac_inst[Mod_idP].n_adj_cells,UE_mac_inst[Mod_idP].adj_cell_id); + } } /* From 8d88bae9e88d0e723659a8d5b058970eadbae918 Mon Sep 17 00:00:00 2001 From: "Wilson W.K. Thong" Date: Tue, 28 Mar 2017 10:38:46 +0800 Subject: [PATCH 490/571] #221 fixed incorrect processing of CQI_PMI_Index in RRCConnectionReconfiguration --- openair2/RRC/LITE/rrc_UE.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index cedf5a11f5..84d9e802dd 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -975,6 +975,8 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio physicalConfigDedicated2->pusch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pusch_ConfigDedicated)); physicalConfigDedicated2->pucch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pucch_ConfigDedicated)); physicalConfigDedicated2->cqi_ReportConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic + = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated)); physicalConfigDedicated2->schedulingRequestConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig)); physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); @@ -1036,14 +1038,25 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio // Update cqi_ReportConfig if(radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig != NULL) { - LOG_I(RRC,"Update cqi_ReportConfig config \n"); + LOG_I(RRC,"Update cqi_ReportConfig config (size=%d,%d)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig), sizeof(CQI_ReportConfig_t)); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig = CALLOC(1,sizeof(CQI_ReportConfig_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig, (char*)radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig, - sizeof(physicalConfigDedicated2->cqi_ReportConfig)); + sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); + + if (radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { + LOG_I(RRC,"Update cqi_ReportPeriodic config (size=%d,%d)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic), sizeof(CQI_ReportPeriodic_t)); + + if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic == NULL) + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1,sizeof(CQI_ReportPeriodic_t)); + + memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic, + (char*)radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic, + sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); + } } else { From 0487631c769060e4f24e82b8cf680ebcdd9d2562 Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:38:46 +0800 Subject: [PATCH 491/571] #221 fixed crash when processing false DCI1A due to incorrect HARQ-PID checking --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 2 +- openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 2a8e442563..6c0c4ff94c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4799,7 +4799,7 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, return(0); } - if(harq_pid >8) + if(harq_pid>=8) { LOG_I(PHY,"bad harq id \n"); return(0); @@ -5013,7 +5013,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, #endif // I- check dci content minimum coherency - if(harq_pid >8) + if(harq_pid>=8) { LOG_I(PHY,"bad harq pid\n"); return(0); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index bd49fdacb0..9ae1dc6603 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -242,7 +242,7 @@ uint32_t ulsch_encoding(uint8_t *a, return(-1); } - if (harq_pid > 7) { + if (harq_pid >= 8) { LOG_E(PHY,"Illegal harq_pid %d\n",harq_pid); return(-1); } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c index a4bcd802f5..6dced43b5f 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c @@ -402,7 +402,7 @@ void ulsch_modulation(int32_t **txdataF, // x1 is set in lte_gold_generic x2 = (ulsch->rnti<<14) + (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1 - if (harq_pid > 7) { + if (harq_pid>=8) { printf("ulsch_modulation.c: Illegal harq_pid %d\n",harq_pid); return; } From 002b9b0f65cdd4631e63d5f30b795b798ea6181e Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Tue, 28 Mar 2017 10:42:04 +0800 Subject: [PATCH 492/571] #222 fix incorrect PUCCH format when sending SR in TDD --- openair1/SCHED/phy_procedures_lte_ue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 776de2335d..adfe0e7581 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -633,7 +633,13 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type, } if(SR_payload == 1) { - return pucch_format1; + if (frame_type == FDD) { + return pucch_format1; + } else if (frame_type == TDD) { + return pucch_format1b; + } else { + AssertFatal(1==0,"Unknown frame_type"); + } } } else From 40f9b9f4e053344f29cc2ef15e6b12f266ab1781 Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Mon, 27 Mar 2017 17:54:31 +0800 Subject: [PATCH 493/571] #223 fixed USRP initialization when disabling --ue-carrier-scan option --- targets/RT/USER/lte-ue.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 8a0b646fc3..f07a0628f8 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -323,11 +323,11 @@ static void *UE_thread_synch(void *arg) { downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, UE->UE_scan_carrier ); - if (UE->UE_scan_carrier == 1) { - UE->UE_scan_carrier = 0; + // rerun with new cell parameters and frequency-offset for (i=0; irf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + if (UE->UE_scan_carrier == 1) { if (freq_offset >= 0) openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); else @@ -337,6 +337,7 @@ static void *UE_thread_synch(void *arg) { downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; freq_offset=0; } + } // reconfigure for potentially different bandwidth switch(UE->frame_parms.N_RB_DL) { @@ -375,6 +376,10 @@ static void *UE_thread_synch(void *arg) { LOG_E(HW,"Could not start the device\n"); oai_exit=1; }*/ + + if (UE->UE_scan_carrier == 1) { + + UE->UE_scan_carrier = 0; } else { AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); UE->is_synchronized = 1; From f65150aa6432a7c62c392da3c27a821d0cd593de Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Fri, 17 Mar 2017 18:52:32 +0800 Subject: [PATCH 494/571] #226 fix incorrect resetting downlink ACK/NACK in the middle of UE_TX processing --- openair1/SCHED/phy_procedures_lte_ue.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 776de2335d..faaef124c1 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -729,7 +729,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, } else if (subframe == 8) { // ACK subframes 4 candidate_dl[0] = 4; } else { - LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", + LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal tx-subframe %d for tdd_config %d\n", ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config); return(0); } @@ -743,8 +743,8 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, } } if (last_dl >= 10) { - LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", - ue->Mod_id,proc->frame_tx,last_dl,frame_parms->tdd_config); + LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal rx-subframe %d (tx-subframe %d) for tdd_config %d\n", + ue->Mod_id,proc->frame_tx,last_dl,subframe,frame_parms->tdd_config); return (0); } @@ -1775,13 +1775,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } } - ack_status_cw0 = reset_ack(&ue->frame_parms, + ack_status_cw0 = get_ack(&ue->frame_parms, ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx, pucch_ack_payload, 0); - ack_status_cw1 = reset_ack(&ue->frame_parms, + ack_status_cw1 = get_ack(&ue->frame_parms, ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack, subframe_tx, pucch_ack_payload, From adf920b6a992f6e9a60cdc6c65b618273fba256b Mon Sep 17 00:00:00 2001 From: Wilson Thong Date: Fri, 17 Mar 2017 14:57:53 +0800 Subject: [PATCH 495/571] #229 add support on processing multiple RAR payloads in one single MSG2 --- openair1/PHY/LTE_TRANSPORT/rar_tools.c | 2 +- openair1/SCHED/phy_procedures_lte_ue.c | 3 +- openair2/LAYER2/MAC/proto.h | 4 ++- openair2/LAYER2/MAC/rar_tools.c | 48 +++++++++++++++++++++++--- openair2/PHY_INTERFACE/defs.h | 2 +- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c index 2629c6ba7f..b7550d5573 100644 --- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c @@ -258,7 +258,7 @@ int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue, if (ulsch->harq_processes[harq_pid]->nb_rb > 4) { msg("rar_tools.c: unlikely rb count for RAR grant : nb_rb > 3\n"); - return(-1); + // return(-1); } // ulsch->harq_processes[harq_pid]->Ndi = 1; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 776de2335d..a9e27315d4 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -3236,7 +3236,8 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo ue->prach_resources[eNB_id]->ra_RNTI, dlsch0->harq_processes[0]->b, &ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti, - ue->prach_resources[eNB_id]->ra_PreambleIndex); + ue->prach_resources[eNB_id]->ra_PreambleIndex, + dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload ue->pdcch_vars[(subframe_rx+1) & 0x1][eNB_id]->crnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti; diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 3343e8821e..ea264f1bfd 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -454,6 +454,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP,int CC_id,frame_t frameP,u @param t_crnti Pointer to PHY variable containing the T_CRNTI @param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of random-access procedure +@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload @returns timing advance or 0xffff if preamble doesn't match */ uint16_t @@ -464,7 +465,8 @@ ue_process_rar( const rnti_t ra_rnti, uint8_t * const dlsch_buffer, rnti_t * const t_crnti, - const uint8_t preamble_index + const uint8_t preamble_index, + uint8_t* selected_rar_buffer ); diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 2de22c067a..51900d8f3a 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -136,15 +136,48 @@ ue_process_rar( const rnti_t ra_rnti, uint8_t* const dlsch_buffer, rnti_t* const t_crnti, - const uint8_t preamble_index + const uint8_t preamble_index, + uint8_t* selected_rar_buffer // output argument for storing the selected RAR header and RAR payload ) //------------------------------------------------------------------------------ { + uint16_t ret = 0; // return value RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; // RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1); uint8_t *rar = (uint8_t *)(dlsch_buffer+1); + // get the last RAR payload for working with CMW500 + uint8_t n_rarpy = 0; // number of RAR payloads + uint8_t n_rarh = 0; // number of MAC RAR subheaders + uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs + while (1) { + n_rarh++; + if (rarh->T == 1) { + n_rarpy++; + LOG_D(MAC, "RAPID %d\n", rarh->RAPID); + } + + if (rarh->RAPID == preamble_index) { + LOG_D(PHY, "Found RAR with the intended RAPID %d\n", rarh->RAPID); + rar = (uint8_t *)(dlsch_buffer+n_rarh + (n_rarpy-1)*6); + break; + } + + if (abs((int)rarh->RAPID - (int)preamble_index) < abs((int)best_rx_rapid - (int)preamble_index)) { + best_rx_rapid = rarh->RAPID; + rar = (uint8_t *)(dlsch_buffer+n_rarh + (n_rarpy-1)*6); + } + + if (rarh->E == 0) { + LOG_I(PHY, "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", best_rx_rapid); + break; + } else { + rarh++; + } + }; + LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_rarh, n_rarpy); + if (CC_id>0) { LOG_W(MAC,"Should not have received RAR on secondary CCs! \n"); return(0xffff); @@ -172,7 +205,7 @@ ue_process_rar( if (opt_enabled) { LOG_D(OPT,"[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n", module_idP, CC_id, frameP, ra_rnti); - trace_pdu(1, (uint8_t*)rarh, 7, module_idP, 2, ra_rnti, + trace_pdu(1, (uint8_t*)dlsch_buffer, n_rarh + n_rarpy*6, module_idP, 2, ra_rnti, UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0); } @@ -180,9 +213,16 @@ ue_process_rar( *t_crnti = (uint16_t)rar[5]+(rar[4]<<8);//rar->t_crnti; UE_mac_inst[module_idP].crnti = *t_crnti;//rar->t_crnti; //return(rar->Timing_Advance_Command); - return((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); + ret = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); } else { UE_mac_inst[module_idP].crnti=0; - return(0xffff); + ret = (0xffff); } + + // move the selected RAR to the front of the RA_PDSCH buffer + memcpy(selected_rar_buffer+0, (uint8_t*)rarh, 1); + memcpy(selected_rar_buffer+1, (uint8_t*)rar , 6); + + return ret; + } diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h index 5769d94a37..effc4c7877 100644 --- a/openair2/PHY_INTERFACE/defs.h +++ b/openair2/PHY_INTERFACE/defs.h @@ -170,7 +170,7 @@ typedef struct { PRACH_RESOURCES_t* (*ue_get_rach)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t Msg3_flag,sub_frame_t subframe); /// Process Random-Access Response - uint16_t (*ue_process_rar)(module_id_t Mod_id,int CC_id,frame_t frameP, uint16_t ra_rnti, uint8_t *dlsch_buffer, uint16_t *t_crnti,uint8_t preamble_index); + uint16_t (*ue_process_rar)(module_id_t Mod_id,int CC_id,frame_t frameP, uint16_t ra_rnti, uint8_t *dlsch_buffer, uint16_t *t_crnti,uint8_t preamble_index, uint8_t* selected_rar_buffer); /// Get SR payload (0,1) from UE MAC uint32_t (*ue_get_SR)(module_id_t Mod_id,int CC_id,frame_t frameP,uint8_t eNB_id,rnti_t rnti,sub_frame_t subframe); From 9a464ca077de3f8fa5033f82576f94a5e3ca1370 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Mar 2017 10:13:54 +0200 Subject: [PATCH 496/571] fix: remove change in build_helper --- cmake_targets/tools/build_helper | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index e3bd2e0782..ede8ef4196 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -164,13 +164,7 @@ compilations() { } > $dlog/$2.$REL.txt 2>&1 set -e echo_info "Log file for compilation has been written to: $dlog/$2.$REL.txt" - -echo "#!/bash/bin" > domake_$2.sh - echo "$SUDO make -j`nproc` $2" >> domake_$2.sh - echo "$SUDO cp $3 $4" >> domake_$2.sh - chmod 775 domake_$2.sh - -if [ -s $3 ] ; then + if [ -s $3 ] ; then cp $3 $4 echo_success "$2 compiled" check_warnings "$dlog/$2.$REL.txt" From 02bfef21848e934ee18ede3f4330ae6448a687a8 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Mar 2017 16:03:17 +0200 Subject: [PATCH 497/571] fix UE variable setting in build_oai --- cmake_targets/build_oai | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index e1361295df..89090d90c5 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -33,6 +33,13 @@ ORIGIN_PATH=$PWD THIS_SCRIPT_PATH=$(dirname $(readlink -f $0)) source $THIS_SCRIPT_PATH/tools/build_helper +# set environment variables (OPENAIR_HOME, ...) +set_openair_env + +#variables for UE data generation +gen_nvram_path=$OPENAIR_DIR/targets/bin +conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf + MSC_GEN="False" XFORMS="True" FLEXRAN_AGENT_SB_IF="True" @@ -388,12 +395,8 @@ function main() { echo_info "2. Setting the OAI PATHS ..." - set_openair_env cecho "OPENAIR_DIR = $OPENAIR_DIR" $green - gen_nvram_path=$OPENAIR_DIR/targets/bin - conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf - # for conf files copy in this bash script if [ -d /usr/lib/freeDiameter ]; then export FREEDIAMETER_PREFIX=/usr From 9814de0570d7859ee544955940f2aad78fe16124 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Mar 2017 16:13:31 +0200 Subject: [PATCH 498/571] revert deletion of directories to before commit 9e78b40d2e9a1a367aa5098e9f39ae1d88f94f73 --- cmake_targets/tools/build_helper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index f0dfe6dfb0..ede8ef4196 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -127,7 +127,7 @@ clean_all_files() { set_openair_env dir=$OPENAIR_DIR/cmake_targets rm -rf $dir/log $OPENAIR_DIR/targets/bin/* - rm -rf $dir/lte_build_oai/build $dir/lte-simulators/build + rm -rf $dir/lte_build_oai $dir/lte-simulators/build rm -rf $dir/oaisim_build_oai/build $dir/oaisim_build_oai/CMakeLists.txt rm -rf $dir/autotests/bin $dir/autotests/log $dir/autotests/*/build } From 99280926ed8426c858182cf57f3aca57480d0ba5 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 28 Mar 2017 17:24:21 +0200 Subject: [PATCH 499/571] fix in dlsim to catch cases where pdcch is not decoded --- openair1/SIMULATION/LTE_PHY/dlsim.c | 42 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index aa8e9360ea..308890701a 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1301,7 +1301,7 @@ int main(int argc, char **argv) unsigned int ret; unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors=0;//,num_layers; + unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors[4]={0,0,0,0};//,num_layers; //int re_allocated; char fname[32],vname[32]; FILE *bler_fd; @@ -2246,7 +2246,10 @@ int main(int argc, char **argv) round_trials[2] = 0; round_trials[3] = 0; - dci_errors=0; + dci_errors[0]=0; + dci_errors[1]=0; + dci_errors[2]=0; + dci_errors[3]=0; // avg_ber = 0; round=0; @@ -2499,6 +2502,9 @@ int main(int argc, char **argv) if (UE->dlsch[subframe&0x1][0][0]->active == 0) { //printf("DCI not received\n"); + dci_errors[round]++; + UE->dlsch_errors[0] = 1; + /* write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],12*UE->frame_parms.N_RB_DL*3,1,1); @@ -2837,13 +2843,13 @@ int main(int argc, char **argv) double std_phy_proc_rx_demod=0; double std_phy_proc_rx_dec=0; - effective_rate = ((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); + effective_rate = 1.0-((double)(errs[0]+errs[1]+errs[2]+errs[3])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n", SNR, (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12))); - printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f)\n", + printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f, normalized delay %f (%f)\n", errs[0], errs2[0], round_trials[0], @@ -2857,13 +2863,13 @@ int main(int argc, char **argv) (double)errs[1]/(round_trials[0]), (double)errs[2]/(round_trials[0]), (double)errs[3]/(round_trials[0]), - dci_errors, - round_trials[0], - (double)dci_errors/(round_trials[0]), - rate*effective_rate, + dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3], + round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3], + (double)(dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3])/(round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]), + //rate*effective_rate, 100*effective_rate, - rate, - rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + //rate, + //rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -2986,7 +2992,7 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3], - dci_errors); + dci_errors[0]); } else { fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", SNR, @@ -3002,7 +3008,7 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3], - dci_errors); + dci_errors[0]); } @@ -3035,7 +3041,7 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3], - dci_errors); + dci_errors[0]); //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", @@ -3058,9 +3064,9 @@ int main(int argc, char **argv) (double)errs[1]/(round_trials[0]), (double)errs[2]/(round_trials[0]), (double)errs[3]/(round_trials[0]), - dci_errors, + dci_errors[0], round_trials[0], - (double)dci_errors/(round_trials[0]), + (double)dci_errors[0]/(round_trials[0]), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -3079,7 +3085,7 @@ int main(int argc, char **argv) round_trials[2], errs[3], round_trials[3], - dci_errors); + dci_errors[0]); //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", @@ -3103,9 +3109,9 @@ int main(int argc, char **argv) (double)errs[1]/(round_trials[0]), (double)errs[2]/(round_trials[0]), (double)errs[3]/(round_trials[0]), - dci_errors, + dci_errors[0], round_trials[0], - (double)dci_errors/(round_trials[0]), + (double)dci_errors[0]/(round_trials[0]), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); From c207df8b0e33942bf5d5c6f63a15929123a98b6a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Mar 2017 17:25:27 +0200 Subject: [PATCH 500/571] bugfix: dlsim was not working anymore When you ran it with the scope as: ./dlsim -X you saw no activity in the "PDSCH I/Q of MF Output" window, so matter what SNR you put (even for very high SNR, say: ./dlsim -X -s40) this commit seems to fix it. I am not sure it is the end of story. The 2 threads PDCCH/PDSCH structures may still not be used correctly everywhere. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index aa8e9360ea..5ab6007a37 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1998,7 +1998,7 @@ int main(int argc, char **argv) } */ - UE->pdcch_vars[0][0]->crnti = n_rnti; + UE->pdcch_vars[subframe & 0x1][0]->crnti = n_rnti; // Fill in UL_alloc UL_alloc_pdu.type = 0; From 3c7c61a46c58f11fc79112c291efbd021010490c Mon Sep 17 00:00:00 2001 From: hbilel Date: Tue, 28 Mar 2017 18:08:00 +0200 Subject: [PATCH 501/571] RLC AM fix specific reassembly issue --- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 37 +++++++++++++++++-- openair2/UTIL/LISTS/list2.c | 2 + 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 62e67b044b..7b0d74c5d9 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -796,6 +796,9 @@ rlc_am_rx_list_check_duplicate_insert_pdu( rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; // it is assumed this pdu is in rx window + /* Init Reassembly status */ + ((rlc_am_rx_pdu_management_t*)(tb_pP->data))->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO; + if (cursor_p == NULL) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[INSERT PDU] LINE %d RX PDU SN %04d (only inserted)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), @@ -806,9 +809,6 @@ rlc_am_rx_list_check_duplicate_insert_pdu( } - /* Init Reassembly status */ - ((rlc_am_rx_pdu_management_t*)(tb_pP->data))->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO; - if (pdu_rx_info_p->rf == 0) { // Case normal PDU received pdu_status = rlc_am_rx_list_handle_pdu(ctxt_pP,rlc_pP,tb_pP); } @@ -1396,6 +1396,7 @@ rlc_am_rx_mark_all_segments_received( } } //----------------------------------------------------------------------------- +//#define RLC_AM_DEBUG_REASSEMBLY void rlc_am_rx_list_reassemble_rlc_sdus( const protocol_ctxt_t* const ctxt_pP, @@ -1413,6 +1414,9 @@ rlc_am_rx_list_reassemble_rlc_sdus( rlc_am_rx_pdu_management_t* rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data)); pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; +#ifdef RLC_AM_DEBUG_REASSEMBLY + rlc_usn_t sn_reass_start = pdu_info_p->sn; +#endif /* Specific process for the first SN if all PDU segments had been reassembled but not freed */ if ((rlc_am_rx_pdu_management_p->all_segments_received > 0) && (pdu_info_p->rf != 0)) { @@ -1445,6 +1449,10 @@ rlc_am_rx_list_reassemble_rlc_sdus( cursor_p = list2_get_head(&rlc_pP->receiver_buffer); if (cursor_p == NULL) { +#ifdef RLC_AM_DEBUG_REASSEMBLY + LOG_D(RLC, "RLC AM REASSEMBLY from sn=%d to ALL, vrR=%d vrMS=%d\n", + sn_reass_start,rlc_pP->vr_r,rlc_pP->vr_ms); +#endif return; } @@ -1458,6 +1466,10 @@ rlc_am_rx_list_reassemble_rlc_sdus( cursor_p = cursor_p->next; if (cursor_p == NULL) { +#ifdef RLC_AM_DEBUG_REASSEMBLY + LOG_D(RLC, "RLC AM REASSEMBLY from sn=%d to ALL, Last is Segment, vrR=%d vrMS=%d\n", + sn_reass_start,rlc_pP->vr_r,rlc_pP->vr_ms); +#endif return; } @@ -1482,12 +1494,29 @@ rlc_am_rx_list_reassemble_rlc_sdus( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); } +#endif +#ifdef RLC_AM_DEBUG_REASSEMBLY + LOG_D(RLC, "RLC AM REASSEMBLY from sn=%d to ALL, vrR=%d vrMS=%d\n", + sn_reass_start,rlc_pP->vr_r,rlc_pP->vr_ms); #endif return; } - } while (((rlc_am_rx_pdu_management_p->pdu_info.sn == ((rlc_am_rx_old_pdu_management->pdu_info.sn + 1) & RLC_AM_SN_MASK)) && (rlc_am_rx_old_pdu_management->all_segments_received > 0)) + } while (((RLC_AM_DIFF_SN(rlc_am_rx_pdu_management_p->pdu_info.sn,rlc_am_rx_old_pdu_management->pdu_info.sn) < 2) && (rlc_am_rx_old_pdu_management->all_segments_received > 0)) || ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && (rlc_am_rx_pdu_management_p->segment_reassembled != RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO))); + +#ifdef RLC_AM_DEBUG_REASSEMBLY + mem_block_t* cursor_head_p = list2_get_head(&rlc_pP->receiver_buffer); + if (cursor_head_p == NULL) { + return; + } + + rlc_am_pdu_info_t* pdu_info_head_p = &((rlc_am_rx_pdu_management_t*)(cursor_head_p->data))->pdu_info; + + LOG_D(RLC, "RLC AM REASSEMBLY from sn=%d to sn=%d, next_sn=%d head sn=%d vrR=%d vrMS=%d\n", + sn_reass_start,rlc_am_rx_old_pdu_management->pdu_info.sn,rlc_am_rx_pdu_management_p->pdu_info.sn,pdu_info_head_p->sn,rlc_pP->vr_r,rlc_pP->vr_ms); +#endif + } //----------------------------------------------------------------------------- mem_block_t * diff --git a/openair2/UTIL/LISTS/list2.c b/openair2/UTIL/LISTS/list2.c index abd9d2aacc..8daa19bfa4 100644 --- a/openair2/UTIL/LISTS/list2.c +++ b/openair2/UTIL/LISTS/list2.c @@ -233,6 +233,8 @@ list2_add_head (mem_block_t * elementP, list2_t * listP) // almost one element if (head == NULL) { + elementP->previous = NULL; + elementP->next = NULL; listP->head = elementP; listP->tail = elementP; } else { From bb4131b33d532356365e0dae7225002cd6b56671 Mon Sep 17 00:00:00 2001 From: hbilel Date: Tue, 28 Mar 2017 19:59:52 +0200 Subject: [PATCH 502/571] RLC AM add fixes --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 8 ++++++++ openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 4 ++-- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c | 5 ++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 4cef19253a..fc31d6e8b6 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -1233,6 +1233,10 @@ mem_block_t * rlc_am_get_pdu_to_retransmit( { // TO DO : RLC Notification to RRC + ReEstablishment procedure tx_data_pdu_management->flags.max_retransmit = 1; + LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RLC AM MAX RETX=%d] SN %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + tx_data_pdu_management->retx_count_next, + sn); } } else if (rlc_pP->nb_bytes_requested_by_mac >= 5) @@ -1273,6 +1277,10 @@ mem_block_t * rlc_am_get_pdu_to_retransmit( { // TO DO : RLC Notification to RRC + ReEstablishment procedure tx_data_pdu_management->flags.max_retransmit = 1; + LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RLC AM MAX RETX=%d] SN %04d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), + tx_data_pdu_management->retx_count_next, + sn); } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 7b0d74c5d9..33b86f7948 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -261,7 +261,7 @@ mem_block_t * create_new_segment_from_pdu( RLC_AM_PDU_SET_E(*pdu_segment_header_p); } /* SN */ - (*pdu_segment_header_p) |= (pdu_new_segment_info_p->sn >> 8) ; + (*pdu_segment_header_p) |= ((pdu_new_segment_info_p->sn >> 8) & 0x3); *(pdu_segment_header_p + 1) = (pdu_new_segment_info_p->sn & 0xFF); pdu_segment_header_p += 2; @@ -272,7 +272,7 @@ mem_block_t * create_new_segment_from_pdu( RLC_AM_PDU_SET_LSF(*pdu_segment_header_p); } /* Store SO bytes */ - * (pdu_segment_header_p ) = (pdu_new_segment_info_p->so >> 8) & 0xFF; + * (pdu_segment_header_p ) |= ((pdu_new_segment_info_p->so >> 8) & 0x7F); * (pdu_segment_header_p + 1) = pdu_new_segment_info_p->so & 0xFF; if (num_li) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 3a00946160..b1f53586cb 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -378,7 +378,10 @@ rlc_am_receive_process_control_pdu( break; } } - sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK; + if (prev_nack_sn != nack_sn) { + /* do not increment sn_cursor in case of several informations for the same nack_sn */ + sn_cursor = (sn_cursor + 1) & RLC_AM_SN_MASK; + } } } From 49006696ac4ef2af66de0b7fe2b6033b06c5ca51 Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 29 Mar 2017 15:59:16 +0200 Subject: [PATCH 503/571] RLC AM add various fixes --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 12 +++++++---- .../LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h | 2 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c | 5 ++--- .../LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c | 2 +- .../LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c | 20 ++++++++++++++++++- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 13 +++++++++--- 6 files changed, 41 insertions(+), 13 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index eda90edf9a..03fabf47b3 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -1253,14 +1253,16 @@ rlc_am_data_req ( l_rlc_p->next_sdu_index = (l_rlc_p->next_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; if (l_rlc_p->channel_id <3) { - LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d\n", + LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d vtA %d vtS %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p), data_size, l_rlc_p->nb_sdu, l_rlc_p->current_sdu_index, l_rlc_p->next_sdu_index, conf, - mui); + mui, + l_rlc_p->vt_a, + l_rlc_p->vt_s); } } else { #if MESSAGE_CHART_GENERATOR @@ -1278,12 +1280,14 @@ rlc_am_data_req ( data_size, mui); #endif - LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ BUFFER FULL, NB SDU %d current_sdu_index=%d next_sdu_index=%d size_input_sdus_buffer=%d\n", + LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ BUFFER FULL, NB SDU %d current_sdu_index=%d next_sdu_index=%d size_input_sdus_buffer=%d vtA=%d vtS=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p), l_rlc_p->nb_sdu, l_rlc_p->current_sdu_index, l_rlc_p->next_sdu_index, - RLC_AM_SDU_CONTROL_BUFFER_SIZE); + RLC_AM_SDU_CONTROL_BUFFER_SIZE, + l_rlc_p->vt_a, + l_rlc_p->vt_s); LOG_W(RLC, " input_sdus[].mem_block=%p next input_sdus[].flags.segmented=%d\n", l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].mem_block, l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.segmented); l_rlc_p->stat_tx_pdcp_sdu_discarded += 1; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h index 10f310d5de..69429b84b8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h @@ -48,7 +48,7 @@ # define RLC_AM_SDU_DATA_BUFFER_SIZE 64*1024 /** Max number of incoming SDUs from upper layer that can be buffered in a RLC AM protocol instance. */ -# define RLC_AM_SDU_CONTROL_BUFFER_SIZE 128 +# define RLC_AM_SDU_CONTROL_BUFFER_SIZE 1024 /** Size of the retransmission buffer (number of PDUs). */ # define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_WINDOW_SIZE diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c index b41dea42f2..4b5c173d4b 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c @@ -57,13 +57,12 @@ void rlc_am_free_in_sdu( memset(&rlcP->input_sdus[index_in_bufferP], 0, sizeof(rlc_am_tx_sdu_management_t)); rlcP->input_sdus[index_in_bufferP].flags.transmitted_successfully = 1; - // TODO : understand why. This should not happen + // case when either one SDU needs to be removed from segmentation or SDU buffer is full if (rlcP->current_sdu_index == index_in_bufferP) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; } - // TODO : this loop is useless as UL SDUs are transmitted and acknowledged in sequence - // even with PDCP UL SDU discard functionality + // wrapping and reset current_sdu_index to next_sdu_index when all transmitted SDUs have been acknowledged while ((rlcP->current_sdu_index != rlcP->next_sdu_index) && (rlcP->input_sdus[rlcP->current_sdu_index].flags.transmitted_successfully == 1)) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index fc31d6e8b6..f80a46695d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -95,7 +95,7 @@ boolean_t rlc_am_nack_pdu ( } // Check consistency - if ((so_startP < so_endP) && (so_endP < tx_data_pdu_buffer_p->payload_size)) { + if ((so_startP <= so_endP) && (so_endP < tx_data_pdu_buffer_p->payload_size)) { if (prev_nack_snP != snP) { /* New NACK_SN with SO */ /* check whether a new segment is to be placed in Retransmission Buffer, then increment vrReTx */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 33b86f7948..cad1a776a8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -222,6 +222,7 @@ mem_block_t * create_new_segment_from_pdu( pdu_new_segment_info_p->p = pdu_rx_info_p->p; pdu_new_segment_info_p->rf = 1; pdu_new_segment_info_p->fi = (((fi_start ? 0: 1) << 1) | (fi_end ? 0: 1)); + pdu_new_segment_info_p->num_li = num_li; pdu_new_segment_info_p->e = (num_li ? 1: 0); pdu_new_segment_info_p->lsf = (lsf ? 1: 0); pdu_new_segment_info_p->so = pdu_rx_info_p->so + so_offset; @@ -380,6 +381,23 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; } + // Try to catch a segment duplicate + next_cursor_p = cursor_p; + while ((next_cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn)) { + if ((so_start_segment >= pdu_info_cursor_p->so) && (so_end_segment <= pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size - 1)) { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); + return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; + } + next_cursor_p = next_cursor_p->next; + if (next_cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + } + } + + // Reset pdu_info_cursor_p because of the loop before + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + // Try to Handle the most likely cases first if (pdu_info_cursor_p->so == 0) { @@ -425,7 +443,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( } /* Now discard the PDU segment if it is within so_start_min and so_end */ - if ((so_start_min <= so_start_segment) && (so_end_segment < so_end)) { + if ((so_start_min <= so_start_segment) && (so_end_segment <= so_end - 1)) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index b1f53586cb..d33dc78e91 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -562,7 +562,7 @@ rlc_am_send_status_pdu( all_segments_received = ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received; /* First fill NACK_SN with each missing PDU between current sn_nack and sn_cursor */ - while ((sn_nack != sn_cursor) && (sn_nack != rlc_pP->vr_ms)) { + while ((sn_nack != sn_cursor) && (RLC_AM_DIFF_SN(sn_nack,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))) { if (nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) <= nb_bits_to_transmit) { /* Fill NACK_SN infos */ control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_nack; @@ -596,6 +596,10 @@ rlc_am_send_status_pdu( } } + if (sn_nack == rlc_pP->vr_ms) { + break; + } + /* Now process all Segments of sn_cursor if PDU not fully received */ if ((!status_report_completed) && (all_segments_received == 0) && (sn_cursor != rlc_pP->vr_ms)) { AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id); @@ -732,10 +736,13 @@ rlc_am_send_status_pdu( } while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == sn_cursor)); } - /* Increment sn_nack except if sn_nack = vrMS and if current SN was not fully received */ - if (sn_nack != rlc_pP->vr_ms) { + /* Increment sn_nack except if sn_cursor = vrMS and if current SN was not fully received */ + if (RLC_AM_DIFF_SN(sn_cursor,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r)) { sn_nack = RLC_AM_NEXT_SN(sn_cursor); } + else { + sn_nack = rlc_pP->vr_ms; + } } // End main while NACK_SN From c36c04537a232bc743ade21fc24ea0440febf38e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 3 Apr 2017 10:24:52 +0200 Subject: [PATCH 504/571] integration fix: fixes for pthread_getname_np - define _GNU_SOURCE before including pthread.h - do not use static for the array 'threadname' used to store the name, it makes it a global variable accessed by several threads in parallel - increase size of 'threadname' (maybe not necessary) - properly indent #define / #under (# should be at column 1) --- openair2/UTIL/LOG/log.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index 26f3f852c1..9c28c4b68d 100644 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -28,6 +28,7 @@ */ +#define _GNU_SOURCE /* required for pthread_getname_np */ //#define LOG_TEST 1 #define COMPONENT_LOG @@ -1033,8 +1034,8 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, } if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { - #define THREAD_NAME_LEN 16 - static char threadname[THREAD_NAME_LEN]; +# define THREAD_NAME_LEN 128 + char threadname[THREAD_NAME_LEN]; if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) { perror("pthread_getname_np : "); @@ -1042,7 +1043,7 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; } - #undef THREAD_NAME_LEN +# undef THREAD_NAME_LEN } if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { From 666ae5d0e1144ebcb4509e96e987ab259e154fdd Mon Sep 17 00:00:00 2001 From: gabrielC Date: Mon, 3 Apr 2017 14:06:41 +0200 Subject: [PATCH 505/571] commit id added to the log --- targets/RT/USER/lte-softmodem.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 848b701133..e09c32cde4 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1387,6 +1387,12 @@ int main( int argc, char **argv ) { memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); + + char command_line[500]; + sprintf(command_line,"git log -1"); + if (background_system(command_line) != 0) + printf("ERROR failed command '%s'", command_line); + set_latency_target(); // set default parameters From e7f1cf42384d1fe7c6573734b881c8580aac079c Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 3 Apr 2017 14:22:10 +0200 Subject: [PATCH 506/571] hotfix: revert value of 'rb_table_index' This reverts commit 7f24927c43a0b450d4f474b68520716dba58e3ef. With value 13 uplink TDD for a 10MHz configuration was not working. UDP traffic sent with: "iperf -c XX -u -b10M" was crashing the eNB. --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 585d9c2c1c..6d0044b346 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -885,7 +885,7 @@ abort(); rb_table_index=UE_template->pre_allocated_rb_table_index_ul; } else { mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index=13; // for PHR + rb_table_index=5; // for PHR } UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; From 8f75878544dfa92ffaebae5c1a80dfd421922fa7 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 4 Apr 2017 10:29:21 +0200 Subject: [PATCH 507/571] Correction for dlsch dual buffer --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 14 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 3 +- openair1/PHY/TOOLS/lte_phy_scope.c | 16 +- openair1/PHY/TOOLS/lte_phy_scope_tm4.c | 28 +- openair1/SCHED/defs.h | 6 + openair1/SCHED/phy_procedures_lte_common.c | 45 ++- openair1/SCHED/phy_procedures_lte_ue.c | 108 +++--- openair1/SCHED/pucch_pc.c | 11 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 38 +- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 324 +++++++++--------- openair1/SIMULATION/LTE_PHY/dlsim_tm7.c | 108 +++--- openair1/SIMULATION/LTE_PHY/ulsim.c | 8 +- 13 files changed, 376 insertions(+), 337 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 6c0c4ff94c..af0b892669 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -7209,7 +7209,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, uint8_t transmission_mode = ue->transmission_mode[eNB_id]; ANFBmode_t AckNackFBMode; LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe&0x1][0]; + LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][0]; PHY_MEASUREMENTS *meas = &ue->measurements; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; // uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; @@ -8015,7 +8015,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, if (frame_parms->frame_type == FDD) { int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); - if (ue->dlsch[dl_subframe&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission + if (ue->dlsch[subframe_DL(&ue->frame_parms,dl_subframe)&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission ulsch->harq_processes[harq_pid]->O_ACK = 1; } else { ulsch->harq_processes[harq_pid]->O_ACK = 0; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 9f8ee6cec7..112eaf17da 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -641,8 +641,8 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, frame_rx_prev = frame_rx_prev%1024; if (err_flag == 1) { - LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, round %d, subframe %d)\n", - phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->round, subframe); + LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, round %d, TBS %d, mcs %d)\n", + phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->round,harq_process->TBS,harq_process->mcs); dlsch->harq_ack[subframe].ack = 0; dlsch->harq_ack[subframe].harq_id = harq_pid; @@ -670,8 +670,8 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, dlsch->harq_ack[subframe].ack = 1; dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].send_harq_status = 1; - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, pid status %d, round %d, subframe %d)\n", - phy_vars_ue->Mod_id, frame_rx_prev, subframe_rx_prev, harq_pid, harq_process->status, harq_process->round, subframe); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, pid status %d, round %d, , TBS %d, mcs %d)\n", + phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); if(is_crnti) { @@ -926,7 +926,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; case PDSCH: // TB0 - dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]; + dlsch_ue = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]; harq_pid = dlsch_ue->current_harq_pid; ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[subframe & 0x1][(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]); DevAssert( ue_id != (uint32_t)-1 ); @@ -972,7 +972,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; case PDSCH1: { // TB1 - dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]; + dlsch_ue = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]; harq_pid = dlsch_ue->current_harq_pid; int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[subframe & 0x1][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] ); DevAssert( UE_id != -1 ); @@ -1026,7 +1026,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; default: - dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]; + dlsch_ue = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]; LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id); dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations; return(1+dlsch_ue->max_turbo_iterations); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index e7f98cea1a..9833a0c649 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -31,6 +31,7 @@ */ //#include "PHY/defs.h" #include "PHY/extern.h" +#include "SCHED/defs.h" #include "defs.h" #include "extern.h" #include "PHY/sse_intrin.h" @@ -145,7 +146,7 @@ int rx_pdsch(PHY_VARS_UE *ue, case PDSCH: pdsch_vars = ue->pdsch_vars[subframe&0x1]; - dlsch = ue->dlsch[subframe&0x1][eNB_id]; + dlsch = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id]; LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame,subframe,symbol,harq_pid, dlsch[0]->harq_processes[harq_pid]->status, diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index cea702ef78..5bf5cf20e0 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -514,16 +514,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { - harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; + mcs = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 - if(!phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { + if(!phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { // we are in TM5 fl_show_object(form->button_0); } @@ -534,12 +534,12 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { + if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { coded_bits_per_codeword = get_G(frame_parms, - phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs), - phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index 92a0d9f218..322f8e02c7 100755 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -448,11 +448,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int mcs1=0; unsigned char harq_pid = 0; int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { - harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs0 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; + mcs0 = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 /* if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { @@ -461,23 +461,23 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } */ } - if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) { - harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid; if (harq_pid>=8) return; - mcs1 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs; + mcs1 = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs; } if (phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]!=NULL) { num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols; } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { + if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { mod0 = get_Qm(mcs0); coded_bits_per_codeword0 = get_G(frame_parms, - phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs0), - phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, @@ -486,13 +486,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); mod0=0; } - if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) { + if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]!=NULL) { mod1 = get_Qm(mcs1); coded_bits_per_codeword1 = get_G(frame_parms, - phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs1), - phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index a6223bef5b..e268cdcf00 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -212,6 +212,12 @@ void prach_procedures(PHY_VARS_eNB *eNB); lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); +/*! + * \brief Function that return the DL SFN, used for TDD where the DL is not always 4 SFN before UL +*/ + +uint8_t subframe_DL(LTE_DL_FRAME_PARMS *frame_parms,uint8_t current_sfn); + /*! \brief Function to compute which type of DCIs to detect in the given subframe @param frame_parms Pointer to DL frame parameter descriptor @param subframe Subframe index diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index e5753483da..c247d57da2 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -374,19 +374,19 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, } // report ACK/NACK status - o_ACK[0] = 1; + o_ACK[cw_idx] = 1; status = 0; if ((subframe_dl0 < 10) && (harq_ack[subframe_dl0].send_harq_status)) { - o_ACK[0] &= harq_ack[subframe_dl0].ack; + o_ACK[cw_idx] &= harq_ack[subframe_dl0].ack; status = harq_ack[subframe_dl0].send_harq_status; } if ((subframe_dl1 < 10) && (harq_ack[subframe_dl1].send_harq_status)) { - o_ACK[0] &= harq_ack[subframe_dl1].ack; + o_ACK[cw_idx] &= harq_ack[subframe_dl1].ack; status = harq_ack[subframe_dl1].send_harq_status; } // report status = Nbundled if (!status) { - o_ACK[0] = 0; + o_ACK[cw_idx] = 0; } else { if (harq_ack[subframe_ul].vDAI_UL < 0xff) { status = harq_ack[subframe_ul].vDAI_UL; @@ -399,17 +399,17 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, subframe_dl0, harq_ack[subframe_dl0].ack, harq_ack[subframe_dl0].send_harq_status, harq_ack[subframe_dl0].vDAI_DL, subframe_dl1, harq_ack[subframe_dl1].ack, harq_ack[subframe_dl1].send_harq_status, harq_ack[subframe_dl1].vDAI_DL, - o_ACK[0], status); + o_ACK[cw_idx], status); } else if (subframe_dl0 < 10) { LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, subframe_dl0, harq_ack[subframe_dl0].ack, harq_ack[subframe_dl0].send_harq_status, harq_ack[subframe_dl0].vDAI_DL, - o_ACK[0], status); + o_ACK[cw_idx], status); }else if (subframe_dl1 < 10) { LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, subframe_dl1, harq_ack[subframe_dl1].ack, harq_ack[subframe_dl1].send_harq_status, harq_ack[subframe_dl1].vDAI_DL, - o_ACK[0], status); + o_ACK[cw_idx], status); } } @@ -604,6 +604,37 @@ lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub } } +uint8_t subframe_DL(LTE_DL_FRAME_PARMS *frame_parms,uint8_t current_sfn) +{ + + // if FDD return dummy value + if (frame_parms->frame_type == FDD) + return(current_sfn); + + switch (frame_parms->tdd_config) { + + case 1: + switch (current_sfn) { + case 3: + case 8: + return(current_sfn-3); + break; + + default: + return(current_sfn); + break; + } + + case 3: + return(current_sfn); + break; + + default: + AssertFatal(0,"TDD config %d not coded",frame_parms->tdd_config); + + } +} + dci_detect_mode_t dci_detect_mode_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { dci_detect_mode_t ret = 0; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 83eeee1f31..eeb3c92f35 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -91,10 +91,10 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; coded_bits_per_codeword = get_G(&ue->frame_parms, - ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm, - ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, + ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm, + ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols, proc->frame_rx, subframe, @@ -510,7 +510,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id uint8_t pucch_ack_payload[2]; if (get_ack(&ue->frame_parms, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx,pucch_ack_payload,0) > 0) { is_sr_an_subframe = 1; @@ -809,11 +809,11 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; // set ACK/NAK to values if not DTX - if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed - harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack; + if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack1 = ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack; - if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].ack; + if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack0 = ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[5+last_dl].ack; if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed @@ -1319,11 +1319,11 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } ack_status_cw0 = reset_ack(&ue->frame_parms, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx, ue->ulsch[eNB_id]->o_ACK,0); ack_status_cw1 = reset_ack(&ue->frame_parms, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][1]->harq_ack, subframe_tx, ue->ulsch[eNB_id]->o_ACK,1); @@ -1345,14 +1345,14 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB if(ue->ulsch[eNB_id]->o_ACK[0]) { LOG_I(PHY,"PUSCH ACK\n"); - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); } else { LOG_I(PHY,"PUSCH NACK\n"); - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); } #endif @@ -1364,10 +1364,10 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } -#ifdef DEBUG_PHY_PROC - LOG_D(PHY, - "[UE %d][PUSCH %d] AbsSubframe %d.%d %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", - Mod_id,harq_pid,frame_tx,subframe_tx,proc->subframe_rx, +//#ifdef DEBUG_PHY_PROC + LOG_I(PHY, + "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", + Mod_id,harq_pid,frame_tx%1024,subframe_tx, first_rb,nb_rb, ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs, @@ -1381,7 +1381,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, ue->ulsch[eNB_id]->bundling); -#endif +//#endif @@ -1525,7 +1525,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif - LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + LOG_I(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); start_meas(&ue->ulsch_modulation_stats); ulsch_modulation(ue->common_vars.txdataF, @@ -1665,7 +1665,7 @@ void get_pucch_param(PHY_VARS_UE *ue, { pucch_resource[0] = get_n1_pucch(ue, proc, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, eNB_id, ack_payload, SR); @@ -1782,13 +1782,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } ack_status_cw0 = get_ack(&ue->frame_parms, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx, pucch_ack_payload, 0); ack_status_cw1 = get_ack(&ue->frame_parms, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][1]->harq_ack, subframe_tx, pucch_ack_payload, 1); @@ -1862,13 +1862,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif if(format == pucch_format1) { LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, isShortenPucch, @@ -1878,9 +1878,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin else { if (SR_payload>0) { - LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", + LOG_I(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, (format == pucch_format1a? "1a": ( format == pucch_format1b? "1b" : "??")), @@ -1891,9 +1891,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin Po_PUCCH, tx_amp); } else { - LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, (format == pucch_format1a? "1a": ( format == pucch_format1b? "1b" : "??")), @@ -1908,13 +1908,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #if T_TRACER if(pucch_payload[0]) { - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); } else { - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); } #endif @@ -1967,12 +1967,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, n2_pucch, Po_PUCCH, @@ -1997,13 +1997,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin case pucch_format2a: LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n", Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); break; case pucch_format2b: LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n", Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); break; default: @@ -2145,9 +2145,9 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui } // reset DL ACK/NACK status - if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0] != NULL) + if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0] != NULL) reset_ack(&ue->frame_parms, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx, ue->ulsch[eNB_id]->o_ACK,0); @@ -2345,8 +2345,8 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id) emos_dump_UE.total_TBS_last = ue->total_TBS_last[eNB_id]; emos_dump_UE.bitrate = ue->bitrate[eNB_id]; emos_dump_UE.total_received_bits = ue->total_received_bits[eNB_id]; - emos_dump_UE.pmi_saved = ue->dlsch[subframe&0x1][eNB_id][0]->pmi_alloc; - emos_dump_UE.mcs = ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mcs; + emos_dump_UE.pmi_saved = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->pmi_alloc; + emos_dump_UE.mcs = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mcs; emos_dump_UE.use_ia_receiver = openair_daq_vars.use_ia_receiver; bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE)); @@ -2778,7 +2778,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (dci_alloc_rx[i].format == format2A) || (dci_alloc_rx[i].format == format2B)) { - ue->dlsch[subframe_rx&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH; + ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH; } ue->dlsch_received[eNB_id]++; @@ -2786,7 +2786,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format); dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_rx&0x1][eNB_id][0]->active); + LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active); #endif // we received a CRNTI, so we're in PUSCH @@ -3687,10 +3687,10 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // deactivate reception until we scan pdcch - if (ue->dlsch[subframe_rx&0x1][eNB_id][0]) - ue->dlsch[subframe_rx&0x1][eNB_id][0]->active = 0; - if (ue->dlsch[subframe_rx&0x1][eNB_id][1]) - ue->dlsch[subframe_rx&0x1][eNB_id][1]->active = 0; + if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]) + ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active = 0; + if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][1]) + ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][1]->active = 0; if (ue->dlsch_SI[eNB_id]) ue->dlsch_SI[eNB_id]->active = 0; @@ -3786,13 +3786,13 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin start_meas(&ue->generic_stat); // do procedures for C-RNTI - if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { + if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[subframe_rx&0x1][eNB_id][0], + ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0], NULL, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, ue->frame_parms.symbols_per_tti>>1, @@ -3893,14 +3893,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // do procedures for C-RNTI LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { + if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); start_meas(&ue->pdsch_procedures_stat); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[subframe_rx&0x1][eNB_id][0], + ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0], NULL, 1+(ue->frame_parms.symbols_per_tti>>1), ue->frame_parms.symbols_per_tti-1, @@ -3915,8 +3915,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin proc, eNB_id, PDSCH, - ue->dlsch[subframe_rx&0x1][eNB_id][0], - ue->dlsch[subframe_rx&0x1][eNB_id][1], + ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0], + ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][1], &ue->dlsch_errors[eNB_id], mode, abstraction_flag); diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c index ae83123862..3f7ec5bc34 100644 --- a/openair1/SCHED/pucch_pc.c +++ b/openair1/SCHED/pucch_pc.c @@ -31,6 +31,7 @@ */ #include "PHY/defs.h" +#include "SCHED/defs.h" #include "PHY/LTE_TRANSPORT/proto.h" #include "PHY/extern.h" @@ -51,7 +52,7 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u Po_PUCCH = get_PL(ue->Mod_id,ue->CC_id,eNB_id)+ ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+ - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch; + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch; switch (pucch_fmt) { case pucch_format1: @@ -90,19 +91,19 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u if (pucch_fmt!=pucch_format1) { LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch); + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch); } else { LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch); + ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch); } return(Po_PUCCH); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index b8e23f2d98..9b12c4b27a 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2105,14 +2105,14 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[subframe&0x1][0][i]) { + if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]->rnti = n_rnti; } UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); @@ -2500,7 +2500,7 @@ int main(int argc, char **argv) if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); phy_procedures_UE_RX(UE,proc,0,0,normal_txrx,no_relay,NULL); - if (UE->dlsch[subframe&0x1][0][0]->active == 0) { + if (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->active == 0) { //printf("DCI not received\n"); dci_errors[round]++; UE->dlsch_errors[0] = 1; @@ -2558,7 +2558,7 @@ int main(int argc, char **argv) //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid); write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); @@ -2576,13 +2576,13 @@ int main(int argc, char **argv) if (UE->dlsch_errors[0] == 0) { - avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt; + avg_iter += UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->last_iteration_cnt; iter_trials++; if (n_frames==1) printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; @@ -2590,25 +2590,25 @@ int main(int argc, char **argv) else { errs[round]++; - avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt-1; + avg_iter += UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->last_iteration_cnt-1; iter_trials++; if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); - for (s=0; sdlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) { - if (sdlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus; + for (s=0; sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->C; s++) { + if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0; idlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -2659,13 +2659,13 @@ int main(int argc, char **argv) } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid); //write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); //write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); //write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - //write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + //write_output("dlsch_w.m","w",UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); //pdcch_vars write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); @@ -2679,7 +2679,7 @@ int main(int argc, char **argv) // printf("round %d errors %d/%d\n",round,errs[round],trials); round++; - // UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++; + // UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round++; } if (xforms==1) { @@ -2869,7 +2869,7 @@ int main(int argc, char **argv) //rate*effective_rate, 100*effective_rate, //rate, - //rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + //rate*get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -2946,7 +2946,7 @@ int main(int argc, char **argv) printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -3235,7 +3235,7 @@ int main(int argc, char **argv) printf("eNB %d\n",i); free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); + free_ue_dlsch(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 57742c5e13..a09d71062a 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -981,15 +981,15 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[subframe&0x1][0][i]) { + if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]->rnti = n_rnti; } // structure for SIC at UE @@ -2137,8 +2137,8 @@ int main(int argc, char **argv) eNB2UE[0]->first_run = 1; - ret[0] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; - ret[1] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; + ret[0] = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations+1; + ret[1] = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations+1; resend_cw0_cw1=1; resend_cw1=0; @@ -2146,10 +2146,10 @@ int main(int argc, char **argv) TB1_active=1; while (((transmission_mode == 3 || transmission_mode == 4) && - ((round < num_rounds) && ((ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) || - (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) || + ((round < num_rounds) && ((ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) || + (ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)))) || ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && - (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) { + (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)))) { #ifdef DEBUG_HARQ printf("\n [DLSIM] On top round is %d\n", round); #endif @@ -2160,10 +2160,10 @@ int main(int argc, char **argv) //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); - /*if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) { + /*if (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) { round_trials[0][round]++; round_trials[1][round]++; - } else if ((ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) + } else if ((ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)) round_trials[1][round]++;*/ @@ -2626,7 +2626,7 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - UE->dlsch[subframe&0x1][0][1]->pmi_alloc, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->pmi_alloc, transmission_mode>=7?transmission_mode:0 ); break; @@ -2854,7 +2854,7 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - UE->dlsch[subframe&0x1][0][1]->pmi_alloc, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->pmi_alloc, transmission_mode>=7?transmission_mode:0 ); break; @@ -2985,7 +2985,7 @@ int main(int argc, char **argv) // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); - UE->dlsch[subframe&0x1][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); if (n_users>1) eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); /* @@ -3009,7 +3009,7 @@ int main(int argc, char **argv) printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); } else if (updated_csi == 0){ @@ -3022,7 +3022,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); } else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ @@ -3033,7 +3033,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); } } else if (updated_csi == 1){ @@ -3052,11 +3052,11 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I quantize from ENodeB 2\n"); #endif - UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); #ifdef DEBUG_HARQ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif - UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); } else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ #ifdef DEBUG_HARQ @@ -3072,11 +3072,11 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I quantize from ENodeB 2\n"); #endif - UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); #ifdef DEBUG_HARQ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif - UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); } } @@ -3525,10 +3525,10 @@ int main(int argc, char **argv) //printf("Generating dlsch parameters for RNTI %x\n",dci_alloc_rx[i].rnti); if (round == 0) { - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx=1; } if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) { - UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->first_tx=1; } if ((dci_alloc_rx[i].rnti == n_rnti) && @@ -3537,7 +3537,7 @@ int main(int argc, char **argv) dci_alloc_rx[i].dci_pdu, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3547,30 +3547,30 @@ int main(int argc, char **argv) UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0)==0)) { dump_dci(&UE->frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword[0]= get_G(&eNB->frame_parms, - UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, - UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), - UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, - UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->Nl, + UE->pdcch_vars[subframe_DL(&UE->frame_parms,subframe)&0x1][0]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); if (transmission_mode == 3 || transmission_mode == 4) { coded_bits_per_codeword[1]= get_G(&eNB->frame_parms, - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[subframe&0x1][1]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); } /* - rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); - rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs); + rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs); */ - printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); + printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->TBS); dlsch_active = 1; // what does it indicates??? } else { @@ -3594,8 +3594,8 @@ int main(int argc, char **argv) UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti; UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols; if (round == 0) { - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; - UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->first_tx=1; } switch (transmission_mode) { @@ -3606,7 +3606,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format1 : format1A, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3617,14 +3617,14 @@ int main(int argc, char **argv) break; case 3: - //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); + //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); generate_ue_dlsch_params_from_dci(0, subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2A : format1A, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3632,7 +3632,7 @@ int main(int argc, char **argv) P_RNTI, transmission_mode<7?0:transmission_mode, UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0); - //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); + //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); break; case 4: generate_ue_dlsch_params_from_dci(0, @@ -3640,7 +3640,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A,//format1A only for a codeblock - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3657,7 +3657,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu2_1E[0], C_RNTI, format1E_2A_M10PRB, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3673,13 +3673,13 @@ int main(int argc, char **argv) if (dlsch_active == 1) { if (TB0_active==1) - cur_harq_pid =UE->dlsch[subframe&0x1][0][0]->current_harq_pid; + cur_harq_pid =UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid; else - cur_harq_pid =UE->dlsch[subframe&0x1][0][1]->current_harq_pid; + cur_harq_pid =UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid; if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix /* if (transmission_mode == 5) { - if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && + if ((UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && (openair_daq_vars.use_ia_receiver ==1)) { rx_type = rx_IC_single_stream; } else { @@ -3701,7 +3701,7 @@ int main(int argc, char **argv) (m==UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols)?1:0, rx_type, i_mod, - UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1){ + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1){ dlsch_active = 0; break; } @@ -3788,7 +3788,7 @@ int main(int argc, char **argv) break; } - UE->dlsch[subframe&0x1][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[TB] = get_G(&eNB->frame_parms, eNB->dlsch[0][TB]->harq_processes[0]->nb_rb, eNB->dlsch[0][TB]->harq_processes[0]->rb_alloc, @@ -3798,12 +3798,12 @@ int main(int argc, char **argv) 0,subframe, transmission_mode>=7?transmission_mode:0); - UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; - UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs); if (n_frames==2) { printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB], - UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->TBS); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]); @@ -3812,7 +3812,7 @@ int main(int argc, char **argv) sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB); - write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); + write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); sprintf(fname,"dlsch_cw%d_e.m", TB); sprintf(vname,"dlschcw%d_e", TB); write_output(fname, vname,eNB->dlsch[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4); @@ -3820,7 +3820,7 @@ int main(int argc, char **argv) printf("trials=%d\n", trials); for (i=0;idlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword][i]<0)) { + if (eNB->dlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } @@ -3842,22 +3842,22 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, 0, - UE->dlsch[subframe&0x1][0][TB], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB], coded_bits_per_codeword[TB], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword], TB, subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); start_meas(&UE->dlsch_decoding_stats[subframe&0x1]); ret[TB] = dlsch_decoding(UE, - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword], &UE->frame_parms, - UE->dlsch[subframe&0x1][0][TB], - UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid], 0, subframe, - UE->dlsch[subframe&0x1][0][TB]->current_harq_pid, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]); #ifdef DEBUG_HARQ @@ -3865,11 +3865,11 @@ int main(int argc, char **argv) #endif //printf("retr cw 0 = %d\n", ret[0]); - //printf("current round = %d\n", UE->dlsch[subframe&0x1][0][cw_non_sic]->harq_processes[UE->dlsch[subframe&0x1][0][cw_non_sic]->current_harq_pid]->round); + //printf("current round = %d\n", UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw_non_sic]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw_non_sic]->current_harq_pid]->round); - if (ret[TB] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 + if (ret[TB] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 #ifdef DEBUG_HARQ printf("[DLSIM] TB%d is decoded\n", TB); #endif @@ -3880,33 +3880,33 @@ int main(int argc, char **argv) if (n_frames==2) { printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) { - if (sdlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->C;s++) { + if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i], - UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); } #endif } - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][TB]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][TB]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][TB]->current_harq_pid]->TBS; // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) - if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + if (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* - //for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { + //for (round = 0 ; round < UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { // we assume here that the second stream has a lower MCS and is thus more likely to be decoded // re-encoding of second stream - dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = LARGE_CDD; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; @@ -3920,14 +3920,14 @@ int main(int argc, char **argv) dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - UE->dlsch[subframe&0x1][eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; - UE->dlsch[subframe&0x1][eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; - UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->active = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->active; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->rnti = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->rnti; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; - dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b, + dlsch_encoding(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, - UE->dlsch[subframe&0x1][eNB_id], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id], 0,subframe, &UE->dlsch_rate_matching_stats, &UE->dlsch_turbo_encoding_stats, @@ -3935,10 +3935,10 @@ int main(int argc, char **argv) ); coded_bits_per_codeword = get_G(&UE->frame_parms, - UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->nb_rb, - UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->rb_alloc, - get_Qm(UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->mcs), - UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->Nl, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->nb_rb, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->mcs), + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->Nl, num_pdcch_symbols, 0,subframe); @@ -3946,7 +3946,7 @@ int main(int argc, char **argv) //scrambling dlsch_scrambling(&UE->frame_parms, 0, - UE->dlsch[subframe&0x1][eNB_id], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id], coded_bits_per_codeword, 0, subframe<<1); @@ -3958,7 +3958,7 @@ int main(int argc, char **argv) subframe, &UE->frame_parms, num_pdcch_symbols, - &UE->dlsch[subframe&0x1][0][0], + &UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0], NULL); // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding // precoding is contained in effective channel estimate @@ -3998,8 +3998,8 @@ int main(int argc, char **argv) } - if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && + if ((UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && (rx_type==rx_SIC_dual_stream)) { #ifdef DEBUG_HARQ printf("[DLSIM] Starting SIC procedure\n"); @@ -4018,10 +4018,10 @@ int main(int argc, char **argv) #endif //printf("I enter round_sic loop \n"); //printf("round_sic= %d\n", round_sic); - dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq->mimo_mode = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode; + dlsch0_eNB_harq->mimo_mode = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; @@ -4033,25 +4033,25 @@ int main(int argc, char **argv) dlsch0_eNB_harq->status = dlsch0_ue_harq->status; if (round_sic == 0){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 0; - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=0; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 0; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=0; } else if (round_sic == 1){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 1; - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=1; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 1; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=1; } else if (round_sic == 2){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 2; - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=2; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 2; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=2; } else{ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 3; - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=3; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 3; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=3; } - UE->dlsch_eNB[eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; - UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; - UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; + UE->dlsch_eNB[eNB_id]->active = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->active; + UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->rnti; + UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; dlsch_encoding_SIC(UE, input_buffer0[0], //UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,, @@ -4089,8 +4089,8 @@ int main(int argc, char **argv) coded_bits_per_codeword[0]); // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); - // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); - // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); switch (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){ @@ -4100,58 +4100,58 @@ int main(int argc, char **argv) case 2: dlsch_qpsk_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - UE->dlsch[subframe&0x1][eNB_id][0]); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]); break; case 4: dlsch_16qam_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs), - UE->dlsch[subframe&0x1][eNB_id][0]); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]); break; case 6: dlsch_64qam_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - UE->dlsch[subframe&0x1][eNB_id][TB]); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][TB]); break; } //}// rouns sic #ifdef DEBUG_HARQ - printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword); + printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword); #endif // write_output("rxdata_llr1.m","llr1", UE->pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); // replace cw_sic with TB+1 - UE->dlsch[subframe&0x1][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[1]= get_G(&eNB->frame_parms, eNB->dlsch[0][1]->harq_processes[0]->nb_rb, eNB->dlsch[0][1]->harq_processes[0]->rb_alloc, @@ -4162,12 +4162,12 @@ int main(int argc, char **argv) subframe, transmission_mode>=7?transmission_mode:0); - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs); if (n_frames==2) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1], - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->TBS); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]); @@ -4181,7 +4181,7 @@ int main(int argc, char **argv) uncoded_ber=0; printf("trials=%d\n", trials); for (i=0;idlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword][i]<0)) { + if (eNB->dlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } @@ -4203,7 +4203,7 @@ int main(int argc, char **argv) 0, UE->dlsch[subframe&0x1][0][1], coded_bits_per_codeword[1], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], 1, subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); @@ -4211,13 +4211,13 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_decoding_stats[subframe&0x1]); ret[1] = dlsch_decoding(UE, - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], &UE->frame_parms, - UE->dlsch[subframe&0x1][0][1], - UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid], 0, subframe, - UE->dlsch[subframe&0x1][0][1]->current_harq_pid, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]); @@ -4227,7 +4227,7 @@ int main(int argc, char **argv) //printf("ret TB 1 = %d round %d \n", ret[1], round); - if (ret[1] <=UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { + if (ret[1] <=UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations ) { decoded_in_sic[round]++; round_sic = round+1; // to exit round_sic #ifdef DEBUG_HARQ @@ -4241,19 +4241,19 @@ int main(int argc, char **argv) printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) { - if (sdlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->C;s++) { + if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i], - UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); } #endif } @@ -4261,7 +4261,7 @@ int main(int argc, char **argv) } //round_sic - if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ){ + if (ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations ){ errs[1][round]++; #ifdef DEBUG_HARQ printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]); @@ -4276,23 +4276,23 @@ int main(int argc, char **argv) //if ((n_frames==1) || (SNR>=30)) { printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) { - if (sdlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->C;s++) { + if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i], - UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); } #endif } //n_frames==1 // exit(0); - } //if (ret > UE->dlsch[subframe&0x1][0][1]->max_turbo_iterations ) + } //if (ret > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->max_turbo_iterations ) }//if SIC } else { @@ -4307,8 +4307,8 @@ int main(int argc, char **argv) iter_trials[0]++; }*/ - if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + if ((UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) { errs[1][round]++; #ifdef DEBUG_HARQ @@ -4327,18 +4327,18 @@ int main(int argc, char **argv) //if ((n_frames==1) || (SNR>=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) { - if (sdlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->C;s++) { + if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i], - UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); } #endif } @@ -4410,12 +4410,12 @@ int main(int argc, char **argv) UE->frame_parms.ofdm_symbol_size*nsymb,1,1); } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid); /* write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("dlsch_eNB_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - write_output("dlsch_UE_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + write_output("dlsch_UE_w.m","w",UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); */ //pdcch_vars @@ -4439,15 +4439,15 @@ int main(int argc, char **argv) printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]); #endif - if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)){ + if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)){ //printf("flag 1 \n"); round++; } if (transmission_mode == 3 || transmission_mode == 4 ) { - if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && - ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ + if (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations && + ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations){ resend_both[round]++; round++; resend_cw0_cw1=1; //resend both cws @@ -4455,8 +4455,8 @@ int main(int argc, char **argv) TB0_active=1; TB1_active=1; } - else if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && - ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ + else if (ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations && + ret[0] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations){ resend_one[round]++; resend_cw0_cw1=0; TB0_active=0; @@ -4476,8 +4476,8 @@ int main(int argc, char **argv) #endif round++; } - else if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && - ret[1] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ + else if (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations && + ret[1] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations){ resend_one[round]++; resend_cw0_cw1=0; TB0_active=1; @@ -4796,7 +4796,7 @@ int main(int argc, char **argv) rate[0]*effective_rate, 100*effective_rate, rate[0], - rate[0]*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + rate[0]*get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+ 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) @@ -4901,7 +4901,7 @@ int main(int argc, char **argv) printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -5326,7 +5326,7 @@ int main(int argc, char **argv) free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); + free_ue_dlsch(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 3055e99b07..4f461cee39 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -953,14 +953,14 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[subframe&0x1][0][i]) { + if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]->rnti = n_rnti; } // structure for SIC at UE @@ -2112,9 +2112,9 @@ int main(int argc, char **argv) //if (trials%100==0) eNB2UE[0]->first_run = 1; - ret = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; + ret = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations+1; - while ((round < num_rounds) && (ret > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) { + while ((round < num_rounds) && (ret > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)) { //printf("Trial %d, round %d\n",trials,round); round_trials[round]++; @@ -2601,7 +2601,7 @@ PMI_FEEDBACK: // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); if (n_users>1) eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); @@ -3227,7 +3227,7 @@ PMI_FEEDBACK: for (i=0; idlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->first_tx=1; + if (round == 0) UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->first_tx=1; if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, @@ -3235,7 +3235,7 @@ PMI_FEEDBACK: dci_alloc_rx[i].dci_pdu, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3244,23 +3244,23 @@ PMI_FEEDBACK: transmission_mode<7?0:transmission_mode))) { //dump_dci(&UE->frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword = get_G(&eNB->frame_parms, - UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, - UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), - UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[0]->num_pdcch_symbols, 0, subframe, (transmission_mode<7?0:transmission_mode)); /*if (transmission_mode==7 && common_flag==0) - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7; */ + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->mimo_mode = TM7; */ /* - rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); - rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs); + rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs); */ printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword, - UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->TBS); dlsch_active = 1; } else { @@ -3288,7 +3288,7 @@ PMI_FEEDBACK: UE->pdcch_vars[0]->crnti = n_rnti; UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; - if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; + if (round == 0) UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx=1; switch (transmission_mode) { case 1: @@ -3299,7 +3299,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format1 : format1A, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3307,24 +3307,24 @@ PMI_FEEDBACK: P_RNTI, transmission_mode<7?0:transmission_mode); /*if(transmission_mode==7 && common_flag==0) - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7;*/ + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->mimo_mode = TM7;*/ break; case 3: - // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); + // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); generate_ue_dlsch_params_from_dci(0, subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2A : format1A, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, 0, P_RNTI, 0); - // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); + // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); break; case 4: @@ -3333,7 +3333,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3349,7 +3349,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu2_1E[0], C_RNTI, format1E_2A_M10PRB, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3381,7 +3381,7 @@ PMI_FEEDBACK: if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix) if ((transmission_mode == 5) && - (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->dl_power_off==0) && + (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->dl_power_off==0) && (UE->use_ia_receiver ==1)) { dual_stream_UE = 1; } else { @@ -3404,7 +3404,7 @@ PMI_FEEDBACK: (m==UE->pdcch_vars[0]->num_pdcch_symbols)?1:0, dual_stream_UE, i_mod, - UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1) { dlsch_active = 0; break; } @@ -3430,7 +3430,7 @@ PMI_FEEDBACK: 0, dual_stream_UE, i_mod, - UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1) { dlsch_active=0; break; } @@ -3456,7 +3456,7 @@ PMI_FEEDBACK: 0, dual_stream_UE, i_mod, - UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1) { dlsch_active=0; break; } @@ -3534,7 +3534,7 @@ PMI_FEEDBACK: } for (int cw=Kmimo-1; cw>=0; cw--) { - UE->dlsch[subframe&0x1][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword = get_G(&eNB->frame_parms, eNB->dlsch[0][cw]->harq_processes[0]->nb_rb, eNB->dlsch[0][cw]->harq_processes[0]->rb_alloc, @@ -3545,7 +3545,7 @@ PMI_FEEDBACK: subframe, (transmission_mode<7?0:transmission_mode)); - UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid]->G = coded_bits_per_codeword; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->current_harq_pid]->G = coded_bits_per_codeword; @@ -3580,15 +3580,15 @@ PMI_FEEDBACK: ret = dlsch_decoding(UE, UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw], &UE->frame_parms, - UE->dlsch[subframe&0x1][0][cw], - UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->current_harq_pid], subframe, - UE->dlsch[subframe&0x1][0][cw]->current_harq_pid, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats); if (cw==1) { - if (ret <= UE->dlsch[subframe&0x1][0][cw]->max_turbo_iterations) { + if (ret <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->max_turbo_iterations) { } else { errs2[round]++; } @@ -3599,7 +3599,7 @@ PMI_FEEDBACK: stop_meas(&UE->phy_proc_rx[subframe&0x1]); - if (ret <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) { + if (ret <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) { avg_iter += ret; iter_trials++; @@ -3607,15 +3607,15 @@ PMI_FEEDBACK: if (n_frames==1) printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; - if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + if (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* - for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { + for (round = 0 ; round < UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { // re-encoding of first stream - dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = LARGE_CDD; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; @@ -3627,13 +3627,13 @@ PMI_FEEDBACK: dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - UE->dlsch[subframe&0x1][eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; - UE->dlsch[subframe&0x1][eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->active = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->active; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->rnti = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->rnti; - dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b, + dlsch_encoding(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, - UE->dlsch[subframe&0x1][0], + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], 0,subframe, &UE->dlsch_rate_matching_stats, &UE->dlsch_turbo_encoding_stats, @@ -3660,18 +3660,18 @@ PMI_FEEDBACK: //if ((n_frames==1) || (SNR>=30)) printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); - for (s=0; sdlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) { - if (sdlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus; + for (s=0; sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->C; s++) { + if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0; idlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -3726,7 +3726,7 @@ PMI_FEEDBACK: write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + write_output("dlsch_w.m","w",UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); */ if (round == 3) exit(-1); @@ -3735,7 +3735,7 @@ PMI_FEEDBACK: // printf("round %d errors %d/%d\n",round,errs[round],trials); round++; - // UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++; + // UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round++; } if (xforms==1) { @@ -3925,7 +3925,7 @@ PMI_FEEDBACK: rate*effective_rate, 100*effective_rate, rate, - rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + rate*get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -4001,7 +4001,7 @@ PMI_FEEDBACK: printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -4290,7 +4290,7 @@ PMI_FEEDBACK: printf("eNB %d\n",i); free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); + free_ue_dlsch(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index f3abbb7e3d..8fe055a309 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -709,20 +709,20 @@ int main(int argc, char **argv) // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms); - UE->dlsch[subframe&1][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); if (!eNB->dlsch[0][i]) { printf("Can't get eNB dlsch structures\n"); exit(-1); } - if (!UE->dlsch[subframe&1][0][i]) { + if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } eNB->dlsch[0][i]->rnti = 14; - UE->dlsch[subframe&1][0][i]->rnti = 14; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][i]->rnti = 14; } @@ -763,7 +763,7 @@ int main(int argc, char **argv) init_ul_hopping(&eNB->frame_parms); - UE->dlsch[subframe&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; From 01b110128871d968675f37214909bca197616a4f Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Sat, 8 Apr 2017 17:20:32 +0200 Subject: [PATCH 508/571] update readme files --- openair1/PHY/INIT/README.txt | 4 ++- openair1/README.TXT | 59 ++++++------------------------------ 2 files changed, 12 insertions(+), 51 deletions(-) diff --git a/openair1/PHY/INIT/README.txt b/openair1/PHY/INIT/README.txt index d40d0feecd..520e0acd4f 100644 --- a/openair1/PHY/INIT/README.txt +++ b/openair1/PHY/INIT/README.txt @@ -2,4 +2,6 @@ This directory contains files related to initialization of variables/structures init_top.c : initialize top-level variables and signal buffers, FFT twiddle factors, etc. lte_init.c : LTE specific initlization routines (DLSCH/ULSCH signal buffers for RX, data buffers for TX, etc.) -init.c : non-LTE initialization routines (to be removed) +lte_param_init.c: used only in unitary simulations. initializes the global variables eNB and UE. +lte_parms.c: contains init_frame_parms to initialize frame parameters structure + diff --git a/openair1/README.TXT b/openair1/README.TXT index 34d3144105..23c86e888e 100644 --- a/openair1/README.TXT +++ b/openair1/README.TXT @@ -1,40 +1,5 @@ This folder contains the software for the device driver of CBMIMO1 and the physical layer signal processing. - -|-- ARCH // contains drivers for hardware -| |-- CBMIMO1 // contains everything related to CBMIMO1 -| | `-- DEVICE_DRIVER -| | |-- Makefile // main Makefile used to compile the driver; usually invoked from the top level Makefile -| | |-- cbmimo1_device.c // main file for device driver (initializes the card, bigphys, main variables) -| | |-- cbmimo1_device.h -| | |-- cbmimo1_dma.c -| | |-- cbmimo1_fileops.c // file that processes IOCTL commands coming from the userspace control utility (USERSPACE_TOOLS/OPENAIR_RF/) -| | |-- cbmimo1_generate_fs4.c // generates test signals (DEBUGGING) -| | |-- cbmimo1_generate_ofdm.c // generates test signals (DEBUGGING) -| | |-- cbmimo1_get_frame.c // code to grab a frame from the card -| | |-- cbmimo1_init.c // code to set up the registers of the card -| | |-- cbmimo1_pci.h -| | |-- cbmimo1_proc.c // generates the proc entries /proc/openair1/bch_stats and /proc/openair1/openair1_state -| | |-- cbmimo1_rf_cntl.c // controls the RF chipset on the card -| | |-- cbmimo1_test.c -| | |-- from_grlib_softconfig.h -| | |-- from_grlib_softregs.h -| | |-- defs.h -| | |-- extern.h -| | `-- vars.h -| |-- COMMON // common for all hardware (mainly bigphys) -| |-- EXPRESS_MIMO // contains everything related to EXPRESS MIMO -|-- DOCS // Documentation -| |-- DOXYGEN // Automaitcally generated DOXYGEN documentation in latex and html -| `-- PAPERS // papers related to openair1 -|-- EMOS // this contains everything related to Eurecom MIMO Openair Sounder (EMOS) -| |-- DOC -| |-- DUMP // program that dumps channel estimate to disk using a FIFO -| |-- GUI -| |-- MATLAB // Matlab code to process measurements -| |-- SIM // EMOS simulator (for DEBUGGING) -| `-- UTIL -|-- MAC_INTERFACE // interface with MAC layer (in openair2) |-- PHY // contains all signal processing related to physical layer (used in real-time AND simulation) General remarks: every directory contains at least defs.h (for declaration of structure and functions), vars.h (for definitions of variables), and extern.h (variables are defined only once in cbmimo1_device.c (for real-time HW operation) or a top-level simulation (in SIMULATION/xxx), if variables are needed in another file, use extern.h) @@ -57,17 +22,19 @@ General remarks: every directory contains at least defs.h (for declaration of st | |-- spec_defs_top.h | |-- types.h | `-- vars.h -|-- SCHED // schedules the different PHY functions according to the nodes role (CH=BS, MR=UE) +|-- SCHED // schedules the different PHY functions according to the nodes role | |-- defs.h | |-- extern.h -| |-- phy_procedures.c // non-LTE PHY procedures this is used in synchronized mode to schedule the slot processing | |-- phy_procedures_emos.c // non-LTE PHY procedures for EMOS | |-- phy_procedures_emos.h | |-- phy_procedures_lte_eNb.c // LTE PHY procedures for eNB (from 36-213) | |-- phy_procedures_lte_ue.c // LTE PHY procedures for UE (from 36-213) +| |-- phy_procedures_lte_common.c // LTE PHY procedures common for UE and eNB (from 36-213) +| |-- phy_mac_stub.c //MAC stub that generates channels when used in phy-test-mode +| |-- pucch_pc.c // power control for PUCCH +| |-- pusch_pc.c // power control for PUSCH +| |-- srs_pc.c // power control for SRS | |-- rt_compat.h -| |-- sched.c // contains the top level scheduler (only for CBMIMO1 HW) -| |-- sched_lte.c // same as sched.c for LTE (only for CBMIMO1 HW) | `-- vars.h |-- SIMULATION // contains simulation routines to test PHY | |-- LTE_PHY // LTE simulation testbenches for unitary simulation of transport/physical channels @@ -76,17 +43,9 @@ General remarks: every directory contains at least defs.h (for declaration of st | | |-- dlsim.c // PDSCH simulation testbench | | |-- ulsim.c // PUSCH simulation testbench | | |-- pucchsim.c // PUCCH simulation testbench -| |-- LTE_PHY_L2 // LTE simulation testbench for full system simulation (PHY,MAC,RLC,RRC,PDCP) -| `-- TOOLS | |-- RF -|-- USERSPACE_TOOLS // tools that run in userspace (not kernel) -| |-- OCTAVE -| | |-- AGILE_RF_TOOLS // octave tools to test agile RF -| | |-- CBMIMO1_TOOLS // octave interface for CBMIMO1 -| | |-- GPIB // octave tools to control signal generator (used for calibration) -| | `-- PHY_SIM // octave implementation of sync -| |-- OPENAIR_RF // tool to interface with the device driver using IOCTL -| |-- SCOPE // tool to visualize data from PHY (channel estimates, IQ plots, etc.). Communicates with kernel module using shared memory. -| `-- SENSING // tools related to sensing +| |-- ETH_TRANSPORT +| `-- TOOLS + From 10113a35177b039828c0d13d7d787245f1e056ba Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 10 Apr 2017 10:29:09 +0200 Subject: [PATCH 509/571] integration fix: change the way to print the version Using "system" to call "git log" is too error-prone. In the test setup, lte-softmodem was blocked because "git log" uses a pager ("less") and the pager was waiting for the user to press enter. We could pass "--no-pager" to "git log" but then what if someone runs the softmodem out of the source tree? cmake defines PACKAGE_VERSION, we can use that instead, as is done in openair-cn. --- targets/RT/USER/lte-softmodem.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index e09c32cde4..68fcbc49d5 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1388,11 +1388,6 @@ int main( int argc, char **argv ) { memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); - char command_line[500]; - sprintf(command_line,"git log -1"); - if (background_system(command_line) != 0) - printf("ERROR failed command '%s'", command_line); - set_latency_target(); // set default parameters @@ -1524,6 +1519,12 @@ int main( int argc, char **argv ) { check_clock(); +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#endif + + LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + // init the parameters for (CC_id=0; CC_id Date: Mon, 10 Apr 2017 17:30:43 +0200 Subject: [PATCH 510/571] minor: bad comparison it was: *num_li_pP >= RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU it should be: *num_li_pP > RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU --- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c index 4255464e3a..c00e87c4e0 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c @@ -183,7 +183,7 @@ int rlc_um_read_length_indicators(unsigned char**data_ppP, rlc_um_e_li_t* e_liP, // AssertFatal(*data_size_pP >= 0, "Invalid data_size!"); } - if (*num_li_pP >= RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU) { + if (*num_li_pP > RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU) { return -1; } } From 94f880ad23c8ac7e6650226fdf22088d7ffb18d8 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 10 Apr 2017 17:31:21 +0200 Subject: [PATCH 511/571] bugfix: increase RLC UM header size The constant RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU is set to 24. This is too low. Running a downlink TCP iperf with a 10MHz or 20MHz cell leads to lots of the following warning in the log: [RLC][W][SN 792] Bad RLC header! Discard this RLC PDU (size=618) The problem is that the uplink RLC PDU contains a lot of TCP ack. We can see much more than 24 of them. The RLC layer is not happy and discards the PDU. Putting 256 for RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU (arbitrarily chosen, big but not too big) solves the problem, at least for 10MHz. --- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h index 2d0a875edb..acd94fa205 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h @@ -53,7 +53,7 @@ // UM_Window_Size = 512 when a 10 bit SN is configured and UM_Window_Size = 0 // when the receiving UM RLC entity is configured for MCCH or MTCH. // li field (values shifted 1 bit left) -# define RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU 24 +# define RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU 256 //---------------------------------------------------------- // Events defined for state model of the acknowledged mode entity /** Internal event defined for state model of the RLC UM. */ From 965aa5e6ef80177f94eb15c3f86be16cb0639f09 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 11 Apr 2017 09:32:14 +0200 Subject: [PATCH 512/571] change value of RLC_AM_MAX_SDU_IN_PDU and RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU Fabrice Nabet (TCL) suggests the value 128 for both. See https://gitlab.eurecom.fr/oai/openairinterface5g/issues/234#note_3179 --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h | 2 +- openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h index 69429b84b8..12af0279a8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h @@ -63,7 +63,7 @@ # define RLC_AM_MIN_SEGMENT_SIZE_REQUEST 8 /** Max SDUs that can fit in a PDU. */ -# define RLC_AM_MAX_SDU_IN_PDU 32 +# define RLC_AM_MAX_SDU_IN_PDU 128 /** Max fragments for a SDU. */ # define RLC_AM_MAX_SDU_FRAGMENTS 32 diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h index acd94fa205..34d97de59d 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_constants.h @@ -53,7 +53,7 @@ // UM_Window_Size = 512 when a 10 bit SN is configured and UM_Window_Size = 0 // when the receiving UM RLC entity is configured for MCCH or MTCH. // li field (values shifted 1 bit left) -# define RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU 256 +# define RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU 128 //---------------------------------------------------------- // Events defined for state model of the acknowledged mode entity /** Internal event defined for state model of the RLC UM. */ From fd618f4357b65394914f58aa039ece8323d7eac5 Mon Sep 17 00:00:00 2001 From: GabrielCouturier Date: Tue, 11 Apr 2017 16:56:07 +0200 Subject: [PATCH 513/571] Fix eNB phy-test 20MHz DCI1 --- openair1/SCHED/phy_mac_stub.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c index 04a98f69c1..f750253c67 100644 --- a/openair1/SCHED/phy_mac_stub.c +++ b/openair1/SCHED/phy_mac_stub.c @@ -70,7 +70,7 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) uint32_t bcch_pdu; uint64_t dlsch_pdu; - LOG_I(PHY,"frame %d, subframe %d, transmission_mode %d\n",proc->frame_tx,proc->subframe_tx,transmission_mode); + LOG_D(PHY,"frame %d, subframe %d, transmission_mode %d\n",proc->frame_tx,proc->subframe_tx,transmission_mode); DCI_pdu->Num_common_dci = 0; DCI_pdu->Num_ue_spec_dci=0; @@ -380,25 +380,25 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) if (eNB->frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_20MHz_FDD_t; - ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc; //computeRIV(100,10,3); + harq_pid_value = ( ((proc->frame_tx * 10) + subframe) % 8 ); + + if (!(subframe&1)) // even subframe + dci_ndi_toggle_tmp = &(dci_ndi_toggle_even[harq_pid_value]); + else // odd subframe + dci_ndi_toggle_tmp = &(dci_ndi_toggle_odd[harq_pid_value]); + + ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rballoc = 0x1ffffff; //rballoc; //computeRIV(100,10,3); ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->TPC = 0; - ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->harq_pid = subframe % 5; + ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->harq_pid = harq_pid_value; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->mcs = eNB->target_ue_dl_mcs; - //((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((eNB->frame%1024)%28); - ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->ndi = subframe / 5; + ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->ndi = (*dci_ndi_toggle_tmp); ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rv = 0; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rah = 0; + (*dci_ndi_toggle_tmp) = ((*dci_ndi_toggle_tmp) + 1) & 1; + memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_20MHz_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 = subframe % 5; - ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = eNB->target_ue_dl_mcs; - //((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((eNB->frame%1024)%28); - ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = subframe/5; - ((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; From 2e8d01f36b7b1279b8f7b01e97afe17f5fd673ae Mon Sep 17 00:00:00 2001 From: tctalcatel Date: Wed, 12 Apr 2017 12:01:32 +0200 Subject: [PATCH 514/571] UE autotest 20 MHz --- .../autotests/testsuite_ue_noS1_TCL.xml | 3516 +++++++++++++++++ 1 file changed, 3516 insertions(+) create mode 100644 cmake_targets/autotests/testsuite_ue_noS1_TCL.xml diff --git a/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml b/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml new file mode 100644 index 0000000000..971819ade5 --- /dev/null +++ b/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml @@ -0,0 +1,3516 @@ + + +TCT-Labo1 TCT-Labo3 + /mnt/sradio/TEST_RESULTS/ + https://gitlab.eurecom.fr/oai/openairinterface5g.git + + + https://gitlab.eurecom.fr/oai/openair-cn.git --> + + eNB_phy-test_fix_20MHz + eNB_phy-test_fix_20MHz --> + + + + + + + + develop + oaisim oaisim_nos1 lte-softmodem lte-softmodem-nos1 mme_gw run_epc auth_request run_hss oai_hss mme spgw hss hss_sim configure_cots* wvdial iperf iperf_script iperf_script_phone ping tshark rrh_gw iperf3 iperf3_script iperf3_script_phone pppd + sudo -S -E /opt/ltebox/tools/stop_ltebox +$OPENAIR_DIR/cmake_targets/build_oai -w EXMIMO -c; sudo -S -E $OPENAIR_DIR/cmake_targets/tools/stop_exmimo2; sudo -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_bandrich_ue.py --reset-ue; sudo -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_huaweiE398_ue.py --reset-ue; sudo -E $OPENAIR_DIR/cmake_targets/autotests/tools/configure_cots_sony_experia_m4_ue.py --stop-ue; uname -a; sudo -E dmesg + 36000 + + + TCT-Labo3 + + + + + + + + + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 0 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS00 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 0 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS00 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 1 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS01 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 1 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS01 + 36 + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 9 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS09 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 9 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS09 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 16 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS16 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 16 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS16 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 10 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS10 + + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 10 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS10 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 17 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS17 + + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 17 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS17 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 18 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS18 + + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 18 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS18 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 19 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS19 + + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 19 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS19 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 20 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS20 + + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 20 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS20 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 21 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS21 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 21 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS21 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 22 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS22 + + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 22 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS22 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 23 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS23 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 23 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS23 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 24 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS24 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 24 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS24 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 25 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS25 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 25 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS25 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 26 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS26 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 26 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS26 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 27 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS27 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 27 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS27 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 28 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS28 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 3600 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 27 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_STAB.BAND7.5MHZ.MCS27 + 16 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 27 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_STAB.BAND7.5MHZ.MCS27 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + /targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf -W -m 27 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.10MHZ.MCS27 + 36 + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + /targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf -W -m 27 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.10MHZ.MCS27 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + /targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf -W -m 28 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + UE_USRP.NOS1.PHYTEST_PERF.BAND7.10MHZ.MCS28 + 36 + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + /targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf -W -m 19 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 0 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 --phy-test + + + + + + False + UE_UEDV1.NOS1.PHYTEST_PERF.BAND7.10MHZ.MCS19 + 36 + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + /targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf -W -m 28 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 30M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.10MHZ.MCS28 + 36 + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 0 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 512K + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 15 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 + + iperf -s -i 1 -u + + 200 + + False + UE_UEDV1.NOS1.DATA_IPERF.BAND7.5MHZ.MCS00 + 36 + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 9 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 15 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 + + iperf -s -i 1 -u + + 200 + + False + UE_UEDV1.NOS1.DATA_IPERF.BAND7.5MHZ.MCS09 + 36 + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 10 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 15 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 + + iperf -s -i 1 -u + + 200 + + False + UE_UEDV1.NOS1.DATA_IPERF.BAND7.5MHZ.MCS10 + 36 + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 16 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 15 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 + + iperf -s -i 1 -u + + 200 + + False + UE_UEDV1.NOS1.DATA_IPERF.BAND7.5MHZ.MCS16 + 36 + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 17 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 15 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 + + iperf -s -i 1 -u + + 200 + + False + UE_UEDV1.NOS1.DATA_IPERF.BAND7.5MHZ.MCS17 + 36 + + + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 19 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 10M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 15 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 + + iperf -s -i 1 -u + + 200 + + False + UE_UEDV1.NOS1.DATA_IPERF.BAND7.5MHZ.MCS19 + 36 + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 3600 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 27 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 2800 + + False + UE_USRP.NOS1.DATA_IPERF_STAB.BAND7.5MHZ.MCS27 + 16 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + ued-PRM-130 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 27 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w EXMIMO --noS1 --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C 2660000000 -r25 --ue-scan-carrier --ue-txgain 15 --ue-rxgain 5 -S -A 6 -F myriadRF_FMX --ue-max-power -25 + + iperf -s -i 1 -u + + 200 + + False + UE_UEDV1.NOS1.DATA_IPERF.BAND7.5MHZ.MCS27 + 36 + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 0 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 512K + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.5MHZ.MCS00 + 36 + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 9 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.5MHZ.MCS09 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 10 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.5MHZ.MCS10 + 36 + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 16 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.5MHZ.MCS16 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 17 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.5MHZ.MCS17 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 19 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.5MHZ.MCS19 + 36 + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 27 + sleep 30;iperf -c 10.0.1.9 -i 1 -u -b 15M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + UE_USRP.NOS1.DATA_IPERF.BAND7.5MHZ.MCS27 + 36 + + + + + + + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 28 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.5MHZ.MCS28 + 36 + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 18000 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 28 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_STAB.BAND7.5MHZ.MCS28 + 16 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 28 + sleep 30;iperf -c 10.0.1.9 -i 1 -u -b 13700K + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 200 + + False + + + + + UE_USRP.NOS1.DATA_IPERF_DL.BAND7.5MHZ.MCS28 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 3600 + UE_USRP.NOS1.DATA_IPERF_STAB_DL.BAND7.5MHZ.MCS28 + 16 + + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 28 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 -u + + 2800 + + False + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.conf -W -m 28 + sleep 30;iperf -c 10.0.1.9 -i 1 + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 + + 200 + + False + + + + + UE_USRP.NOS1.DATA_IPERF_TCP_DL.BAND7.5MHZ.MCS28 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + /targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf downlink_frequency 2660000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf -W -m 28 + sleep 80;iperf -c 10.0.1.9 -i 1 + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S + + iperf -s -i 1 + + 200 + + False + UE_USRP.NOS1.DATA_IPERF_TCP_DL.BAND7.10MHZ.MCS28 + 36 + + + + + + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 28 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.20MHZ.MCS28 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 0 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.20MHZ.MCS0 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 18 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.20MHZ.MCS18 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 700 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 0 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 + + iperf -s -i 1 -u + + 600 + + False + + + + UE_USRP.NOS1.DATA_IPERF_DL.BAND7.20MHZ.MCS0 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 700 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 18 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 24M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 + + iperf -s -i 1 -u + + 600 + + False + + + + UE_USRP.NOS1.DATA_IPERF_DL.BAND7.20MHZ.MCS18 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 700 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 28 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 55M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 + + iperf -s -i 1 -u + + 600 + + False + + + + UE_USRP.NOS1.DATA_IPERF_DL.BAND7.20MHZ.MCS28 + 36 + + + + + + + From 63b10db64556742a565027bd7c6ba48ff7385504 Mon Sep 17 00:00:00 2001 From: Yoshi Date: Wed, 12 Apr 2017 19:23:04 +0900 Subject: [PATCH 515/571] made generate_pucch3x and rx_pucch --- openair1/PHY/LTE_TRANSPORT/defs.h | 3 +- openair1/PHY/LTE_TRANSPORT/pucch.c | 1199 +++++++++++++++++++++++++++- 2 files changed, 1200 insertions(+), 2 deletions(-) mode change 100644 => 100755 openair1/PHY/LTE_TRANSPORT/pucch.c diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index f6293bf1b2..dced65fa2c 100755 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -777,7 +777,8 @@ typedef enum { pucch_format1b, pucch_format2, pucch_format2a, - pucch_format2b + pucch_format2b, + pucch_format3 // PUCCH format3 } PUCCH_FMT_t; diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c old mode 100644 new mode 100755 index 1efad912af..9f19f0a57e --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -115,6 +115,182 @@ int16_t W3_im[3][6] = {{0 ,0 ,0 }, char pucch_format_string[6][20] = {"format 1\0","format 1a\0","format 1b\0","format 2\0","format 2a\0","format 2b\0"}; +/* PUCCH format3 >> */ +#define D_I 0 +#define D_Q 1 +#define D_IQDATA 2 +#define D_NSLT1SF 2 +#define D_NSYM1SLT 7 +#define D_NSYM1SF 2*7 +#define D_NSC1RB 12 +#define D_NRB1PUCCH 2 +#define D_NPUCCH_SF5 5 +#define D_NPUCCH_SF4 4 + +uint8_t chcod_tbl[128][48] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1}, + {0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0}, + {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0}, + {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1}, + {1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1}, + {0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0}, + {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0}, + {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1}, + {1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1}, + {0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0}, + {0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, + {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1}, + {1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1}, + {0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0}, + {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1}, + {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0}, + {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0}, + {0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1}, + {0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1}, + {1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0}, + {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0}, + {0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1}, + {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1}, + {1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0}, + {1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0}, + {0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1}, + {0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1}, + {1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, + {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0}, + {0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0}, + {0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1}, + {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1}, + {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0}, + {1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0}, + {0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1}, + {0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1}, + {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0}, + {1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0}, + {0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1}, + {0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1}, + {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0}, + {1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0}, + {0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1}, + {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, + {1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}, + {1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1}, + {0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0}, + {0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0}, + {1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1}, + {1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1}, + {0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0}, + {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1}, + {1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1}, + {0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0}, + {0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1}, + {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1}, + {0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0}, + {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1}, + {1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0}, + {1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0}, + {0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1}, + {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0}, + {0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1}, + {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0}, + {1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0}, + {0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1}, + {0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1}, + {1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0}, + {1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0}, + {0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1}, + {0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0}, + {1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1}, + {1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1}, + {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0}, + {0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1}, + {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1}, + {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1}, + {1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1}, + {0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0}, + {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0}, + {1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1}, + {1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1}, + {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0}, + {1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1}, + {1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1}, + {0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, + {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0}, + {1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1}, + {1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1}, + {0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0}, + {1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1}, + {1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1}, + {0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0}, + {0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0}, + {1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1}, + {1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1}, + {0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1}, + {1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0}, + {1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1}, + {0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, + {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0}, + {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1}, + {0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, + {1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0}, + {1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0}, + {0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1}, + {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}, + {1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0}, + {1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0}, + {0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1} }; + +// W5_TBL +int16_t W5_fmt3_re[5][5] = { {32767, 32767, 32767, 32767, 32767}, + {32767, 10125, -26509, -26509, 10125}, + {32767, -26509, 10125, 10125, -26509}, + {32767, -26509, 10125, 10125, -26509}, + {32767, 10125, -26509, -26509, 10125} }; + +int16_t W5_fmt3_im[5][5] = { {0, 0, 0, 0, 0}, + {0, 31163, 19259, -19259, -31163}, + {0, 19259, -31163, 31163, -19259}, + {0, -19259, 31163, -31163, 19259}, + {0, -31163, -19259, 19259, 31163} }; + +int16_t W4_fmt3[4][4] = { {32767, 32767, 32767, 32767}, + {32767, -32767, 32767, -32767}, + {32767, 32767, -32767, -32767}, + {32767, -32767, -32767, 32767} }; + +// W2 TBL +int16_t W2[2] = {32767, 32767}; + +// e^j*pai*floor (ncs_cell(ns,l)/64)/2 +int16_t RotTBL_re[4] = {32767, 0, -32767, 0}; +int16_t RotTBL_im[4] = {0, 32767, 0, -32767}; + +//np4_tbl, np5_tbl +uint8_t Np5_TBL[5] = {0, 3, 6, 8, 10}; +uint8_t Np4_TBL[4] = {0, 3, 6, 9}; + +// alpha_TBL +int16_t alphaTBL_re[12] = {32767, 28377, 16383, 0, -16383, -28377, -32767, -28377, -16383, 0, 16383, 28377}; +int16_t alphaTBL_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0, -16383, -28377, -32767, -28377, -16383}; + +/* PUCCH format3 << */ + void generate_pucch1x(int32_t **txdataF, LTE_DL_FRAME_PARMS *frame_parms, uint8_t ncs_cell[20][7], @@ -660,11 +836,928 @@ void generate_pucch2x(int32_t **txdataF, } } +/* PUCCH format3 >> */ +/* DFT */ +void pucchfmt3_Dft( int16_t *x, int16_t *y ) +{ + int16_t i, k; + int16_t tmp[2]; + int16_t calctmp[D_NSC1RB*2]={0}; + + for (i=0; i>15); + calctmp[2*i+1] += (((int32_t)x[2*k+1] * tmp[0] + (int32_t)x[2*k] * tmp[1])>>15); + } + y[2*i] = (int16_t)( (double) calctmp[2*i] / sqrt(D_NSC1RB)); + y[2*i+1] = (int16_t)((double) calctmp[2*i+1] / sqrt(D_NSC1RB)); + } +} + +void generate_pucch3x(int32_t **txdataF, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t ncs_cell[20][7], + PUCCH_FMT_t fmt, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint16_t n3_pucch, + uint8_t shortened_format, + uint8_t *payload, + int16_t amp, + uint8_t subframe, + uint16_t rnti) +{ + + uint32_t u, v, n; + uint16_t i, j, re_offset; + uint32_t z[12*14], *zptr; + uint32_t y_tilda[12*14]={}, *y_tilda_ptr; + uint8_t ns, nsymb, n_oc, n_oc0, n_oc1; + uint8_t N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6; + uint8_t m, l; + uint8_t n_cs; + int16_t tmp_re, tmp_im, W_re=0, W_im=0; + int32_t *txptr; + uint32_t symbol_offset; + + uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30; + uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30; + uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + + // variables for channel coding + uint8_t chcod_tbl_idx = 0; + uint8_t chcod_dt[48] = {}; + + // variables for Scrambling + uint32_t cinit = 0; + uint32_t x1; + uint32_t s,s0,s1; + uint8_t C[48] ={}; + uint8_t scr_dt[48]={}; + + // variables for Modulation + int16_t d_re[24]={}; + int16_t d_im[24]={}; + + // variables for orthogonal sequence selection + uint8_t N_PUCCH_SF0 = 5; + uint8_t N_PUCCH_SF1 = (shortened_format==0)? 5:4; + uint8_t first_slot = 0; + int16_t rot_re=0; + int16_t rot_im=0; + + uint8_t dt_offset; + uint8_t sym_offset; + int16_t y_re[14][12]={0}; + int16_t y_im[14][12]={0}; + + // DMRS + uint8_t alpha_idx=0; + uint8_t m_alpha_idx=0; + + // Channel Coding + for (uint8_t i=0; i<7; i++) { + chcod_tbl_idx += (payload[i]<Nid_cell + 1)<<16) + rnti; + s0 = lte_gold_generic(&x1,&cinit,1); + s1 = lte_gold_generic(&x1,&cinit,0); + + for (i=0; i<48; i++) { + s = (i<32)? s0:s1; + j = (i<32)? i:(i-32); + C[i] = ((s>>j)&1); + } + + for (i=0; i<48; i++) { + scr_dt[i] = chcod_tbl[chcod_tbl_idx][i] ^ C[i]; + } + + // Modulation + for (uint8_t i=0; i<48; i+=2){ + if (scr_dt[i]==0 && scr_dt[i+1]==0){ + d_re[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); + d_im[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); + } else if (scr_dt[i]==0 && scr_dt[i+1]==1) { + d_re[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp) >>15); + d_im[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp) >>15); + } else if (scr_dt[i]==1 && scr_dt[i+1]==0) { + d_re[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); + d_im[ i>>1] = ((ONE_OVER_SQRT2_Q15 * amp)>>15); + } else if (scr_dt[i]==1 && scr_dt[i+1]==1) { + d_re[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); + d_im[ i>>1] = -1 * ((ONE_OVER_SQRT2_Q15 * amp)>>15); + } else { + //***log Modulation Error! + } + } + + // Calculate Orthogonal Sequence index + n_oc0 = n3_pucch % N_PUCCH_SF1; + if (N_PUCCH_SF1 == 5) { + n_oc1 = (3 * n_oc0) % N_PUCCH_SF1; + } else { + n_oc1 = n_oc0 % N_PUCCH_SF1; + } + + y_tilda_ptr = y_tilda; + zptr = z; + + // loop over 2 slots + for (ns=(subframe<<1), u=u0, v=v0; ns<(2+(subframe<<1)); ns++, u=u1, v=v1) { + first_slot = (ns==(subframe<<1))?1:0; + + //loop over symbols in slot + for (l=0; l=2 && l<5) { // data + W_re=W4_fmt3[n_oc][l-1]; + W_im=0; + } else if (l==5) { // DMRS + W_re=W2[1]; + W_im=0; + } else if ((l>=N_UL_symb-2)) { // data + ; + } else { + //***log W Select Error! + } + } else { + if (first_slot == 1) { // 1st slot or 2nd slot and not shortened + n_oc=n_oc0; + } else { + n_oc=n_oc1; + } + + if (l<1) { // data + W_re=W5_fmt3_re[n_oc][l]; + W_im=W5_fmt3_im[n_oc][l]; + } else if (l==1) { // DMRS + W_re=W2[0]; + W_im=0; + } else if (l>=2 && l<5) { // data + W_re=W5_fmt3_re[n_oc][l-1]; + W_im=W5_fmt3_im[n_oc][l-1]; + } else if (l==5) { // DMRS + W_re=W2[1]; + W_im=0; + } else if ((l>=N_UL_symb-1)) { // data + W_re=W5_fmt3_re[n_oc][l-N_UL_symb+5]; + W_im=W5_fmt3_im[n_oc][l-N_UL_symb+5]; + } else { + //***log W Select Error! + } + } // W Selection end + + // Compute n_cs (36.211 p. 18) + n_cs = ncs_cell[ns][l]; + if (N_PUCCH_SF1 == 5) { + alpha_idx = (n_cs + Np5_TBL[n_oc]) % 12; + } else { + alpha_idx = (n_cs + Np4_TBL[n_oc]) % 12; + } + + // generate pucch data + dt_offset = (first_slot == 1) ? 0:12; + sym_offset = (first_slot == 1) ? 0:7; + + for (i=0; i<12; i++) { + // Calculate yn(i) + tmp_re = (((int32_t) (W_re*rot_re - W_im*rot_im)) >>15); + tmp_im = (((int32_t) (W_re*rot_im + W_im*rot_re)) >>15); + y_re[l+sym_offset][i] = (((int32_t) (tmp_re*d_re[i+dt_offset] - tmp_im*d_im[i+dt_offset]))>>15); + y_im[l+sym_offset][i] = (((int32_t) (tmp_re*d_im[i+dt_offset] + tmp_im*d_re[i+dt_offset]))>>15); + + // cyclic shift + ((int16_t *)&y_tilda_ptr[(l+sym_offset)*12+(i-(ncs_cell[ns][l]%12)+12)%12])[0] = y_re[l+sym_offset][i]; + ((int16_t *)&y_tilda_ptr[(l+sym_offset)*12+(i-(ncs_cell[ns][l]%12)+12)%12])[1] = y_im[l+sym_offset][i]; + + // DMRS + m_alpha_idx = (alpha_idx * i) % 12; + if (l==1 || l==5) { + ((int16_t *)&zptr[(l+sym_offset)*12+i])[0] =(((((int32_t) alphaTBL_re[m_alpha_idx]*ul_ref_sigs[u][v][0][i<<1] - (int32_t) alphaTBL_im[m_alpha_idx] * ul_ref_sigs[u][v][0][1+(i<<1)])>>15) * (int32_t)amp)>>15); + ((int16_t *)&zptr[(l+sym_offset)*12+i])[1] =(((((int32_t) alphaTBL_re[m_alpha_idx]*ul_ref_sigs[u][v][0][1+(i<<1)] + (int32_t) alphaTBL_im[m_alpha_idx] * ul_ref_sigs[u][v][0][i<<1])>>15) * (int32_t)amp)>>15); + } + } + + } // l loop + } // ns + + // DFT for pucch-data + for (l=0; l<14; l++) { + if (l==1 || l==5 || l==8 || l==12) { + ; + } else { + pucchfmt3_Dft((int16_t*)&y_tilda_ptr[l*12],(int16_t*)&zptr[l*12]); + } + } + + + // Mapping + m = n3_pucch / N_PUCCH_SF0; + + if (shortened_format == 1) { + nsymb = (N_UL_symb<<1) - 1; + } else { + nsymb = (N_UL_symb<<1); + } + + for (j=0,l=0; l<(nsymb); l++) { + + if ((l<7) && ((m&1) == 0)) + re_offset = (m*6) + frame_parms->first_carrier_offset; + else if ((l<7) && ((m&1) == 1)) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else if ((m&1) == 0) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else + re_offset = ((m-1)*6) + frame_parms->first_carrier_offset; + + if (re_offset > frame_parms->ofdm_symbol_size) + re_offset -= (frame_parms->ofdm_symbol_size); + + symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*(l+(subframe*14)); + txptr = &txdataF[0][symbol_offset]; + + for (i=0; i<12; i++,j++) { + txptr[re_offset++] = z[j]; + + if (re_offset==frame_parms->ofdm_symbol_size) + re_offset = 0; + +#ifdef DEBUG_PUCCH_TX + msg("[PHY] PUCCH subframe %d (%d,%d,%d,%d) => %d,%d\n",subframe,l,i,re_offset-1,m,((int16_t *)&z[j])[0],((int16_t *)&z[j])[1]); +#endif + } + } + +} + +/* PUCCH format3 << */ + //#define Amax 13 //void init_pucch2x_rx() {}; +/* PUCCH format3 >> */ +/* SubCarrier Demap */ +uint16_t pucchfmt3_subCarrierDeMapping( PHY_VARS_eNB *eNB, + int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2], + uint16_t n3_pucch ) +{ + LTE_eNB_COMMON *eNB_common_vars = &eNB->common_vars; + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + int16_t *rxptr; + uint8_t N_UL_symb = D_NSYM1SLT; // only Normal CP format + uint16_t m; // Mapping to physical resource blocks(m) + uint32_t aa; + uint16_t k, l; + uint32_t symbol_offset; + uint16_t carrier_offset; + + + m = n3_pucch / D_NPUCCH_SF5; + + // Do detection + for (aa=0; aanb_antennas_rx; aa++) { + + for (l=0; lfirst_carrier_offset; + else if ((lfirst_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else if ((m&1) == 0) + carrier_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else + carrier_offset = (((m-1)*6) + frame_parms->first_carrier_offset); + + if (carrier_offset > frame_parms->ofdm_symbol_size) + carrier_offset -= (frame_parms->ofdm_symbol_size); + + symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*l; + rxptr = (int16_t *)&eNB_common_vars->rxdataF[0][aa][symbol_offset]; + + for (k=0; k<12; k++,carrier_offset++) { + SubCarrierDeMapData[aa][l][k][0] = (int16_t)rxptr[carrier_offset<<1]; // DeMapping Data I + SubCarrierDeMapData[aa][l][k][1] = (int16_t)rxptr[1+(carrier_offset<<1)]; // DeMapping Date Q + + if (carrier_offset==frame_parms->ofdm_symbol_size) + carrier_offset = 0; + + #ifdef DEBUG_PUCCH_RX + LOG_D(PHY,"[eNB] PUCCH subframe %d (%d,%d,%d,%d) : (%d,%d)\n",subframe,l,k,carrier_offset,m, + SubCarrierDeMapData[aa][l][k][0],SubCarrierDeMapData[aa][l][k][1]); + #endif + } + } + } + return 0; +} + +/* cyclic shift hopping remove */ +uint16_t pucchfmt3_Baseseq_csh_remove( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2], + int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2], + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t subframe, + uint8_t ncs_cell[20][7] ) +{ + int16_t calctmp_baSeq[2]; + int16_t calctmp_beta[2]; + int16_t calctmp_alphak[2]; + int16_t calctmp_SCDeMapData_alphak[2]; + int32_t n_cell_cs_div64; + int32_t n_cell_cs_modNSC_RB; + + int32_t NSlot1subframe = D_NSLT1SF; + int32_t NSym1slot = D_NSYM1SLT; // Symbol per 1slot + int32_t NSym1subframe = D_NSYM1SF; // Symbol per 1subframe + int32_t aa, symNo, slotNo, sym, k, i; + + + for (aa=0; aanb_antennas_rx; aa++) { // Antenna + for (symNo=0; symNo>15); + calctmp_SCDeMapData_alphak[1] = (((int32_t)SubCarrierDeMapData[aa][symNo][k][1] * calctmp_alphak[0] - (int32_t)SubCarrierDeMapData[aa][symNo][k][0] * calctmp_alphak[1])>>15); + + // (e^(-alphar*k)*r_l,m,n,k) * e^(-beta) + CshData_fmt3[aa][symNo][k][0] = (((int32_t)calctmp_SCDeMapData_alphak[0] * calctmp_beta[0] + (int32_t)calctmp_SCDeMapData_alphak[1] * calctmp_beta[1])>>15); + CshData_fmt3[aa][symNo][k][1] = (((int32_t)calctmp_SCDeMapData_alphak[1] * calctmp_beta[0] - (int32_t)calctmp_SCDeMapData_alphak[0] * calctmp_beta[1])>>15); + } + } + } + return 0; +} + +#define MAXROW_TBL_SF5_OS_IDX (5) // Orthogonal sequence index +const int16_t TBL_3_SF5_GEN_N_DASH_NS[MAXROW_TBL_SF5_OS_IDX] = {0,3,6,8,10}; + +#define MAXROW_TBL_SF4_OS_IDX (4) // Orthogonal sequence index +const int16_t TBL_3_SF4_GEN_N_DASH_NS[MAXROW_TBL_SF4_OS_IDX] = {0,3,6,9}; + +/* Channel estimation */ +uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2], + double delta_theta[NB_ANTENNAS_RX][12], + int16_t ChestValue[NB_ANTENNAS_RX][2][12][2], + int16_t *Interpw, + uint8_t subframe, + uint8_t shortened_format, + LTE_DL_FRAME_PARMS *frame_parms, + uint16_t n3_pucch, + uint16_t n3_pucch_array[NUMBER_OF_UE_MAX], + uint8_t ncs_cell[20][7] ) +{ + uint32_t aa, symNo, k, rb, sltNo, ueNo, slotNo, sym, i, j; + int16_t np, np_n, ip_np, npucch_sf, ip_ind; + int16_t calctmp[2], calctmp_cs[2]; + int16_t BsCshData[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2]; + int16_t delta_theta_calctmp[NB_ANTENNAS_RX][4][D_NSC1RB][2], delta_theta_comp[NB_ANTENNAS_RX][D_NSC1RB][2]; + int16_t CsData_allavg[NB_ANTENNAS_RX][14][2]; + int16_t CsData_temp[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2]; + int32_t IP_CsData_allsfavg[NB_ANTENNAS_RX][14][4][2]; + int32_t IP_allavg[D_NPUCCH_SF5]; + int16_t temp_ch[2]; + int16_t m[NUMBER_OF_UE_MAX], m_self, same_m_number; + uint16_t n3_pucch_sameRB[NUMBER_OF_UE_MAX]; + int16_t n_oc0[NUMBER_OF_UE_MAX]; + int16_t n_oc1[NUMBER_OF_UE_MAX]; + int16_t np_n_array[2][NUMBER_OF_UE_MAX]; //Cyclic shift + uint8_t N_PUCCH_SF0 = 5; + uint8_t N_PUCCH_SF1 = (shortened_format==0)? 5:4; + + uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30; + uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30; + uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + + uint32_t u=u0; + uint32_t v=v0; + + double d_theta[32]={0.0}; + int32_t temp_theta[32][2]={0}; + + for (aa=0; aanb_antennas_rx; aa++) { + for (symNo=0; symNonb_antennas_rx; aa++) { + for (symNo=0; symNo>15); + BsCshData[aa][symNo][k][1] = (((int32_t)SubCarrierDeMapData[aa][symNo][k][1] * ul_ref_sigs[u][v][0][k<<1] - (int32_t)SubCarrierDeMapData[aa][symNo][k][0] * ul_ref_sigs[u][v][0][1+(k<<1)])>>15); + + if(shortened_format == 1) { + if (symNo < D_NSYM1SLT) { + np = n3_pucch % D_NPUCCH_SF4; // np = n_oc + np_n = TBL_3_SF4_GEN_N_DASH_NS[np]; // + } else { + np = n3_pucch % D_NPUCCH_SF4; // + np_n = TBL_3_SF4_GEN_N_DASH_NS[np]; // + } + npucch_sf = D_NPUCCH_SF4;// = 4 + } else { + if (symNo < D_NSYM1SLT) { + np = n3_pucch % D_NPUCCH_SF5; + np_n = TBL_3_SF5_GEN_N_DASH_NS[np]; + } else { + np = (3 * n3_pucch) % D_NPUCCH_SF5; + np_n = TBL_3_SF5_GEN_N_DASH_NS[np]; + } + npucch_sf = D_NPUCCH_SF5;// = 5 + } + // cyclic shift e^(-j * beta_n * k) + calctmp[0] = alphaTBL_re[(((ncs_cell[2*subframe+slotNo][sym] + np_n)%D_NSC1RB)*k)%12]; + calctmp[1] = alphaTBL_im[(((ncs_cell[2*subframe+slotNo][sym] + np_n)%D_NSC1RB)*k)%12]; + + // Channel Estimation 1A, g'(n_cs)_l,m,n + // CsData_temp = g_l,m,n,k + // remove cyclic shift BsCshData * e^(-j * beta_n * k) + CsData_temp[aa][symNo][k][0]=((((int32_t)BsCshData[aa][symNo][k][0] * calctmp[0] + (int32_t)BsCshData[aa][symNo][k][1] * calctmp[1])/ D_NSC1RB)>>15); + CsData_temp[aa][symNo][k][1]=((((int32_t)BsCshData[aa][symNo][k][1] * calctmp[0] - (int32_t)BsCshData[aa][symNo][k][0] * calctmp[1])/ D_NSC1RB)>>15); + + // Interference power for Channel Estimation 1A, No use Cyclic Shift g'(n_cs)_l,m,n + // Calculated by the cyclic shift that is not used S(ncs)_est + ip_ind = 0; + for(i=0; i>15); + IP_CsData_allsfavg[aa][symNo][ip_ind][1] += ((((int32_t)BsCshData[aa][symNo][k][1] * calctmp[0] - (int32_t)BsCshData[aa][symNo][k][0] * calctmp[1]))>>15); + if((symNo == 1 || symNo == 5 || symNo == 8 || symNo == 12)) { + } + ip_ind++; + } + } + } + } + if(symNo > D_NSYM1SLT-1) { + u=u1; + v=v1; + } + } + } + + for (aa=0; aanb_antennas_rx; aa++) { + for (symNo=0; symNonb_antennas_rx; aa++) { + for (k=0; k<12; k++) { + delta_theta_comp[aa][k][0] = 0; + delta_theta_comp[aa][k][1] = 0; + + delta_theta_comp[aa][k][0] += (((int32_t)CsData_temp[aa][1][k][0] * CsData_temp[aa][5][k][0] + (int32_t)((CsData_temp[aa][1][k][1])*CsData_temp[aa][5][k][1]))>>8); + delta_theta_comp[aa][k][1] += (((int32_t)CsData_temp[aa][1][k][0]*CsData_temp[aa][5][k][1] - (int32_t)((CsData_temp[aa][1][k][1])*CsData_temp[aa][5][k][0]) )>>8); + + delta_theta_comp[aa][k][0] += (((int32_t)CsData_temp[aa][8][k][0] * CsData_temp[aa][12][k][0] + (int32_t)((CsData_temp[aa][8][k][1])*CsData_temp[aa][12][k][1]))>>8); + delta_theta_comp[aa][k][1] += (((int32_t)CsData_temp[aa][8][k][0]*CsData_temp[aa][12][k][1] - (int32_t)((CsData_temp[aa][8][k][1])*CsData_temp[aa][12][k][0]))>>8); + + delta_theta[aa][k] = atan2((double)delta_theta_comp[aa][k][1], (double)delta_theta_comp[aa][k][0]) / 4.0; + } + } + + for (aa=0; aanb_antennas_rx; aa++) { + for (k=0; knb_antennas_rx; aa++) { + if(ip_ind == 0) {//ip_ind= The total number of cyclic shift of non-use + *Interpw = 1; + break; + } + for(i=0; i>8); + IP_allavg[i] += (((int32_t)IP_CsData_allsfavg[aa][5][i][0] * IP_CsData_allsfavg[aa][5][i][0] + (int32_t)IP_CsData_allsfavg[aa][5][i][1]*IP_CsData_allsfavg[aa][5][i][1])>>8); + IP_allavg[i] += (((int32_t)IP_CsData_allsfavg[aa][8][i][0] * IP_CsData_allsfavg[aa][8][i][0] + (int32_t)IP_CsData_allsfavg[aa][8][i][1]*IP_CsData_allsfavg[aa][8][i][1])>>8); + IP_allavg[i] += (((int32_t)IP_CsData_allsfavg[aa][12][i][0] * IP_CsData_allsfavg[aa][12][i][0] + (int32_t)IP_CsData_allsfavg[aa][12][i][1]*IP_CsData_allsfavg[aa][12][i][1])>>8); + *Interpw += IP_allavg[i]/(2*D_NSLT1SF*frame_parms->nb_antennas_rx*ip_ind*12); + } + } + return 0; +} + +/* Channel Equalization */ +uint16_t pucchfmt3_Equalization( int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2], + int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2], + int16_t ChestValue[NB_ANTENNAS_RX][2][12][2], + LTE_DL_FRAME_PARMS *frame_parms) +{ + int16_t ueNo, aa, sltNo, symNo, k; + + for (aa=0; aanb_antennas_rx; aa++) { + sltNo = 0; + for (symNo=0; symNo= D_NSYM1SLT) { + sltNo = 1; + } + for (k=0; k>8); + ChdetAfterValue_fmt3[aa][symNo][k][1] = (((int32_t)CshData_fmt3[aa][symNo][k][1] * ChestValue[aa][sltNo][k][0] - (int32_t)CshData_fmt3[aa][symNo][k][0] * ChestValue[aa][sltNo][k][1])>>8); + } + } + } + return 0; +} + +/* Frequency deviation remove AFC */ +uint16_t pucchfmt3_FrqDevRemove( int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2], + double delta_theta[NB_ANTENNAS_RX][12], + int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2], + LTE_DL_FRAME_PARMS *frame_parms ) +{ + int16_t ueNo, aa, sltNo, symNo1slt, k, n; + double calctmp[2]; + + for (aa=0; aanb_antennas_rx; aa++) { + for(sltNo = 0; sltNonb_antennas_rx; aa++) { + for (sltNo=0; sltNo>15); + Fmt3xDataRmvOrth[aa][sltNo][n][k][1] = (((int32_t)RemoveFrqDev_fmt3[aa][sltNo][n][k][1] * TBL_3_SF4[noc][n][0] - (int32_t)RemoveFrqDev_fmt3[aa][sltNo][n][k][0] * TBL_3_SF4[noc][n][1])>>15); + } else { + Fmt3xDataRmvOrth[aa][sltNo][n][k][0] = (((int32_t)RemoveFrqDev_fmt3[aa][sltNo][n][k][0] * TBL_3_SF5[noc][n][0] + (int32_t)RemoveFrqDev_fmt3[aa][sltNo][n][k][1] * TBL_3_SF5[noc][n][1])>>15); + Fmt3xDataRmvOrth[aa][sltNo][n][k][1] = (((int32_t)RemoveFrqDev_fmt3[aa][sltNo][n][k][1] * TBL_3_SF5[noc][n][0] - (int32_t)RemoveFrqDev_fmt3[aa][sltNo][n][k][0] * TBL_3_SF5[noc][n][1])>>15); + } + } + } + } + } + return 0; +} + +/* averaging antenna */ +uint16_t pucchfmt3_AvgAnt( int16_t Fmt3xDataRmvOrth[NB_ANTENNAS_RX][2][5][12][2], + int16_t Fmt3xDataAvgAnt[2][5][12][2], + uint8_t shortened_format, + LTE_DL_FRAME_PARMS *frame_parms ) +{ + int16_t aa, sltNo, symNo, n, k; + int16_t Npucch_sf; + + for (sltNo=0; sltNonb_antennas_rx; aa++) { + Fmt3xDataAvgAnt[sltNo][n][k][0] += Fmt3xDataRmvOrth[aa][sltNo][n][k][0] / frame_parms->nb_antennas_rx; + Fmt3xDataAvgAnt[sltNo][n][k][1] += Fmt3xDataRmvOrth[aa][sltNo][n][k][1] / frame_parms->nb_antennas_rx; + } + } + } + } + return 0; +} + +/* averaging symbol */ +uint16_t pucchfmt3_AvgSym( int16_t Fmt3xDataAvgAnt[2][5][12][2], + int16_t Fmt3xDataAvgSym[2][12][2], + uint8_t shortened_format ) +{ + int16_t sltNo, n, k; + int16_t Npucch_sf; + + for (sltNo=0; sltNo>15); + calctmp[2*k+1] += (((int32_t)x[2*i+1] * tmp[0] + (int32_t)x[2*i] * tmp[1])>>15); + } + y[2*k] = (int16_t)( (double) calctmp[2*k] / sqrt(D_NSC1RB)); + y[2*k+1] = (int16_t)((double) calctmp[2*k+1] / sqrt(D_NSC1RB)); + } +} + +/* descramble */ +uint16_t pucchfmt3_Descramble( int16_t IFFTOutData_Fmt3[2][12][2], + int16_t b[48], + uint8_t subframe, + uint32_t Nid_cell, + uint32_t rnti + ) +{ + int16_t m, k, c,i,j; + uint32_t cinit = 0; + uint32_t x1; + uint32_t s,s0,s1; + cinit = (subframe + 1) * ((2 * Nid_cell + 1)<<16) + rnti; + s0 = lte_gold_generic(&x1,&cinit,1); + s1 = lte_gold_generic(&x1,&cinit,0); + i=0; + for (m=0; m>j)&1); + b[i] = (IFFTOutData_Fmt3[m][k][0] * (1 - 2*c)); + i++; + + s = (i<32)? s0:s1; + j = (i<32)? i:(i-32); + c=((s>>j)&1); + b[i] = (IFFTOutData_Fmt3[m][k][1] * (1 - 2*c)); + i++; + } + } + return 0; +} + +int16_t pucchfmt3_Decode( int16_t b[48], + uint8_t subframe, + int16_t DTXthreshold, + int16_t Interpw, + uint8_t do_sr) +{ + int16_t c, i; + int32_t Rho_tmp; + int16_t c_max; + int32_t Rho_max; + int16_t bit_pattern; + + /* Is payload 6bit or 7bit? */ + if( do_sr == 1 ) { + bit_pattern = 128; + } else { + bit_pattern = 64; + } + + c=0; + Rho_tmp = 0; + for (i=0;i<48;i++) { + Rho_tmp += b[i] * (1-2*chcod_tbl[c][i]); + } + c_max = c; + Rho_max = Rho_tmp; + + for(c=1; c Rho_max) { + c_max = c; + Rho_max = Rho_tmp; + } + } + if(Interpw==0){ + Interpw=1; + } + if((Rho_max/Interpw) > DTXthreshold) { + // ***Log + return c_max; + } else { + // ***Log + return -1; + } +} + +/* PUCCH format3 << */ + uint32_t rx_pucch(PHY_VARS_eNB *eNB, PUCCH_FMT_t fmt, uint8_t UE_id, @@ -716,6 +1809,32 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; int chL; + /* PUCCH format3 >> */ + uint16_t Ret = 0; + int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] + int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] + double delta_theta[NB_ANTENNAS_RX][12]; //[Antenna][Subcarrier][Complex] + int16_t ChestValue[NB_ANTENNAS_RX][2][12][2]; //[Antenna][Slot][Subcarrier][Complex] + int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] + int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2]; //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex] + int16_t Fmt3xDataRmvOrth[NB_ANTENNAS_RX][2][5][12][2]; //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex] + int16_t Fmt3xDataAvgAnt[2][5][12][2]; //[Slot][PUCCH_Symbol][Subcarrier][Complex] + int16_t Fmt3xDataAvgSym[2][12][2]; //[Slot][Subcarrier][Complex] + int16_t IFFTOutData_Fmt3[2][12][2]; //[Slot][Subcarrier][Complex] + int16_t b[48]; //[bit] + int16_t IP_CsData_allavg[NB_ANTENNAS_RX][12][4][2]; //[Antenna][Symbol][Nouse Cyclic Shift][Complex] + int16_t payload_entity = -1; + int16_t DTXthreshold = 500; + int16_t Interpw; + int16_t payload_max; + + // TODO + // When using PUCCH format3, it must be an argument of rx_pucch function + uint16_t n3_pucch = 20; + uint16_t n3_pucch_array[NUMBER_OF_UE_MAX]; + uint8_t do_sr = 1; + /* PUCCH format3 << */ + if (first_call == 1) { for (i=0;i<10;i++) { for (j=0;j3)) { LOG_E(PHY,"[eNB] rx_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift); return(-1); @@ -1293,6 +2413,83 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, } else { LOG_E(PHY,"[eNB] PUCCH fmt2/2a/2b not supported\n"); } + + /* PUCCH format3 >> */ + } else { + /* SubCarrier Demap */ + Ret = pucchfmt3_subCarrierDeMapping( eNB, SubCarrierDeMapData, n3_pucch ); + if(Ret != 0) { + //***log pucchfmt3_subCarrierDeMapping Error! + return(-1); + } + + /* cyclic shift hopping remove */ + Ret = pucchfmt3_Baseseq_csh_remove( SubCarrierDeMapData, CshData_fmt3, frame_parms, subframe, eNB->ncs_cell ); + if(Ret != 0) { + //***log pucchfmt3_Baseseq_csh_remove Error! + return(-1); + } + + /* Channel Estimation */ + Ret = pucchfmt3_ChannelEstimation( SubCarrierDeMapData, delta_theta, ChestValue, &Interpw, subframe, shortened_format, frame_parms, n3_pucch, n3_pucch_array, eNB->ncs_cell ); + if(Ret != 0) { + //***log pucchfmt3_ChannelEstimation Error! + return(-1); + } + + /* Channel Equalization */ + Ret = pucchfmt3_Equalization( CshData_fmt3, ChdetAfterValue_fmt3, ChestValue, frame_parms ); + if(Ret != 0) { + //***log pucchfmt3_Equalization Error! + return(-1); + } + + /* Frequency deviation remove AFC */ + Ret = pucchfmt3_FrqDevRemove( ChdetAfterValue_fmt3, delta_theta, RemoveFrqDev_fmt3, frame_parms ); + if(Ret != 0) { + //***log pucchfmt3_FrqDevRemove Error! + return(-1); + } + + /* orthogonal sequence remove */ + Ret = pucchfmt3_OrthSeqRemove( RemoveFrqDev_fmt3, Fmt3xDataRmvOrth, shortened_format, n3_pucch, frame_parms ); + if(Ret != 0) { + //***log pucchfmt3_OrthSeqRemove Error! + return(-1); + } + + /* averaging antenna */ + pucchfmt3_AvgAnt( Fmt3xDataRmvOrth, Fmt3xDataAvgAnt, shortened_format, frame_parms ); + + /* averaging symbol */ + pucchfmt3_AvgSym( Fmt3xDataAvgAnt, Fmt3xDataAvgSym, shortened_format ); + + /* IDFT */ + pucchfmt3_IDft2( (int16_t*)Fmt3xDataAvgSym[0], (int16_t*)IFFTOutData_Fmt3[0] ); + pucchfmt3_IDft2( (int16_t*)Fmt3xDataAvgSym[1], (int16_t*)IFFTOutData_Fmt3[1] ); + + /* descramble */ + pucchfmt3_Descramble(IFFTOutData_Fmt3, b, subframe, frame_parms->Nid_cell, eNB->UE_stats[UE_id].crnti); + + /* Is payload 6bit or 7bit? */ + if( do_sr == 1 ) { + payload_max = 7; + } else { + payload_max = 6; + } + + /* decode */ + payload_entity = pucchfmt3_Decode( b, subframe, DTXthreshold, Interpw, do_sr ); + if (payload_entity == -1) { + //***log pucchfmt3_Decode Error! + return(-1); + } + + for(i=0; i>i) & 0x01); + } + } + /* PUCCH format3 << */ return((int32_t)stat_max); From 5498741f0b3b1ef522158caebe9da2031763d92a Mon Sep 17 00:00:00 2001 From: tctalcatel Date: Fri, 14 Apr 2017 09:03:12 +0200 Subject: [PATCH 516/571] Add 20 MHz test for the default XML file --- cmake_targets/autotests/testsuite_ue_noS1.xml | 310 ++++++++++++++++++ 1 file changed, 310 insertions(+) diff --git a/cmake_targets/autotests/testsuite_ue_noS1.xml b/cmake_targets/autotests/testsuite_ue_noS1.xml index c5403feab2..9cb5c20593 100644 --- a/cmake_targets/autotests/testsuite_ue_noS1.xml +++ b/cmake_targets/autotests/testsuite_ue_noS1.xml @@ -3208,6 +3208,316 @@ + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 28 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.20MHZ.MCS28 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 0 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.20MHZ.MCS0 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 300 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 18 --single-thread-disable --phy-test + + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test + + + + + + False + + + + UE_USRP.NOS1.PHYTEST_PERF.BAND7.20MHZ.MCS18 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 700 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 0 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 + + iperf -s -i 1 -u + + 600 + + False + + + + UE_USRP.NOS1.DATA_IPERF_DL.BAND7.20MHZ.MCS0 + 36 + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 700 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 18 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 24M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 + + iperf -s -i 1 -u + + 600 + + False + + + + UE_USRP.NOS1.DATA_IPERF_DL.BAND7.20MHZ.MCS18 + 36 + + + + + + lte-softmodem-noS1 + + TCT-Labo1 + TCT-Labo3 + 700 + /tmp + targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L + $OPENAIR_DIR/cmake_targets/build_oai + -c -w USRP --eNB --noS1 + source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB + + $OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 + -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 28 + sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 55M + + + + False + + /tmp + + $OPENAIR_DIR/cmake_targets/build_oai + -c --UE -w USRP --noS1 --eNB --ue-autotest-trace + source ./targets/bin/init_nas_nos1 UE + + sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 + + iperf -s -i 1 -u + + 600 + + False + + + + UE_USRP.NOS1.DATA_IPERF_DL.BAND7.20MHZ.MCS28 + 36 + + + From 58aa9f1f5237d3730d4a59f6e96c92d7c2f26888 Mon Sep 17 00:00:00 2001 From: tctalcatel Date: Fri, 14 Apr 2017 09:07:13 +0200 Subject: [PATCH 517/571] change eNB and UE name --- cmake_targets/autotests/testsuite_ue_noS1.xml | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cmake_targets/autotests/testsuite_ue_noS1.xml b/cmake_targets/autotests/testsuite_ue_noS1.xml index 9cb5c20593..f88244e7ef 100644 --- a/cmake_targets/autotests/testsuite_ue_noS1.xml +++ b/cmake_targets/autotests/testsuite_ue_noS1.xml @@ -3213,8 +3213,8 @@ lte-softmodem-noS1 - TCT-Labo1 - TCT-Labo3 + imb182-desktop + yanbo-M4HM87P-00 300 /tmp targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L @@ -3265,8 +3265,8 @@ lte-softmodem-noS1 - TCT-Labo1 - TCT-Labo3 + imb182-desktop + yanbo-M4HM87P-00 300 /tmp targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L @@ -3317,8 +3317,8 @@ lte-softmodem-noS1 - TCT-Labo1 - TCT-Labo3 + imb182-desktop + yanbo-M4HM87P-00 300 /tmp targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L @@ -3370,8 +3370,8 @@ lte-softmodem-noS1 - TCT-Labo1 - TCT-Labo3 + imb182-desktop + yanbo-M4HM87P-00 700 /tmp targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L @@ -3420,8 +3420,8 @@ lte-softmodem-noS1 - TCT-Labo1 - TCT-Labo3 + imb182-desktop + yanbo-M4HM87P-00 700 /tmp targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L @@ -3471,8 +3471,8 @@ lte-softmodem-noS1 - TCT-Labo1 - TCT-Labo3 + imb182-desktop + yanbo-M4HM87P-00 700 /tmp targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf downlink_frequency 2680000000L From 20a2bfd109029989e34e853c97cda719afa70c44 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 14 Apr 2017 18:17:13 +0200 Subject: [PATCH 518/571] hotfix: fix TDD 20MHz DCI0 structure In 20MHz the UE didn't do any uplink granted by DCI0. It was replying to RAR, so uplink decoding was okay. Turns out the DCI0 structure for TDD was wrong. --- openair1/PHY/LTE_TRANSPORT/dci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h index 2987f026e0..a9a5dda29e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.h +++ b/openair1/PHY/LTE_TRANSPORT/dci.h @@ -230,7 +230,7 @@ typedef struct DCI1A_10MHz_TDD_1_6 DCI1A_10MHz_TDD_1_6_t; /// DCI Format Type 0 (20 MHz,TDD1-6, 27 bits) struct DCI0_20MHz_TDD_1_6 { /// Padding - uint32_t padding:2; + uint32_t padding:3; /// CQI request uint32_t cqi_req:1; /// DAI From fc4d03d41983c1677465d640b746e93e83b856c6 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 18 Apr 2017 09:55:37 +0200 Subject: [PATCH 519/571] fix tm1 generic configuration file - RBs set to 25 - disable SRS --- .../CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf index 8db3e2304d..140d215b9c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf @@ -34,7 +34,7 @@ eNBs = downlink_frequency = 2680000000L; uplink_frequency_offset = -120000000; Nid_cell = 0; - N_RB_DL = 50; + N_RB_DL = 25; Nid_cell_mbsfn = 0; nb_antenna_ports = 1; nb_antennas_tx = 1; @@ -62,7 +62,7 @@ eNBs = pusch_nDMRS1 = 0; phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; - srs_enable = "ENABLE"; + srs_enable = "DISABLE"; srs_BandwidthConfig =2; srs_SubframeConfig =13; srs_ackNackST ="DISABLE"; From 8163d78ce3ac6d5a04b4d3231dbc00b894d5db27 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 18 Apr 2017 14:28:15 +0200 Subject: [PATCH 520/571] Remove some logs --- openair1/SCHED/phy_procedures_lte_ue.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index eeb3c92f35..5a73778199 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1365,7 +1365,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } //#ifdef DEBUG_PHY_PROC - LOG_I(PHY, + LOG_D(PHY, "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx, first_rb,nb_rb, @@ -1525,7 +1525,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); #endif - LOG_I(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); start_meas(&ue->ulsch_modulation_stats); ulsch_modulation(ue->common_vars.txdataF, @@ -1878,7 +1878,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin else { if (SR_payload>0) { - LOG_I(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", + LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, @@ -1891,7 +1891,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin Po_PUCCH, tx_amp); } else { - LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, @@ -1995,13 +1995,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin break; case pucch_format2a: - LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n", + LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); break; case pucch_format2b: - LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n", + LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); From 46da64063bdaaf1edc598f66dcb384f81a650c0d Mon Sep 17 00:00:00 2001 From: Yoshi Date: Fri, 21 Apr 2017 14:04:56 +0900 Subject: [PATCH 521/571] add comment --- openair1/PHY/LTE_TRANSPORT/pucch.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 9f19f0a57e..ab6cef6782 100755 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -1865,6 +1865,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, */ if(fmt!=pucch_format3) { /* PUCCH format3 */ + + // TODO + // "CQI/PMI/RI+ACK/NACK" will be supported in the future. if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) { LOG_E(PHY,"[eNB] rx_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift); From 7854030b90f4035fdefc6d595f9e08c10f76d9ab Mon Sep 17 00:00:00 2001 From: HARADA Masayuki Date: Mon, 24 Apr 2017 13:24:39 +0900 Subject: [PATCH 522/571] Add pucch format3 test to pucchsim --- openair1/PHY/LTE_TRANSPORT/proto.h | 11 +++++ openair1/PHY/LTE_TRANSPORT/pucch.c | 5 +- openair1/SIMULATION/LTE_PHY/pucchsim.c | 64 +++++++++++++++++++------- 3 files changed, 62 insertions(+), 18 deletions(-) mode change 100644 => 100755 openair1/PHY/LTE_TRANSPORT/proto.h mode change 100644 => 100755 openair1/SIMULATION/LTE_PHY/pucchsim.c diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h old mode 100644 new mode 100755 index 423d08c385..6d2603d904 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1998,6 +1998,17 @@ void generate_pucch2x(int32_t **txdataF, uint8_t subframe, uint16_t rnti); +void generate_pucch3x(int32_t **txdataF, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t ncs_cell[20][7], + PUCCH_FMT_t fmt, + PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, + uint16_t n3_pucch, + uint8_t shortened_format, + uint8_t *payload, + int16_t amp, + uint8_t subframe, + uint16_t rnti); void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue, UE_rxtx_proc_t *proc, diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index ab6cef6782..f22cb4b6ab 100755 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -1744,7 +1744,7 @@ int16_t pucchfmt3_Decode( int16_t b[48], Rho_max = Rho_tmp; } } - if(Interpw==0){ + if(Interpw<1){ Interpw=1; } if((Rho_max/Interpw) > DTXthreshold) { @@ -1833,6 +1833,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, uint16_t n3_pucch = 20; uint16_t n3_pucch_array[NUMBER_OF_UE_MAX]; uint8_t do_sr = 1; + uint16_t crnti=0x1234; /* PUCCH format3 << */ if (first_call == 1) { @@ -2472,7 +2473,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, pucchfmt3_IDft2( (int16_t*)Fmt3xDataAvgSym[1], (int16_t*)IFFTOutData_Fmt3[1] ); /* descramble */ - pucchfmt3_Descramble(IFFTOutData_Fmt3, b, subframe, frame_parms->Nid_cell, eNB->UE_stats[UE_id].crnti); + pucchfmt3_Descramble(IFFTOutData_Fmt3, b, subframe, frame_parms->Nid_cell, crnti); /* Is payload 6bit or 7bit? */ if( do_sr == 1 ) { diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c old mode 100644 new mode 100755 index d1db3c29e1..3869851f71 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -85,11 +85,13 @@ int main(int argc, char **argv) // double pucch_sinr; uint8_t osf=1,N_RB_DL=25; - uint32_t pucch_tx=0,pucch1_missed=0,pucch1_false=0,sig; + uint32_t pucch_tx=0,pucch1_missed=0,pucch1_false=0,pucch3_false=0,sig; PUCCH_FMT_t pucch_format = pucch_format1; PUCCH_CONFIG_DEDICATED pucch_config_dedicated; uint8_t subframe=0; uint8_t pucch_payload,pucch_payload_rx; + uint8_t pucch3_payload_size=7; + uint8_t pucch3_payload[21],pucch3_payload_rx[21]; double tx_gain=1.0; int32_t stat; double stat_no_sig,stat_sig; @@ -98,6 +100,9 @@ int main(int argc, char **argv) uint16_t n1_pucch = 0; uint16_t n2_pucch = 0; + uint16_t n3_pucch = 20; + + uint16_t n_rnti=0x1234; number_of_cards = 1; @@ -118,6 +123,8 @@ int main(int argc, char **argv) pucch_format = pucch_format1a; else if (atoi(optarg)==2) pucch_format = pucch_format1b; + else if (atoi(optarg)==6) // 3,4,5 is reserved for format2,2a,2b + pucch_format = pucch_format3; else { printf("Unsupported pucch_format %d\n",atoi(optarg)); exit(-1); @@ -282,7 +289,7 @@ int main(int argc, char **argv) printf("-N Noise variance in dB\n"); printf("-R N_RB_DL\n"); printf("-O oversampling factor (1,2,4,8,16)\n"); - printf("-f PUCCH format (0=1,1=1a,2=1b), formats 2/2a/2b not supported\n"); + printf("-f PUCCH format (0=1,1=1a,2=1b,6=3), formats 2/2a/2b not supported\n"); printf("-F Input filename (.txt format) for RX conformance testing\n"); exit (-1); break; @@ -362,18 +369,34 @@ int main(int argc, char **argv) UE->frame_parms.pucch_config_common.nRB_CQI = 4; UE->frame_parms.pucch_config_common.nCS_AN = 6; - pucch_payload = 0; - generate_pucch1x(UE->common_vars.txdataF, - frame_parms, - UE->ncs_cell, - pucch_format, - &pucch_config_dedicated, - n1_pucch, - 0, //shortened_format, - &pucch_payload, - AMP, //amp, - subframe); //subframe + if( (pucch_format == pucch_format1) || (pucch_format == pucch_format1a) || (pucch_format == pucch_format1b) ){ + pucch_payload = 0; + generate_pucch1x(UE->common_vars.txdataF, + frame_parms, + UE->ncs_cell, + pucch_format, + &pucch_config_dedicated, + n1_pucch, + 0, //shortened_format, + &pucch_payload, + AMP, //amp, + subframe); //subframe + }else if( pucch_format == pucch_format3){ + for(i=0;icommon_vars.txdataF, + frame_parms, + UE->ncs_cell, + pucch_format, + &pucch_config_dedicated, + n3_pucch, + 0, //shortened_format, + pucch3_payload, + AMP, //amp, + subframe, //subframe + n_rnti); //rnti + } write_output("txsigF0.m","txsF0", &UE->common_vars.txdataF[0][2*subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*nsymb,1,1); tx_lev = 0; @@ -429,6 +452,7 @@ int main(int argc, char **argv) pucch_tx = 0; pucch1_missed=0; pucch1_false=0; + pucch3_false=0; stat_no_sig = 0; stat_sig = 0; @@ -540,7 +564,7 @@ int main(int argc, char **argv) n1_pucch, n2_pucch, 0, //shortened_format, - &pucch_payload_rx, //payload, + (pucch_format==pucch_format3) ? pucch3_payload_rx : &pucch_payload_rx, //payload, 0 /* frame not defined, let's pass 0 */, subframe, pucch1_thres); @@ -561,8 +585,15 @@ int main(int argc, char **argv) printf("EXIT\n"); exit(-1); }*/ - } else { + } else if( (pucch_format==pucch_format1a) || (pucch_format==pucch_format1b) ) { pucch1_false = (pucch_payload_rx != pucch_payload) ? (pucch1_false+1) : pucch1_false; + } else if (pucch_format==pucch_format3){ + for(i=0;i Date: Mon, 24 Apr 2017 15:51:59 +0200 Subject: [PATCH 523/571] add logging trace --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 2 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 40 +++++++++++++--- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 47 ++++++++++--------- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 2 + openair1/PHY/LTE_TRANSPORT/lte_mcs.c | 4 +- openair1/SCHED/phy_procedures_lte_ue.c | 4 +- targets/RT/USER/lte-ue.c | 3 +- 7 files changed, 68 insertions(+), 34 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index af0b892669..eeaa76d685 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2982,7 +2982,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) break; case 25: - LOG_D(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", + LOG_I(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 112eaf17da..863f8c4994 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -461,11 +461,11 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, //#ifndef __AVX2__ #if 1 if (err_flag == 0) { - - LOG_D(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", - Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS, +/* + LOG_I(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", + Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations); - +*/ if (llr8_flag) { AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); @@ -641,8 +641,21 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, frame_rx_prev = frame_rx_prev%1024; if (err_flag == 1) { - LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, round %d, TBS %d, mcs %d)\n", - phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->round,harq_process->TBS,harq_process->mcs); + LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", + phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); + + + if(0){// (harq_process->nb_rb==25 && r==3 && harq_process->round==0 ) { + write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); + write_output("rxdataF0.m" , "rxdataF0", &phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); + write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp00.m","rxdataF_comp00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); + + AssertFatal (0,"number of soft bits %d nb_rb %d",G,frame_parms->N_RB_DL); + } + dlsch->harq_ack[subframe].ack = 0; dlsch->harq_ack[subframe].harq_id = harq_pid; @@ -665,12 +678,25 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, return((1+dlsch->max_turbo_iterations)); } else { + LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d harq_process->mcs %d harq_process->nb_rb %d\n", + phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); + + if (harq_process->nb_rb==25 && harq_process->mcs==28) { + write_output("decoder_llr_ok.m","decllr_ok",dlsch_llr,G,1,0); + write_output("rxdataF0_ok.m" , "rxdataF0_ok", &phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); + write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("rxdataF_comp00_ok.m","rxdataF_comp00_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("magDLFirst_ok.m", "magDLFirst_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); + write_output("magDLSecond_ok.m", "magDLSecond_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); + AssertFatal (0,"number of soft bits %d",G); + } + harq_process->status = SCH_IDLE; harq_process->round = 0; dlsch->harq_ack[subframe].ack = 1; dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].send_harq_status = 1; - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, pid status %d, round %d, , TBS %d, mcs %d)\n", + LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); if(is_crnti) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 9833a0c649..7e6685f114 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -257,12 +257,12 @@ int rx_pdsch(PHY_VARS_UE *ue, ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); -//#ifdef DEBUG_DLSCH_MOD - /* printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); +#ifdef DEBUG_DLSCH_MOD + printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); for (rb=0;rbpmi_ext[rb]); - printf("\n");*/ -//#endif + printf("\n"); +#endif if (rx_type >= rx_IC_single_stream) { if (eNB_id_in_connected_eNB) // we are in TM5 @@ -354,7 +354,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #ifdef DEBUG_PHY - LOG_D(PHY,"[DLSCH] log2_maxh = %d (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); + LOG_I(PHY,"[DLSCH] nb_rb %d log2_maxh = %d (%d,%d)\n",nb_rb,pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); #endif @@ -465,13 +465,14 @@ int rx_pdsch(PHY_VARS_UE *ue, avg, symbol, nb_rb); -#ifdef DEBUG_PHY - LOG_I(PHY,"[DLSCH] log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",pdsch_vars[eNB_id]->log2_maxh, +//#ifdef DEBUG_PHY + LOG_I(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", + frame%1024,subframe, pdsch_vars[eNB_id]->log2_maxh, pdsch_vars[eNB_id]->log2_maxh0, pdsch_vars[eNB_id]->log2_maxh1, avg[0],avgs); - LOG_I(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); -#endif + LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); +//#endif } #if T_TRACER @@ -745,6 +746,8 @@ int rx_pdsch(PHY_VARS_UE *ue, //i_mod should have been passed as a parameter } + //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol); + switch (dlsch0_harq->Qm) { case 2 : if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { @@ -910,6 +913,8 @@ int rx_pdsch(PHY_VARS_UE *ue, } break; case 6 : + printf("LLR rx_type %d cw0 %d cw1 %d symbol %d first symbol %d nb_rb %d rballoceven %d sfn %d beamforming_mode %d\n", + rx_type,codeword_TB0,codeword_TB1,symbol,first_symbol_flag,nb_rb,dlsch0_harq->rb_alloc_even,subframe,beamforming_mode); if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { dlsch_64qam_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, @@ -1046,15 +1051,15 @@ int rx_pdsch(PHY_VARS_UE *ue, // Please keep it: useful for debugging #if 0 - if( (symbol == 13) && (dlsch0_harq->mimo_mode == 2) ) + if( (symbol == 13) && (subframe==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/) { LOG_E(PHY,"Dump Phy Chan Est \n"); - if(subframe&0x1) + if(1) { #if 1 - //write_output("rxdataF0.m" , "rxdataF0", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); + write_output("rxdataF0.m" , "rxdataF0", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); //write_output("rxdataF1.m" , "rxdataF1", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); - //write_output("dl_ch_estimates00.m", "dl_ch_estimates00", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1); + write_output("dl_ch_estimates00.m", "dl_ch_estimates00", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1); //write_output("dl_ch_estimates01.m", "dl_ch_estimates01", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1); //write_output("dl_ch_estimates10.m", "dl_ch_estimates10", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1); //write_output("dl_ch_estimates11.m", "dl_ch_estimates11", &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1); @@ -1065,16 +1070,16 @@ int rx_pdsch(PHY_VARS_UE *ue, //write_output("rxdataF_ext10.m" , "rxdataF_ext10", &pdsch_vars[eNB_id]->rxdataF_ext[2][0],14*frame_parms->N_RB_DL*12,1,1); //write_output("rxdataF_ext11.m" , "rxdataF_ext11", &pdsch_vars[eNB_id]->rxdataF_ext[3][0],14*frame_parms->N_RB_DL*12,1,1); write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("dl_ch_estimates_ext01.m", "dl_ch_estimates_ext01", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[1][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("dl_ch_estimates_ext10.m", "dl_ch_estimates_ext10", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[2][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("dl_ch_estimates_ext11.m", "dl_ch_estimates_ext11", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[3][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("dl_ch_estimates_ext01.m", "dl_ch_estimates_ext01", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[1][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("dl_ch_estimates_ext10.m", "dl_ch_estimates_ext10", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[2][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("dl_ch_estimates_ext11.m", "dl_ch_estimates_ext11", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[3][0],14*frame_parms->N_RB_DL*12,1,1); write_output("rxdataF_comp00.m","rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp01.m","rxdataF_comp01", &pdsch_vars[eNB_id]->rxdataF_comp0[1][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp10.m","rxdataF_comp10", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp11.m","rxdataF_comp11", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("rxdataF_comp01.m","rxdataF_comp01", &pdsch_vars[eNB_id]->rxdataF_comp0[1][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("rxdataF_comp10.m","rxdataF_comp10", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("rxdataF_comp11.m","rxdataF_comp11", &pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][0],14*frame_parms->N_RB_DL*12,1,1); #endif write_output("llr0.m","llr0", &pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - write_output("llr1.m","llr1", &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + //write_output("llr1.m","llr1", &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); AssertFatal(0," "); @@ -3324,7 +3329,7 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); - LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); + LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index e2de78f9ca..2b0eba324b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -1092,6 +1092,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len2=len>>2; // length in quad words (4 REs) len2+=((len_mod4==0)?0:1); + printf("Sym %d llr Length %d %d\n", symbol,len,len2); + for (i=0; iNcp==NORMAL) ? 14 : 12; - // printf("adjust_G2 : symbol %d, subframe %d\n",symbol,subframe); + //printf("adjust_G2 : symbol %d, subframe %d\n",symbol,subframe); if ((subframe!=0) && (subframe!=5) && (subframe!=6)) // if not PBCH/SSS or SSS return(0); @@ -234,7 +234,7 @@ int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_ord } } - // printf("re_pbch_sss %d\n",re_pbch_sss); + //printf("re_pbch_sss %d\n",re_pbch_sss); return(re_pbch_sss); } diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 5a73778199..36477a110f 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -3678,8 +3678,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->frame_parms.samples_per_tti * 4)); // start timers - - LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + printf("\n"); + LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); start_meas(&ue->phy_proc_rx[subframe_rx&0x1]); start_meas(&ue->generic_stat); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index f07a0628f8..0747c82949 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -754,7 +754,8 @@ void *UE_thread(void *arg) { UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) UE->rx_offset_diff = 1; - LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); + LOG_I(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); + readBlockSize=UE->frame_parms.samples_per_tti - UE->frame_parms.ofdm_symbol_size - UE->frame_parms.nb_prefix_samples0 - From 655859b865b2423c0eea22731257fa9444cddcdc Mon Sep 17 00:00:00 2001 From: Yoshi Date: Tue, 25 Apr 2017 12:31:21 +0900 Subject: [PATCH 524/571] add comment --- openair1/PHY/LTE_TRANSPORT/pucch.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index f22cb4b6ab..618593326a 100755 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -918,6 +918,11 @@ void generate_pucch3x(int32_t **txdataF, uint8_t alpha_idx=0; uint8_t m_alpha_idx=0; + // TODO + // "SR+ACK/NACK" length is only 7 bits. + // This restriction will be lifted in the future. + // "CQI/PMI/RI+ACK/NACK" will be supported in the future. + // Channel Coding for (uint8_t i=0; i<7; i++) { chcod_tbl_idx += (payload[i]<3)) { From bdcc8ecf66c30aa06d7609eb062bdbe6dd474853 Mon Sep 17 00:00:00 2001 From: Yoshi Date: Tue, 25 Apr 2017 17:54:42 +0900 Subject: [PATCH 525/571] Adjust parameters --- openair1/PHY/LTE_TRANSPORT/pucch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 618593326a..9a03c52c90 100755 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -1829,16 +1829,17 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, int16_t b[48]; //[bit] int16_t IP_CsData_allavg[NB_ANTENNAS_RX][12][4][2]; //[Antenna][Symbol][Nouse Cyclic Shift][Complex] int16_t payload_entity = -1; - int16_t DTXthreshold = 500; int16_t Interpw; int16_t payload_max; // TODO // When using PUCCH format3, it must be an argument of rx_pucch function uint16_t n3_pucch = 20; - uint16_t n3_pucch_array[NUMBER_OF_UE_MAX]; + uint16_t n3_pucch_array[NUMBER_OF_UE_MAX]={1}; + n3_pucch_array[0]=n3_pucch; uint8_t do_sr = 1; uint16_t crnti=0x1234; + int16_t DTXthreshold = 10; /* PUCCH format3 << */ if (first_call == 1) { From 780c7b03bae44cb08da85c5509edc9b0bee8443d Mon Sep 17 00:00:00 2001 From: gabrielC Date: Tue, 25 Apr 2017 11:33:40 +0200 Subject: [PATCH 526/571] - fix for TDD config 3 --- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 18 ++++++------ openair1/SCHED/phy_procedures_lte_common.c | 8 ++++-- openair1/SCHED/phy_procedures_lte_ue.c | 32 ++++++++++++++++----- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 863f8c4994..3e499c35e6 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -641,8 +641,8 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, frame_rx_prev = frame_rx_prev%1024; if (err_flag == 1) { - LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", - phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); + //LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", + // phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); if(0){// (harq_process->nb_rb==25 && r==3 && harq_process->round==0 ) { @@ -671,17 +671,17 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, } if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } return((1+dlsch->max_turbo_iterations)); } else { - LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d harq_process->mcs %d harq_process->nb_rb %d\n", - phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); + //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d harq_process->mcs %d harq_process->nb_rb %d\n", + //phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); - if (harq_process->nb_rb==25 && harq_process->mcs==28) { + if(0){// (harq_process->mcs==28 && (subframe ==5 || subframe==0)) { write_output("decoder_llr_ok.m","decllr_ok",dlsch_llr,G,1,0); write_output("rxdataF0_ok.m" , "rxdataF0_ok", &phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); @@ -696,12 +696,12 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, dlsch->harq_ack[subframe].ack = 1; dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].send_harq_status = 1; - LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", - phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); + //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", + // phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); + LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); } //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index c247d57da2..e19bed4c8a 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -455,15 +455,17 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, // report ACK/NACK status if (harq_ack[subframe_dl0].send_harq_status == 1) { - o_ACK[0] = harq_ack[subframe_dl0].ack; + o_ACK[cw_idx] = harq_ack[subframe_dl0].ack; if (harq_ack[subframe_dl1].send_harq_status == 1) - o_ACK[1] = harq_ack[subframe_dl1].ack; + o_ACK[cw_idx] &= harq_ack[subframe_dl1].ack; } else if (harq_ack[subframe_dl1].send_harq_status == 1) - o_ACK[0] = harq_ack[subframe_dl1].ack; + o_ACK[cw_idx] = harq_ack[subframe_dl1].ack; status = harq_ack[subframe_dl0].send_harq_status + (harq_ack[subframe_dl1].send_harq_status<<1); + LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d, dl Sfn1 %d status %d \n", subframe, subframe_dl0, harq_ack[subframe_dl0].send_harq_status, + subframe_dl1, harq_ack[subframe_dl1].send_harq_status); if (do_reset) { // reset ACK/NACK status harq_ack[subframe_dl0].ack = 2; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 36477a110f..0f83851011 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -633,13 +633,15 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type, } if(SR_payload == 1) { + return pucch_format1; + /* if (frame_type == FDD) { return pucch_format1; } else if (frame_type == TDD) { return pucch_format1b; } else { AssertFatal(1==0,"Unknown frame_type"); - } + }*/ } } else @@ -1793,7 +1795,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin pucch_ack_payload, 1); - nb_cw = ack_status_cw0 + ack_status_cw1; + nb_cw = ( (ack_status_cw0 != 0) ? 1:0) + ( (ack_status_cw1 != 0) ? 1:0); cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& (is_cqi_TXOp(ue,proc,eNB_id)==1)); @@ -1830,8 +1832,8 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin (uint8_t *)&pucch_payload, &len); - LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", - frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); + LOG_I(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", + frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); // Part - IV @@ -1866,7 +1868,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif if(format == pucch_format1) { - LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", + LOG_I(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, @@ -1878,7 +1880,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin else { if (SR_payload>0) { - LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", + LOG_I(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, @@ -1891,7 +1893,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin Po_PUCCH, tx_amp); } else { - LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, @@ -3999,6 +4001,22 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->dlsch_ra[eNB_id]->active = 0; } + // duplicate harq structure + uint8_t current_harq_pid = ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid; + LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[current_harq_pid]; + LTE_DL_UE_HARQ_t *harq_processes_dest = ue->dlsch[(subframe_rx+1)&0x1][eNB_id][0]->harq_processes[current_harq_pid]; + + harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_ack[subframe_rx]; + harq_status_t *harq_ack_dest = &ue->dlsch[(subframe_rx+1)&0x1][eNB_id][0]->harq_ack[subframe_rx]; + + memcpy(harq_processes_dest, current_harq_processes, sizeof(LTE_DL_UE_HARQ_t)); + memcpy(harq_ack_dest, current_harq_ack, sizeof(harq_status_t)); + + LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.status %d DestHarqProcess.status %d\n",frame_rx%1024,subframe_rx,current_harq_processes->status,harq_processes_dest->status); + LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.round %d DestHarqProcess.round %d\n",frame_rx%1024,subframe_rx,current_harq_processes->round,harq_processes_dest->round); + LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.delta_PUCCH %d DestHarqProcess.delta_PUCCH %d\n",frame_rx%1024,subframe_rx,current_harq_processes->delta_PUCCH,harq_processes_dest->delta_PUCCH); + LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.rvidx %d DestHarqProcess.rvidx %d\n",frame_rx%1024,subframe_rx,current_harq_processes->rvidx,harq_processes_dest->rvidx); + if (subframe_rx==9) { if (frame_rx % 10 == 0) { if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0) From cd7e479fc7f255444716015b7b4590be1e5936c0 Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 26 Apr 2017 17:05:29 +0200 Subject: [PATCH 527/571] sss pss calculation --- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 148 +++++++++++++++--- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 8 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 4 +- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 2 +- openair1/PHY/LTE_TRANSPORT/proto.h | 6 +- openair1/PHY/LTE_TRANSPORT/sss.c | 41 ++++- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 7 +- openair1/PHY/MODULATION/slot_fep.c | 10 +- openair1/SCHED/phy_procedures_lte_common.c | 8 +- openair1/SCHED/phy_procedures_lte_ue.c | 47 +++++- 10 files changed, 230 insertions(+), 51 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index d075d0ca50..8d014b590a 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -172,6 +172,10 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, uint8_t subframe = slot>>1; int aarx,rb,n; + uint8_t pss_symb; + uint8_t sss_symb; + + int32_t **rxdataF; int16_t *rxF,*rxF_pss,*rxF_sss; uint16_t Nid_cell = ue->frame_parms.Nid_cell; @@ -185,6 +189,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, int32_t (*xss_ext)[72]; // point to either pss_ext or sss_ext for common calculation int16_t *re,*im; // real and imag part of each 32-bit xss_ext[][] value + LOG_I(PHY,"UE RRC MEAS Start Subframe %d Frame Type %d slot %d \n",subframe,ue->frame_parms.frame_type,slot); for (eNB_offset = 0; eNB_offset<1+ue->measurements.n_adj_cells; eNB_offset++) { if (eNB_offset==0) { @@ -192,27 +197,28 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, //ue->measurements.n0_power_tot = 0; if (abstraction_flag == 0) { - if ((ue->frame_parms.frame_type == FDD) && - ((subframe == 0) || (subframe == 5))) { // FDD PSS/SSS, compute noise in DTX REs + if ( ((ue->frame_parms.frame_type == FDD) && ((subframe == 0) || (subframe == 5))) || + ((ue->frame_parms.frame_type == TDD) && ((subframe == 1) || (subframe == 6))) + ) + { // FDD PSS/SSS, compute noise in DTX REs if (ue->frame_parms.Ncp==NORMAL) { for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + if(ue->frame_parms.frame_type == FDD) + { rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)]; rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)]; - + } + else + { + rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)]; + rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)]; + } //-ve spectrum from SSS - // printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]); - // ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71])); - // printf("sssn36 %d\n",ue->measurements.n0_power[aarx]); - ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69])); - ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67])); - ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65])); - // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); - // printf("sssm32 %d\n",ue->measurements.n0_power[aarx]); //+ve spectrum from SSS - ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69])); ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67])); ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65])); // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63])); @@ -223,18 +229,58 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65])); // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63])); // printf("pss32 %d\n",ue->measurements.n0_power[aarx]); //-ve spectrum from PSS - rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)]; + if(ue->frame_parms.frame_type == FDD) + { + rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)]; + rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)]; + } + else + { + rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)]; + rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)]; + } // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71])); // printf("pssm36 %d\n",ue->measurements.n0_power[aarx]); ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69])); ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67])); ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65])); + + ue->measurements.n0_power[aarx] = (((int32_t)rxF_sss[-70]*rxF_sss[-70])+((int32_t)rxF_sss[-69]*rxF_sss[-69])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-68]*rxF_sss[-68])+((int32_t)rxF_sss[-67]*rxF_sss[-67])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-66]*rxF_sss[-66])+((int32_t)rxF_sss[-65]*rxF_sss[-65])); + // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; } + LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); +#if 0 + if(ue->dlsch[subframe&0x1][0][0]->active == 1){// (harq_process->nb_rb==25 && r==3 && harq_process->round==0 ) { + //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); + write_output("rxdataF0_pss_tdd.m" , "pss_cur_tdd", + &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][2*ue->frame_parms.ofdm_symbol_size], + ue->frame_parms.ofdm_symbol_size,1,1); + write_output("rxdataF0_sss_tdd.m" , "sss_prev_tdd", + &ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[0][13*ue->frame_parms.ofdm_symbol_size], + ue->frame_parms.ofdm_symbol_size,1,1); + + /*write_output("rxdataF0_pss.m" , "pss_cur", + &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][6*ue->frame_parms.ofdm_symbol_size], + ue->frame_parms.ofdm_symbol_size,1,1); + write_output("rxdataF0_sss.m" , "sss_prev", + &ue->common_vars.common_vars_rx_data_per_thread[(subframe)&0x1].rxdataF[0][5*ue->frame_parms.ofdm_symbol_size], + ue->frame_parms.ofdm_symbol_size,1,1);*/ + + //write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("rxdataF_comp00.m","rxdataF_comp00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); + + AssertFatal (0,""); + } +#endif ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); } else { @@ -242,9 +288,9 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, } } else if ((ue->frame_parms.frame_type == TDD) && - ((slot == 2) || (slot == 12) || (slot == 1) || (slot == 11))) { // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation + ((subframe == 1) || (subframe == 6))) { // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation -#if 1 // fixing REs extraction in noise power calculation +#if 0 // fixing REs extraction in noise power calculation // check if this slot has a PSS or SSS sequence if ((slot == 2) || (slot == 12)) { @@ -259,12 +305,12 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, } if (isPss) { - pss_only_extract(ue, pss_ext); + pss_only_extract(ue, pss_ext, subframe); xss_ext = pss_ext; } if (isSss) { - sss_only_extract(ue, sss_ext); + sss_only_extract(ue, sss_ext, subframe); xss_ext = sss_ext; } @@ -288,19 +334,63 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; } + LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(num_tot)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); #else + + pss_symb = 2; + sss_symb = ue->frame_parms.symbols_per_tti-1; if (ue->frame_parms.Ncp==NORMAL) { for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)]; + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF; + rxF_pss = (int16_t *) &rxdataF[aarx][((pss_symb*(ue->frame_parms.ofdm_symbol_size)))]; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF; + rxF_sss = (int16_t *) &rxdataF[aarx][((sss_symb*(ue->frame_parms.ofdm_symbol_size)))]; + + //-ve spectrum from SSS + // printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]); + + // ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71])); + // printf("sssn36 %d\n",ue->measurements.n0_power[aarx]); + ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65])); + // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); + // printf("sssm32 %d\n",ue->measurements.n0_power[aarx]); + //+ve spectrum from SSS + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65])); + // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63])); + // printf("sssp32 %d\n",ue->measurements.n0_power[aarx]); + //+ve spectrum from PSS + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65])); + // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63])); + // printf("pss32 %d\n",ue->measurements.n0_power[aarx]); //-ve spectrum from PSS + rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)]; + // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71])); + // printf("pssm36 %d\n",ue->measurements.n0_power[aarx]); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67])); + ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65])); + // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); + // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); + ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); + ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; + + + //rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)]; // note this is a dummy pointer, the pss is not really there! // in FDD the pss is in the symbol after the sss, but not in TDD - rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)]; - + //rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)]; +/* //-ve spectrum from SSS // ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71])); ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69])); @@ -315,11 +405,17 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63])); ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(6)); - ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; + ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; */ } + + ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); + ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); +/* ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(6*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); +*/ + LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); } #endif @@ -452,6 +548,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, #endif } + } void lte_ue_measurements(PHY_VARS_UE *ue, @@ -550,6 +647,8 @@ void lte_ue_measurements(PHY_VARS_UE *ue, (((k1*((long long int)(ue->measurements.rx_power_avg[eNB_id]))) + (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10); + LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg, + ue->measurements.n0_power_tot); ue->measurements.n0_power_avg = (int) (((k1*((long long int) (ue->measurements.n0_power_avg))) + (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); @@ -566,15 +665,16 @@ void lte_ue_measurements(PHY_VARS_UE *ue, ue->measurements.wideband_cqi_tot[eNB_id] = dB_fixed2(ue->measurements.rx_power_tot[eNB_id],ue->measurements.n0_power_tot); ue->measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(ue->measurements.rx_power_avg[eNB_id],ue->measurements.n0_power_avg); ue->measurements.rx_rssi_dBm[eNB_id] = ue->measurements.rx_power_avg_dB[eNB_id] - ue->rx_total_gain_dB; -#ifdef DEBUG_MEAS_UE - LOG_D(PHY,"[eNB %d] RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", +//#ifdef DEBUG_MEAS_UE + LOG_I(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", eNB_id, + subframe, ue->measurements.rx_rssi_dBm[eNB_id], ue->measurements.rx_power_avg_dB[eNB_id], ue->measurements.wideband_cqi_avg[eNB_id], ue->measurements.rx_power_avg[eNB_id], ue->measurements.n0_power_avg); -#endif +//#endif } ue->measurements.n0_power_avg_dB = dB_fixed( ue->measurements.n0_power_avg); diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index eeaa76d685..6592a850d4 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -6386,7 +6386,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } -#ifdef DEBUG_DCI +//#ifdef DEBUG_DCI if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe); @@ -6395,15 +6395,15 @@ int generate_ue_dlsch_params_from_dci(int frame, printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid); //printf("PDSCH dlsch0 UE: tpc %d\n",TPC); - printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); + //printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); printf("PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); printf("PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); printf("PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx); printf("PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS); printf("PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); - printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); + //printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); } -#endif +//#endif #if T_TRACER if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index 7e6685f114..ce7299715f 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -913,8 +913,8 @@ int rx_pdsch(PHY_VARS_UE *ue, } break; case 6 : - printf("LLR rx_type %d cw0 %d cw1 %d symbol %d first symbol %d nb_rb %d rballoceven %d sfn %d beamforming_mode %d\n", - rx_type,codeword_TB0,codeword_TB1,symbol,first_symbol_flag,nb_rb,dlsch0_harq->rb_alloc_even,subframe,beamforming_mode); + //printf("LLR rx_type %d cw0 %d cw1 %d symbol %d first symbol %d nb_rb %d rballoceven %d sfn %d beamforming_mode %d\n", + // rx_type,codeword_TB0,codeword_TB1,symbol,first_symbol_flag,nb_rb,dlsch0_harq->rb_alloc_even,subframe,beamforming_mode); if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) { dlsch_64qam_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 2b0eba324b..9a8b272c83 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -1092,7 +1092,7 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len2=len>>2; // length in quad words (4 REs) len2+=((len_mod4==0)?0:1); - printf("Sym %d llr Length %d %d\n", symbol,len,len2); + //printf("Sym %d llr Length %d %d\n", symbol,len,len2); for (i=0; inb_antennas_rx; aarx++) { if (frame_parms->frame_type == FDD) { @@ -180,11 +181,26 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue, pss_symb = 2; sss_symb = frame_parms->symbols_per_tti-1; + if(subframe==5 || subframe==0) + { rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF; sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; rxdataF = ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)&0x1)].rxdataF; pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else if(subframe==6 || subframe==1) + { + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF; + pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF; + sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else + { + AssertFatal(0,""); + } } //printf("extract_rbs: symbol_mod=%d, rx_offset=%d, ch_offset=%d\n",symbol_mod, @@ -204,11 +220,26 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue, } else { + if(subframe==5 || subframe==0) + { rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF; sss_rxF = &rxdataF[aarx][(1 + (sss_symb*(frame_parms->ofdm_symbol_size)))]; rxdataF = ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)&0x1)].rxdataF; pss_rxF = &rxdataF[aarx][(1 + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else if(subframe==6 || subframe==1) + { + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF; + pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))]; + + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF; + sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))]; + } + else + { + AssertFatal(0,""); + } } } @@ -237,18 +268,20 @@ int pss_sss_extract(PHY_VARS_UE *phy_vars_ue, } int pss_only_extract(PHY_VARS_UE *phy_vars_ue, - int32_t pss_ext[4][72]) + int32_t pss_ext[4][72], + uint8_t subframe) { static int32_t dummy[4][72]; - return _do_pss_sss_extract(phy_vars_ue, pss_ext, dummy, 1 /* doPss */, 0 /* doSss */, 0); + return _do_pss_sss_extract(phy_vars_ue, pss_ext, dummy, 1 /* doPss */, 0 /* doSss */, subframe); } int sss_only_extract(PHY_VARS_UE *phy_vars_ue, - int32_t sss_ext[4][72]) + int32_t sss_ext[4][72], + uint8_t subframe) { static int32_t dummy[4][72]; - return _do_pss_sss_extract(phy_vars_ue, dummy, sss_ext, 0 /* doPss */, 1 /* doSss */, 0); + return _do_pss_sss_extract(phy_vars_ue, dummy, sss_ext, 0 /* doPss */, 1 /* doSss */, subframe); } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 9ae1dc6603..8a53f11bfb 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -515,8 +515,9 @@ uint32_t ulsch_encoding(uint8_t *a, G = G - Q_RI - Q_CQI; ulsch->harq_processes[harq_pid]->G = G; -/* - LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK); + + LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), " + "Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK); LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n", frame_parms->Nid_cell,ulsch->rnti, @@ -527,7 +528,7 @@ uint32_t ulsch_encoding(uint8_t *a, ulsch->O_RI, ulsch->harq_processes[harq_pid]->O_ACK, G); -*/ + if ((int)G < 0) { LOG_E(PHY,"FATAL: ulsch_coding.c G < 0 (%d) : Q_RI %d, Q_CQI %d, O %d, betaCQI_times8 %d)\n",G,Q_RI,Q_CQI,ulsch->O,ulsch->beta_offset_cqi_times8); diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index 3a3b3b4c0d..973e417dd1 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -117,6 +117,8 @@ int slot_fep(PHY_VARS_UE *ue, if (l==0) { + LOG_I(PHY,"FFT odfm symbol %d Slot %d \n",symbol,Ns); + if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((short *)&common_vars->rxdata[aa][frame_length_samples], (short *)&common_vars->rxdata[aa][0], @@ -170,19 +172,19 @@ int slot_fep(PHY_VARS_UE *ue, } - #ifdef DEBUG_FEP + //#ifdef DEBUG_FEP // if (ue->frame <100) printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset); - #endif + //#endif } if (ue->perfect_ce == 0) { if ((l==0) || (l==(4-frame_parms->Ncp))) { for (aa=0; aanb_antenna_ports_eNB; aa++) { -#ifdef DEBUG_FEP +//#ifdef DEBUG_FEP printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); -#endif +//#endif start_meas(&ue->dlsch_channel_estimation_stats); lte_dl_channel_estimation(ue,eNB_id,0, Ns, diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index e19bed4c8a..8f01dd7fe5 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -454,6 +454,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, } // report ACK/NACK status + o_ACK[cw_idx] = 0; if (harq_ack[subframe_dl0].send_harq_status == 1) { o_ACK[cw_idx] = harq_ack[subframe_dl0].ack; @@ -462,10 +463,11 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, } else if (harq_ack[subframe_dl1].send_harq_status == 1) o_ACK[cw_idx] = harq_ack[subframe_dl1].ack; - status = harq_ack[subframe_dl0].send_harq_status + (harq_ack[subframe_dl1].send_harq_status<<1); + status = harq_ack[subframe_dl0].send_harq_status + harq_ack[subframe_dl1].send_harq_status; - LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d, dl Sfn1 %d status %d \n", subframe, subframe_dl0, harq_ack[subframe_dl0].send_harq_status, - subframe_dl1, harq_ack[subframe_dl1].send_harq_status); + LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d o_Ack %d, dl Sfn1 %d status %d o_Ack %d\n", + subframe, subframe_dl0, harq_ack[subframe_dl0].send_harq_status,harq_ack[subframe_dl0].ack, + subframe_dl1, harq_ack[subframe_dl1].send_harq_status,harq_ack[subframe_dl1].ack); if (do_reset) { // reset ACK/NACK status harq_ack[subframe_dl0].ack = 2; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 0f83851011..712ac081a1 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1367,8 +1367,9 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } //#ifdef DEBUG_PHY_PROC - LOG_D(PHY, - "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", + LOG_I(PHY, + "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " + "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx, first_rb,nb_rb, ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, @@ -1618,14 +1619,20 @@ void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8 int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) { + if ((ue->transmission_mode[eNB_id]<4)|| (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback // 4-bit CQI message + LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id], + ue->measurements.wideband_cqi_avg[eNB_id], + sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id], + ue->transmission_mode[eNB_id])); *len=4; return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id], ue->transmission_mode[eNB_id])); } else { // Mode 1-1 feedback, later + LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]); *len=0; // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI) @@ -1741,7 +1748,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin if(ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag) { - LOG_D(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx); + LOG_I(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT); return; } @@ -2148,10 +2155,16 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui // reset DL ACK/NACK status if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0] != NULL) + { reset_ack(&ue->frame_parms, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx, ue->ulsch[eNB_id]->o_ACK,0); + reset_ack(&ue->frame_parms, + ue->dlsch[(subframe_DL(&ue->frame_parms,proc->subframe_rx)+1)&0x1][eNB_id][0]->harq_ack, + subframe_tx, + ue->ulsch[eNB_id]->o_ACK,0); + } if (ue->dlsch_SI[eNB_id] != NULL) reset_ack(&ue->frame_parms, @@ -2193,6 +2206,8 @@ void ue_measurement_procedures( uint16_t slot, // slot index of each radio frame [0..19] uint8_t abstraction_flag,runmode_t mode) { + LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp); + LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; @@ -2232,6 +2247,7 @@ void ue_measurement_procedures( if (l==(6-ue->frame_parms.Ncp)) { // make sure we have signal from PSS/SSS for N0 measurement + LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN); ue_rrc_measurements(ue, @@ -3159,7 +3175,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC if (dlsch0 && (!dlsch1)) { harq_pid = dlsch0->current_harq_pid; - LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d\n",ue->Mod_id,subframe_rx,harq_pid); + LOG_I(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m); if ((pdsch==PDSCH) && (ue->transmission_mode[eNB_id] == 5) && @@ -3866,6 +3882,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin stop_meas(&ue->ofdm_demod_stats); } + LOG_I(PHY," Measurement slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); } // for l=1..l2 @@ -3931,6 +3949,27 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } start_meas(&ue->generic_stat); + +#if 0 + if(subframe_rx==5 && ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->nb_rb > 20){ + //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); + //write_output("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + + write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + //write_output("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[(subframe_rx+1)&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + + //write_output("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + + write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx&0x1].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[subframe_rx&0x1][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + write_output("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[subframe_rx&0x1][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); + //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); + + AssertFatal (0,""); + } +#endif + // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { ue_pdsch_procedures(ue, From 3c6e206e975df31314261c29a6f06f0eea3383c8 Mon Sep 17 00:00:00 2001 From: hbilel Date: Tue, 2 May 2017 18:01:47 +0200 Subject: [PATCH 528/571] TDD fix for several issues --- .../lte_dl_channel_estimation.c | 192 +++--- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 16 +- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 3 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 3 +- openair1/PHY/MODULATION/slot_fep.c | 8 +- openair1/SCHED/defs.h | 6 +- openair1/SCHED/phy_procedures_lte_common.c | 66 +- openair1/SCHED/phy_procedures_lte_ue.c | 596 +++++++++++++++++- 8 files changed, 745 insertions(+), 145 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c index b34331eb8d..10dd9b7d04 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c @@ -637,105 +637,137 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, 32767-ue->ch_est_alpha, dl_ch-(ue->frame_parms.ofdm_symbol_size<<1),0,ue->frame_parms.ofdm_symbol_size); } else { // high_speed_flag == 1 - if (symbol == 0) { - // printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp); - // dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)]; + if ((symbol == 0)) { + // printf("Interpolating %d->0\n",4-ue->frame_parms.Ncp); + // dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)]; if(((Ns>>1)!=0) || ( ((Ns>>1)==0) && interpolateS11S12)) { - //LOG_D(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns); - dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; + LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns); + dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; + + multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + + multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + } + + interpolateS11S12 = 1; + } // this is 1/3,2/3 combination for pilots spaced by 3 symbols + else if (symbol == pilot1) { + dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0]; + + LOG_I(PHY,"Interpolate s0-->s4 to get s1 s2 and s3 Ns %d \n", Ns); + if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination) + + + //subframe_select(ue->frame_parms,((Ns>>1)-1)) == SF_UL + //if((Ns>>1) != 5) + + + + uint8_t previous_subframe; + if(Ns>>1 == 0) + previous_subframe = 9; + else + previous_subframe = ((Ns>>1) - 1 )%9; + if(((Ns>>1)>0 && subframe_select(&ue->frame_parms,((Ns>>1)-1)) == SF_UL && ue->frame_parms.frame_type == TDD) || + ((Ns>>1)==0 && subframe_select(&ue->frame_parms,9) == SF_UL && ue->frame_parms.frame_type == TDD) ) + { + + multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + + multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + + multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,32440,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + } + else + { + multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + + multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + + multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + + } + } else { + multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + + multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + } // pilot spacing 3 symbols (1/3,2/3 combination) + } else if (symbol == pilot2) { + dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(ue->frame_parms.ofdm_symbol_size)]; multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - } + } else { // symbol == pilot3 + // printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp); + dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)]; - interpolateS11S12 = 1; - } // this is 1/3,2/3 combination for pilots spaced by 3 symbols - else if (symbol == pilot1) { - dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0]; + if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination) + multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination) - multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + } else { + multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - } else { - multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size); + multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); + } // pilot spacing 3 symbols (1/3,2/3 combination) - multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - } // pilot spacing 3 symbols (1/3,2/3 combination) - } else if (symbol == pilot2) { - dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(ue->frame_parms.ofdm_symbol_size)]; - - multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - - multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - } else { // symbol == pilot3 - // printf("Interpolating 0->%d\n",4-ue->frame_parms.Ncp); - dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)]; - - if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination) - multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,8192,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - - multadd_complex_vector_real_scalar(dl_ch_prev,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,16384,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - - multadd_complex_vector_real_scalar(dl_ch_prev,8192,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,24576,dl_ch_prev+(3*2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - } else { - multadd_complex_vector_real_scalar(dl_ch_prev,10923,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),0,ue->frame_parms.ofdm_symbol_size); - - multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)<<1),1,ue->frame_parms.ofdm_symbol_size); - multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((ue->frame_parms.ofdm_symbol_size)<<1)),0,ue->frame_parms.ofdm_symbol_size); - } // pilot spacing 3 symbols (1/3,2/3 combination) - - if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9)) - { - //LOG_D(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns); - interpolateS11S12 = 0; - //LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol); - int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; - int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)]; - - // interpolate ofdm s12: 5/4*ofdms11 + -1/4*ofdms7 5/4 q1.15 40960 -1/4 q1.15 8192 - int16_t *dlChEst_ofdm12 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][12*ue->frame_parms.ofdm_symbol_size]; - for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) + if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9)) { - int64_t tmp_mult = 0; - tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 40960 - (int64_t)dlChEst_ofdm7[i] * 8192); + LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns); + interpolateS11S12 = 0; + //LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol); + int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; + int16_t *dlChEst_ofdm7 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(ue->frame_parms.ofdm_symbol_size)]; - tmp_mult = tmp_mult >> 15; - dlChEst_ofdm12[i] = tmp_mult; + // interpolate ofdm s12: 5/4*ofdms11 + -1/4*ofdms7 5/4 q1.15 40960 -1/4 q1.15 8192 + int16_t *dlChEst_ofdm12 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][12*ue->frame_parms.ofdm_symbol_size]; + for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) + { + int64_t tmp_mult = 0; + tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 40960 - (int64_t)dlChEst_ofdm7[i] * 8192); + + tmp_mult = tmp_mult >> 15; + dlChEst_ofdm12[i] = tmp_mult; + } + + // interpolate ofdm s13: 3/2*ofdms11 + -1/2*ofdms7 3/2 q1.15 49152 1/2 q1.15 16384 + int16_t *dlChEst_ofdm13 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][13*ue->frame_parms.ofdm_symbol_size]; + for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) + { + int64_t tmp_mult = 0; + tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 49152 - (int64_t)dlChEst_ofdm7[i] * 16384); + + tmp_mult = tmp_mult >> 15; + dlChEst_ofdm13[i] = tmp_mult; + } } - // interpolate ofdm s13: 3/2*ofdms11 + -1/2*ofdms7 3/2 q1.15 49152 1/2 q1.15 16384 - int16_t *dlChEst_ofdm13 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][13*ue->frame_parms.ofdm_symbol_size]; - for(int i=0; i<(2*ue->frame_parms.ofdm_symbol_size); i++) - { - int64_t tmp_mult = 0; - tmp_mult = ((int64_t)dlChEst_ofdm11[i] * 49152 - (int64_t)dlChEst_ofdm7[i] * 16384); - - tmp_mult = tmp_mult >> 15; - dlChEst_ofdm13[i] = tmp_mult; - } - } - + } } - } +// } + } } diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 6592a850d4..338eba7308 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -8031,10 +8031,16 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, dlsch[0]->harq_ack[subframe].vDAI_UL = dai+1; - LOG_D(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d\n", + + LOG_I(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d" + " ulsch->bundling %d, O_ACK %d \n", harq_pid, (frame_parms->frame_type == TDD? "TDD" : "FDD"), - cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc, ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag); + cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc, + ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb, + ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, + ulsch->bundling, + ulsch->harq_processes[harq_pid]->O_ACK); ulsch->beta_offset_cqi_times8 = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18; ulsch->beta_offset_ri_times8 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10; @@ -8086,7 +8092,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; -#ifdef DEBUG_DCI +//#ifdef DEBUG_DCI printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe); printf("Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); @@ -8108,9 +8114,9 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, printf("Format 0 DCI :ulsch (ue): Nsymb_pusch %d\n",ulsch->Nsymb_pusch); printf("Format 0 DCI :ulsch (ue): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); printf("Format 0 DCI :ulsch (ue): phich status %d\n",ulsch->harq_processes[harq_pid]->status); -#else +//#else UNUSED_VARIABLE(dai); -#endif +//#endif return(0); } else { LOG_E(PHY,"frame %d, subframe %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n", diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 8a53f11bfb..b84d4fad36 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -517,7 +517,8 @@ uint32_t ulsch_encoding(uint8_t *a, LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), " - "Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK); + "Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial, + ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK); LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n", frame_parms->Nid_cell,ulsch->rnti, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index a26f3a876b..51a9d1e946 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -2067,7 +2067,8 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, if ((UE_index >= oai_emulation.info.first_ue_local) ||(UE_index <(oai_emulation.info.first_ue_local+oai_emulation.info.nb_ue_local))) { get_ack(&eNB->frame_parms, PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0][0]->harq_ack, - subframe, + proc->subframe_tx, + proc->subframe_rx, eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0); } else { // get remote UEs' ack eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0]; diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index 973e417dd1..ef2cd62882 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -172,19 +172,19 @@ int slot_fep(PHY_VARS_UE *ue, } - //#ifdef DEBUG_FEP + #ifdef DEBUG_FEP // if (ue->frame <100) printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset); - //#endif + #endif } if (ue->perfect_ce == 0) { if ((l==0) || (l==(4-frame_parms->Ncp))) { for (aa=0; aanb_antenna_ports_eNB; aa++) { -//#ifdef DEBUG_FEP +#ifdef DEBUG_FEP printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); -//#endif +#endif start_meas(&ue->dlsch_channel_estimation_stats); lte_dl_channel_estimation(ue,eNB_id,0, Ns, diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index e268cdcf00..7d0ff20b9c 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -311,7 +311,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n); @param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH @returns status indicator for PUCCH/PUSCH transmission */ -uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK, uint8_t cw_idx); +uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe_tx,uint8_t subframe_rx,uint8_t *o_ACK, uint8_t cw_idx); /*! \brief Reset ACK/NACK information @param frame_parms Pointer to DL frame parameter descriptor @@ -322,8 +322,10 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t */ uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, - unsigned char subframe, + unsigned char subframe_tx, + unsigned char subframe_rx, unsigned char *o_ACK, + uint8_t *pN_bundled, uint8_t cw_idx); /*! \brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH. Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6) diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index 8f01dd7fe5..ed26ef10ba 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -323,8 +323,10 @@ unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char s // return the number 'Nbundled' uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, - unsigned char subframe, + unsigned char subframe_tx, + unsigned char subframe_rx, unsigned char *o_ACK, + uint8_t *pN_bundled, uint8_t cw_idx, uint8_t do_reset) // 1 to reset ACK/NACK status : 0 otherwise { @@ -333,10 +335,10 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, // printf("get_ack: SF %d\n",subframe); if (frame_parms->frame_type == FDD) { - if (subframe < 4) - subframe_dl0 = subframe + 6; + if (subframe_tx < 4) + subframe_dl0 = subframe_tx + 6; else - subframe_dl0 = subframe - 4; + subframe_dl0 = subframe_tx - 4; o_ACK[cw_idx] = harq_ack[subframe_dl0].ack; status = harq_ack[subframe_dl0].send_harq_status; @@ -347,29 +349,29 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, } else { switch (frame_parms->tdd_config) { case 1: - if (subframe == 2) { // ACK subframes 5,6 + if (subframe_tx == 2) { // ACK subframes 5,6 subframe_ul = 6; subframe_dl0 = 5; subframe_dl1 = 6; - } else if (subframe == 3) { // ACK subframe 9 + } else if (subframe_tx == 3) { // ACK subframe 9 subframe_ul = 9; subframe_dl0 = 9; subframe_dl1 = 0xff; - } else if (subframe == 4) { // nothing + } else if (subframe_tx == 4) { // nothing subframe_ul = 0xff; subframe_dl0 = 0xff; // invalid subframe number indicates ACK/NACK is not needed subframe_dl1 = 0xff; - } else if (subframe == 7) { // ACK subframes 0,1 + } else if (subframe_tx == 7) { // ACK subframes 0,1 subframe_ul = 1; subframe_dl0 = 0; subframe_dl1 = 1; - } else if (subframe == 8) { // ACK subframes 4 + } else if (subframe_tx == 8) { // ACK subframes 4 subframe_ul = 4; subframe_dl0 = 4; subframe_dl1 = 0xff; } else { - LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); + LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe_tx %d for tdd_config %d\n", + subframe_tx,frame_parms->tdd_config); return(0); } @@ -396,18 +398,18 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, if (!do_reset && (subframe_ul < 10)) { if ((subframe_dl0 < 10) && (subframe_dl1 < 10)) { LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d harq_status=%d vDAI_DL=%d, dlsf#%d ACK=%d harq_status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", - subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, + subframe_tx, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, subframe_dl0, harq_ack[subframe_dl0].ack, harq_ack[subframe_dl0].send_harq_status, harq_ack[subframe_dl0].vDAI_DL, subframe_dl1, harq_ack[subframe_dl1].ack, harq_ack[subframe_dl1].send_harq_status, harq_ack[subframe_dl1].vDAI_DL, o_ACK[cw_idx], status); } else if (subframe_dl0 < 10) { LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", - subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, + subframe_tx, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, subframe_dl0, harq_ack[subframe_dl0].ack, harq_ack[subframe_dl0].send_harq_status, harq_ack[subframe_dl0].vDAI_DL, o_ACK[cw_idx], status); }else if (subframe_dl1 < 10) { LOG_D(PHY,"ul-sf#%d vDAI_UL[sf#%d]=%d Nbundled=%d: dlsf#%d ACK=%d status=%d vDAI_DL=%d, o_ACK[0]=%d status=%d\n", - subframe, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, + subframe_tx, subframe_ul, harq_ack[subframe_ul].vDAI_UL, status, subframe_dl1, harq_ack[subframe_dl1].ack, harq_ack[subframe_dl1].send_harq_status, harq_ack[subframe_dl1].vDAI_DL, o_ACK[cw_idx], status); } @@ -415,7 +417,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, // reset ACK/NACK status if (do_reset) { - LOG_D(PHY,"ul-sf#%d ACK/NACK status resetting @ dci0-sf#%d, dci1x/2x-sf#%d, dci1x/2x-sf#%d\n", subframe, subframe_ul, subframe_dl0, subframe_dl1); + LOG_D(PHY,"ul-sf#%d ACK/NACK status resetting @ dci0-sf#%d, dci1x/2x-sf#%d, dci1x/2x-sf#%d\n", subframe_tx, subframe_ul, subframe_dl0, subframe_dl1); if (subframe_ul < 10) { harq_ack[subframe_ul].vDAI_UL = 0xff; } @@ -434,22 +436,25 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, break; case 3: - if (subframe == 2) { // ACK subframes 5 and 6 + if (subframe_tx == 2) { // ACK subframes 5 and 6 subframe_dl0 = 5; subframe_dl1 = 6; - //printf("Subframe 2, TDD config 3: harq_ack[5] = %d (%d),harq_ack[6] = %d (%d)\n",harq_ack[5].ack,harq_ack[5].send_harq_status,harq_ack[6].ack,harq_ack[6].send_harq_status); - } else if (subframe == 3) { // ACK subframes 7 and 8 + subframe_ul = 2; + //printf("subframe_tx 2, TDD config 3: harq_ack[5] = %d (%d),harq_ack[6] = %d (%d)\n",harq_ack[5].ack,harq_ack[5].send_harq_status,harq_ack[6].ack,harq_ack[6].send_harq_status); + } else if (subframe_tx == 3) { // ACK subframes 7 and 8 subframe_dl0 = 7; subframe_dl1 = 8; + subframe_ul = 3; //printf("Subframe 3, TDD config 3: harq_ack[7] = %d,harq_ack[8] = %d\n",harq_ack[7].ack,harq_ack[8].ack); //printf("status %d : o_ACK (%d,%d)\n", status,o_ACK[0],o_ACK[1]); - } else if (subframe == 4) { // ACK subframes 9 and 0 + } else if (subframe_tx == 4) { // ACK subframes 9 and 0 subframe_dl0 = 9; subframe_dl1 = 0; + subframe_ul = 4; //printf("Subframe 4, TDD config 3: harq_ack[9] = %d,harq_ack[0] = %d\n",harq_ack[9].ack,harq_ack[0].ack); } else { - LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); + LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe_tx %d for tdd_config %d\n", + subframe_tx,frame_parms->tdd_config); return(0); } @@ -463,11 +468,12 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, } else if (harq_ack[subframe_dl1].send_harq_status == 1) o_ACK[cw_idx] = harq_ack[subframe_dl1].ack; + pN_bundled[0] = harq_ack[subframe_rx].vDAI_UL; status = harq_ack[subframe_dl0].send_harq_status + harq_ack[subframe_dl1].send_harq_status; - LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d o_Ack %d, dl Sfn1 %d status %d o_Ack %d\n", - subframe, subframe_dl0, harq_ack[subframe_dl0].send_harq_status,harq_ack[subframe_dl0].ack, - subframe_dl1, harq_ack[subframe_dl1].send_harq_status,harq_ack[subframe_dl1].ack); + LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d o_Ack %d, dl Sfn1 %d status %d o_Ack %d subframe_rx %d N_bundled %d \n", + subframe_tx, subframe_dl0, harq_ack[subframe_dl0].send_harq_status,harq_ack[subframe_dl0].ack, + subframe_dl1, harq_ack[subframe_dl1].send_harq_status,harq_ack[subframe_dl1].ack, subframe_rx, pN_bundled[0]); if (do_reset) { // reset ACK/NACK status harq_ack[subframe_dl0].ack = 2; @@ -488,20 +494,24 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, - unsigned char subframe, + unsigned char subframe_tx, + unsigned char subframe_rx, unsigned char *o_ACK, uint8_t cw_idx) { - return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 0); + uint8_t N_bundled = 0; + return get_reset_ack(frame_parms, harq_ack, subframe_tx, subframe_rx, o_ACK, &N_bundled, cw_idx, 0); } uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms, harq_status_t *harq_ack, - unsigned char subframe, + unsigned char subframe_tx, + unsigned char subframe_rx, unsigned char *o_ACK, + uint8_t *pN_bundled, uint8_t cw_idx) { - return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 1); + return get_reset_ack(frame_parms, harq_ack, subframe_tx, subframe_rx, o_ACK, pN_bundled, cw_idx, 1); } diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 712ac081a1..dc9bec2098 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -444,8 +444,523 @@ uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) return(0); } +void compute_cqi_ri_resources(PHY_VARS_UE *ue, + LTE_UE_ULSCH_t *ulsch, + uint8_t eNB_id, + uint16_t rnti, + uint16_t p_rnti, + uint16_t cba_rnti, + uint8_t cqi_status, + uint8_t ri_status) +{ + PHY_MEASUREMENTS *meas = &ue->measurements; + uint8_t transmission_mode = ue->transmission_mode[eNB_id]; + if (cqi_status == 1 || ri_status == 1) + { + if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) ) + { + ulsch->O_RI = 1; + } + else + { + ulsch->O_RI = 0; + } + //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table + + switch(transmission_mode) { + // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling + case 1: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + case 2: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + case 3: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + case 4: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank1_2A; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank2_2A; + ulsch->o_RI[0] = 1; + } + + break; + + case 5: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank1_2A; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank2_2A; + ulsch->o_RI[0] = 1; + } + + break; + + case 6: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank1_2A; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; + break; + + case 50: + ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; + break; + + case 100: + ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; + break; + } + + ulsch->uci_format = wideband_cqi_rank2_2A; + ulsch->o_RI[0] = 1; + } + + break; + + case 7: + if ((rnti >= cba_rnti) && (rnti < p_rnti)) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_mcs_CBA; + ulsch->o_RI[0] = 0; + } else if(meas->rank[eNB_id] == 0) { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 0; + } else { + switch (ue->frame_parms.N_RB_DL) { + case 6: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; + break; + + case 25: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; + break; + + case 50: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; + break; + + case 100: + ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; + break; + } + + ulsch->uci_format = HLC_subband_cqi_nopmi; + ulsch->o_RI[0] = 1; + } + + break; + + default: + LOG_E(PHY,"Incorrect Transmission Mode \n"); + break; + } + ulsch->O = 4; + } + else + { + ulsch->O_RI = 0; + ulsch->O = 0; + ulsch->uci_format = HLC_subband_cqi_nopmi; + } +} + void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS) { @@ -511,7 +1026,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id uint8_t pucch_ack_payload[2]; if (get_ack(&ue->frame_parms, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, - subframe_tx,pucch_ack_payload,0) > 0) + subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0) { is_sr_an_subframe = 1; } @@ -536,6 +1051,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id } LOG_D(PHY," srsCellSubframe: %d, srsUeSubframe: %d, Nsymb-pusch: %d \n", pSoundingrs_ul_config_dedicated->srsCellSubframe, pSoundingrs_ul_config_dedicated->srsUeSubframe, ue->ulsch[eNB_id]->Nsymb_pusch); } + } @@ -1218,9 +1734,11 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB uint8_t ulsch_input_buffer[5477] __attribute__ ((aligned(32))); uint8_t access_mode; uint8_t Nbundled=0; + uint8_t NbundledCw1=0; uint8_t ack_status_cw0=0; uint8_t ack_status_cw1=0; - + uint8_t cqi_status = 0; + uint8_t ri_status = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN); // get harq_pid from subframe relationship @@ -1323,25 +1841,41 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ack_status_cw0 = reset_ack(&ue->frame_parms, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx, - ue->ulsch[eNB_id]->o_ACK,0); + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &Nbundled, + 0); ack_status_cw1 = reset_ack(&ue->frame_parms, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][1]->harq_ack, subframe_tx, - ue->ulsch[eNB_id]->o_ACK,1); + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &NbundledCw1, + 1); + + //Nbundled = ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack; + //ue->ulsch[eNB_id]->bundling = Nbundled; - Nbundled = ack_status_cw0; first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb; nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; + // check Periodic CQI/RI reporting + cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& + (is_cqi_TXOp(ue,proc,eNB_id)==1)); + + ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && + (is_ri_TXOp(ue,proc,eNB_id)==1)); - + // compute CQI/RI resources + compute_cqi_ri_resources(ue, ue->ulsch[eNB_id], eNB_id, ue->ulsch[eNB_id]->rnti, P_RNTI, CBA_RNTI, cqi_status, ri_status); + if (ack_status_cw0 > 0) { // check if we received a PDSCH at subframe_tx - 4 // ==> send ACK/NACK on PUSCH - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; + //ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; #if T_TRACER if(ue->ulsch[eNB_id]->o_ACK[0]) @@ -1369,7 +1903,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB //#ifdef DEBUG_PHY_PROC LOG_I(PHY, "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " - "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n", + "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d, Nbundled %d, CQI %d, RI %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx, first_rb,nb_rb, ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, @@ -1383,7 +1917,9 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1], ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, - ue->ulsch[eNB_id]->bundling); + ue->ulsch[eNB_id]->bundling, Nbundled, + cqi_status, + ri_status); //#endif @@ -1793,12 +2329,14 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ack_status_cw0 = get_ack(&ue->frame_parms, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx, + proc->subframe_rx, pucch_ack_payload, 0); ack_status_cw1 = get_ack(&ue->frame_parms, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][1]->harq_ack, subframe_tx, + proc->subframe_rx, pucch_ack_payload, 1); @@ -1812,9 +2350,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // Part - II // if nothing to report ==> exit function - if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0)) + if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0) ) { - LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n", + LOG_I(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n", frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); return; } @@ -2154,23 +2692,33 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui } // reset DL ACK/NACK status + uint8_t N_bundled = 0; if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0] != NULL) { reset_ack(&ue->frame_parms, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, subframe_tx, - ue->ulsch[eNB_id]->o_ACK,0); + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &N_bundled, + 0); reset_ack(&ue->frame_parms, ue->dlsch[(subframe_DL(&ue->frame_parms,proc->subframe_rx)+1)&0x1][eNB_id][0]->harq_ack, subframe_tx, - ue->ulsch[eNB_id]->o_ACK,0); + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &N_bundled, + 0); } if (ue->dlsch_SI[eNB_id] != NULL) reset_ack(&ue->frame_parms, ue->dlsch_SI[eNB_id]->harq_ack, subframe_tx, - ue->ulsch[eNB_id]->o_ACK,0); + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &N_bundled, + 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); @@ -2206,7 +2754,7 @@ void ue_measurement_procedures( uint16_t slot, // slot index of each radio frame [0..19] uint8_t abstraction_flag,runmode_t mode) { - LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp); + //LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp); LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; @@ -2247,7 +2795,7 @@ void ue_measurement_procedures( if (l==(6-ue->frame_parms.Ncp)) { // make sure we have signal from PSS/SSS for N0 measurement - LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); + // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN); ue_rrc_measurements(ue, @@ -3175,7 +3723,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC if (dlsch0 && (!dlsch1)) { harq_pid = dlsch0->current_harq_pid; - LOG_I(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m); + LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m); if ((pdsch==PDSCH) && (ue->transmission_mode[eNB_id] == 5) && @@ -3752,8 +4300,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin l=1; } - LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_I(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_I(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); for (; l<=l2; l++) { if (abstraction_flag == 0) { start_meas(&ue->ofdm_demod_stats); @@ -3771,7 +4319,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); if ((l==pilot1) || ((pmch_flag==1)&(l==l2))) { - LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); + LOG_I(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); @@ -4051,10 +4599,10 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin memcpy(harq_processes_dest, current_harq_processes, sizeof(LTE_DL_UE_HARQ_t)); memcpy(harq_ack_dest, current_harq_ack, sizeof(harq_status_t)); - LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.status %d DestHarqProcess.status %d\n",frame_rx%1024,subframe_rx,current_harq_processes->status,harq_processes_dest->status); - LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.round %d DestHarqProcess.round %d\n",frame_rx%1024,subframe_rx,current_harq_processes->round,harq_processes_dest->round); - LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.delta_PUCCH %d DestHarqProcess.delta_PUCCH %d\n",frame_rx%1024,subframe_rx,current_harq_processes->delta_PUCCH,harq_processes_dest->delta_PUCCH); - LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.rvidx %d DestHarqProcess.rvidx %d\n",frame_rx%1024,subframe_rx,current_harq_processes->rvidx,harq_processes_dest->rvidx); + //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.status %d DestHarqProcess.status %d\n",frame_rx%1024,subframe_rx,current_harq_processes->status,harq_processes_dest->status); + //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.round %d DestHarqProcess.round %d\n",frame_rx%1024,subframe_rx,current_harq_processes->round,harq_processes_dest->round); + //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.delta_PUCCH %d DestHarqProcess.delta_PUCCH %d\n",frame_rx%1024,subframe_rx,current_harq_processes->delta_PUCCH,harq_processes_dest->delta_PUCCH); + //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.rvidx %d DestHarqProcess.rvidx %d\n",frame_rx%1024,subframe_rx,current_harq_processes->rvidx,harq_processes_dest->rvidx); if (subframe_rx==9) { if (frame_rx % 10 == 0) { From ceb13b8aa4c15752c967dc4b566ec5e4bc52b76a Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 3 May 2017 09:57:03 +0200 Subject: [PATCH 529/571] [OAI-UE] Additional TDD fix --- openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c index 10dd9b7d04..75efef24bd 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c @@ -671,8 +671,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, previous_subframe = 9; else previous_subframe = ((Ns>>1) - 1 )%9; - if(((Ns>>1)>0 && subframe_select(&ue->frame_parms,((Ns>>1)-1)) == SF_UL && ue->frame_parms.frame_type == TDD) || - ((Ns>>1)==0 && subframe_select(&ue->frame_parms,9) == SF_UL && ue->frame_parms.frame_type == TDD) ) + + if((subframe_select(&ue->frame_parms,previous_subframe) == SF_UL)) { multadd_complex_vector_real_scalar(dl_ch_prev,328,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); From 3fcdec1ad75a1b121bedccb5eb90ac3ec53bb182 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Wed, 3 May 2017 11:11:06 +0200 Subject: [PATCH 530/571] fix for FDD --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 9 +- openair1/SCHED/phy_procedures_lte_common.c | 1 + openair1/SCHED/phy_procedures_lte_ue.c | 502 +-------------------- 3 files changed, 14 insertions(+), 498 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 338eba7308..7a147f8e66 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -8013,13 +8013,20 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, ulsch->bundling = 1-AckNackFBMode; if (frame_parms->frame_type == FDD) { - int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); + //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); + int dl_subframe = subframe; if (ue->dlsch[subframe_DL(&ue->frame_parms,dl_subframe)&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission ulsch->harq_processes[harq_pid]->O_ACK = 1; } else { ulsch->harq_processes[harq_pid]->O_ACK = 0; } + LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe, + ue->dlsch[0][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, + ue->dlsch[1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, + harq_pid, + ulsch->harq_processes[harq_pid]->O_ACK); + } else { if (ulsch->bundling) ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1; diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index ed26ef10ba..ae64cceb59 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -343,6 +343,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, o_ACK[cw_idx] = harq_ack[subframe_dl0].ack; status = harq_ack[subframe_dl0].send_harq_status; + LOG_I(PHY,"dl subframe %d send_harq_status %d cw_idx %d, reset %d\n",subframe_dl0, status, cw_idx, do_reset); if(do_reset) harq_ack[subframe_dl0].send_harq_status = 0; //printf("get_ack: Getting ACK/NAK for PDSCH (subframe %d) => %d\n",subframe_dl,o_ACK[0]); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index dc9bec2098..362356c3c1 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -457,507 +457,16 @@ void compute_cqi_ri_resources(PHY_VARS_UE *ue, uint8_t transmission_mode = ue->transmission_mode[eNB_id]; + LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format); if (cqi_status == 1 || ri_status == 1) { - if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) ) - { - ulsch->O_RI = 1; - } - else - { - ulsch->O_RI = 0; - } - //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table - - switch(transmission_mode) { - // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling - case 1: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - case 2: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - case 3: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - case 4: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank1_2A; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank2_2A; - ulsch->o_RI[0] = 1; - } - - break; - - case 5: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank1_2A; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank2_2A; - ulsch->o_RI[0] = 1; - } - - break; - - case 6: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank1_2A; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; - break; - - case 50: - ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; - break; - - case 100: - ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; - break; - } - - ulsch->uci_format = wideband_cqi_rank2_2A; - ulsch->o_RI[0] = 1; - } - - break; - - case 7: - if ((rnti >= cba_rnti) && (rnti < p_rnti)) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_mcs_CBA; - ulsch->o_RI[0] = 0; - } else if(meas->rank[eNB_id] == 0) { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 0; - } else { - switch (ue->frame_parms.N_RB_DL) { - case 6: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; - break; - - case 25: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; - break; - - case 50: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; - break; - - case 100: - ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; - break; - } - - ulsch->uci_format = HLC_subband_cqi_nopmi; - ulsch->o_RI[0] = 1; - } - - break; - - default: - LOG_E(PHY,"Incorrect Transmission Mode \n"); - break; - } ulsch->O = 4; } else { - ulsch->O_RI = 0; - ulsch->O = 0; - ulsch->uci_format = HLC_subband_cqi_nopmi; + //ulsch->O_RI = 0; + //ulsch->O = 0; + //ulsch->uci_format = HLC_subband_cqi_nopmi; } } @@ -1051,7 +560,6 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id } LOG_D(PHY," srsCellSubframe: %d, srsUeSubframe: %d, Nsymb-pusch: %d \n", pSoundingrs_ul_config_dedicated->srsCellSubframe, pSoundingrs_ul_config_dedicated->srsUeSubframe, ue->ulsch[eNB_id]->Nsymb_pusch); } - } @@ -1875,7 +1383,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB // check if we received a PDSCH at subframe_tx - 4 // ==> send ACK/NACK on PUSCH - //ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; #if T_TRACER if(ue->ulsch[eNB_id]->o_ACK[0]) From 8d787768c4915de0d54f0a24ea6c0aa0bf49f372 Mon Sep 17 00:00:00 2001 From: fnabet Date: Wed, 3 May 2017 14:43:45 +0200 Subject: [PATCH 531/571] Issue 238 fix: RLC AM --- .../RLC/AM_v9.3.0/rlc_am_status_report.c | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index d33dc78e91..c07e9cd6f3 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -408,19 +408,27 @@ rlc_am_receive_process_control_pdu( //TODO : this part does not cover all cases of Data Cnf and move it at the end of Status PDU processing sn_cursor = rlc_pP->vt_a; - /* Handle all acked PDU up to and excluding sn_data_cnf */ - while (sn_cursor != sn_data_cnf) { - rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_cursor); - sn_cursor = RLC_AM_NEXT_SN(sn_cursor); - } + // Fix Issue 238 : check sn_data_cnf has been transmitted + if ((rlc_pP->tx_data_pdu_buffer[sn_data_cnf % RLC_AM_WINDOW_SIZE].flags.transmitted) && + (rlc_pP->tx_data_pdu_buffer[sn_data_cnf % RLC_AM_WINDOW_SIZE].sn == sn_data_cnf)) { + /* Handle all acked PDU up to and excluding sn_data_cnf */ + while (sn_cursor != sn_data_cnf) { + rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_cursor); + sn_cursor = RLC_AM_NEXT_SN(sn_cursor); + } - // Handle last SN. TO DO : case of PDU partially ACKED with SDU to be data conf - if (data_cnf_so_stop == 0x7FFF) { - rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_data_cnf); - } + // Handle last SN. TO DO : case of PDU partially ACKED with SDU to be data conf + if (data_cnf_so_stop == 0x7FFF) { + rlc_am_pdu_sdu_data_cnf(ctxt_pP,rlc_pP,sn_data_cnf); + } - LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU ACK_SN=%d NewvtA=%d OldvtA=%d SnDataCnf=%d DataCnfSOStop=%d vtS=%d\n", - PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,sn_data_cnf,data_cnf_so_stop,rlc_pP->vt_s); + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU ACK_SN=%d NewvtA=%d OldvtA=%d SnDataCnf=%d DataCnfSOStop=%d vtS=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,sn_data_cnf,data_cnf_so_stop,rlc_pP->vt_s); + } + else { + LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RECEIVE STATUS PDU WITH NO SDU CNF ACK_SN=%d NewvtA=%d OldvtA=%d vtS=%d\n", + PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,vt_a_new,rlc_pP->vt_a,rlc_pP->vt_s); + } /* Update vtA and vtMS */ rlc_pP->vt_a = vt_a_new; From 966291029d3f11e32fffd3a638b835e7be134c08 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Wed, 3 May 2017 15:26:39 +0200 Subject: [PATCH 532/571] Clean and remove a problematic memcpy --- .../lte_dl_channel_estimation.c | 15 +- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 131 ++---------------- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 24 ++-- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 27 +--- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 6 +- .../PHY/LTE_TRANSPORT/dlsch_llr_computation.c | 2 - openair1/PHY/LTE_TRANSPORT/lte_mcs.c | 4 +- openair1/PHY/LTE_TRANSPORT/sss.c | 2 +- openair1/PHY/LTE_TRANSPORT/ulsch_coding.c | 8 +- openair1/PHY/MODULATION/slot_fep.c | 2 - openair1/SCHED/phy_procedures_lte_common.c | 8 +- openair1/SCHED/phy_procedures_lte_ue.c | 101 +++++++++----- targets/RT/USER/lte-ue.c | 3 +- 13 files changed, 112 insertions(+), 221 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c index 75efef24bd..9743c68a22 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c @@ -23,6 +23,7 @@ #include #endif #include "defs.h" +#include "SCHED/defs.h" #include "PHY/defs.h" #include "filt96_32.h" #include "T.h" @@ -642,7 +643,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, // dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-ue->frame_parms.Ncp)*(ue->frame_parms.ofdm_symbol_size)]; if(((Ns>>1)!=0) || ( ((Ns>>1)==0) && interpolateS11S12)) { - LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns); + //LOG_I(PHY,"Interpolate s11-->s0 to get s12 and s13 Ns %d \n", Ns); dl_ch_prev = (int16_t *)&dl_ch_estimates_previous[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(ue->frame_parms.ofdm_symbol_size)),1,ue->frame_parms.ofdm_symbol_size); @@ -657,15 +658,9 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, else if (symbol == pilot1) { dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0]; - LOG_I(PHY,"Interpolate s0-->s4 to get s1 s2 and s3 Ns %d \n", Ns); + //LOG_I(PHY,"Interpolate s0-->s4 to get s1 s2 and s3 Ns %d \n", Ns); if (ue->frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination) - - //subframe_select(ue->frame_parms,((Ns>>1)-1)) == SF_UL - //if((Ns>>1) != 5) - - - uint8_t previous_subframe; if(Ns>>1 == 0) previous_subframe = 9; @@ -734,7 +729,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, if((ue->rx_offset_diff !=0) && ((Ns>>1) == 9)) { - LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns); + //LOG_I(PHY,"Extrapolate s7-->s11 to get s12 and s13 Ns %d\n", Ns); interpolateS11S12 = 0; //LOG_E(PHY,"Interpolate s7--s11 s12 s13 pilot 3 Ns %d l %d symbol %d \n", Ns, l, symbol); int16_t *dlChEst_ofdm11 = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(ue->frame_parms.ofdm_symbol_size)]; @@ -766,8 +761,6 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue, } } -// } - } } diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 8d014b590a..4033e4c378 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -171,7 +171,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, { uint8_t subframe = slot>>1; - int aarx,rb,n; + int aarx,rb; uint8_t pss_symb; uint8_t sss_symb; @@ -182,14 +182,14 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, uint8_t eNB_offset,nu,l,nushift,k; uint16_t off; - uint8_t isPss; // indicate if this is a slot for extracting PSS - uint8_t isSss; // indicate if this is a slot for extracting SSS - int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS - int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS - int32_t (*xss_ext)[72]; // point to either pss_ext or sss_ext for common calculation - int16_t *re,*im; // real and imag part of each 32-bit xss_ext[][] value + //uint8_t isPss; // indicate if this is a slot for extracting PSS + //uint8_t isSss; // indicate if this is a slot for extracting SSS + //int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS + //int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS + //int32_t (*xss_ext)[72]; // point to either pss_ext or sss_ext for common calculation + //int16_t *re,*im; // real and imag part of each 32-bit xss_ext[][] value - LOG_I(PHY,"UE RRC MEAS Start Subframe %d Frame Type %d slot %d \n",subframe,ue->frame_parms.frame_type,slot); + //LOG_I(PHY,"UE RRC MEAS Start Subframe %d Frame Type %d slot %d \n",subframe,ue->frame_parms.frame_type,slot); for (eNB_offset = 0; eNB_offset<1+ue->measurements.n_adj_cells; eNB_offset++) { if (eNB_offset==0) { @@ -255,32 +255,8 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; } - LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); -#if 0 - if(ue->dlsch[subframe&0x1][0][0]->active == 1){// (harq_process->nb_rb==25 && r==3 && harq_process->round==0 ) { - //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); - write_output("rxdataF0_pss_tdd.m" , "pss_cur_tdd", - &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][2*ue->frame_parms.ofdm_symbol_size], - ue->frame_parms.ofdm_symbol_size,1,1); - write_output("rxdataF0_sss_tdd.m" , "sss_prev_tdd", - &ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[0][13*ue->frame_parms.ofdm_symbol_size], - ue->frame_parms.ofdm_symbol_size,1,1); + //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); - /*write_output("rxdataF0_pss.m" , "pss_cur", - &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][6*ue->frame_parms.ofdm_symbol_size], - ue->frame_parms.ofdm_symbol_size,1,1); - write_output("rxdataF0_sss.m" , "sss_prev", - &ue->common_vars.common_vars_rx_data_per_thread[(subframe)&0x1].rxdataF[0][5*ue->frame_parms.ofdm_symbol_size], - ue->frame_parms.ofdm_symbol_size,1,1);*/ - - //write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); - //write_output("rxdataF_comp00.m","rxdataF_comp00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); - //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); - //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); - - AssertFatal (0,""); - } -#endif ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); } else { @@ -290,55 +266,6 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, else if ((ue->frame_parms.frame_type == TDD) && ((subframe == 1) || (subframe == 6))) { // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation -#if 0 // fixing REs extraction in noise power calculation - - // check if this slot has a PSS or SSS sequence - if ((slot == 2) || (slot == 12)) { - isPss = 1; - } else { - isPss = 0; - } - if ((slot == 1) || (slot == 11)) { - isSss = 1; - } else { - isSss = 0; - } - - if (isPss) { - pss_only_extract(ue, pss_ext, subframe); - xss_ext = pss_ext; - } - - if (isSss) { - sss_only_extract(ue, sss_ext, subframe); - xss_ext = sss_ext; - } - - // calculate noise power - int num_tot=0; // number of REs totally used in calculating noise power - for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - - int num_per_rx=0; // number of REs used in caluclaing noise power for this RX antenna - ue->measurements.n0_power[aarx] = 0; - for (n=2; n<70; n++) { // skip the 2 REs next to PDSCH, i.e. n={0,1,70,71} - if (n==5) {n=67;} - - re = (int16_t*)(&(xss_ext[aarx][n])); - im = re+1; - ue->measurements.n0_power[aarx] += (*re)*(*re) + (*im)*(*im); - num_per_rx++; - num_tot++; - } - - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(num_per_rx)); - ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; - } - - LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(num_tot)); - ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); - -#else pss_symb = 2; sss_symb = ue->frame_parms.symbols_per_tti-1; @@ -383,42 +310,15 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; - - - //rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)]; - // note this is a dummy pointer, the pss is not really there! - // in FDD the pss is in the symbol after the sss, but not in TDD - - //rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)]; -/* - //-ve spectrum from SSS - // ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71])); - ue->measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69])); - ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67])); - ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65])); - // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); - //+ve spectrum from SSS - // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+72]*rxF_sss[2+72])+((int32_t)rxF_sss[2+71]*rxF_sss[2+71])); - ue->measurements.n0_power[aarx] = (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69])); - ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67])); - ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65])); - // ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63])); - - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/(6)); - ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; */ } ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); -/* - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(6*aarx)); - ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); -*/ - LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); + + //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); } -#endif } } } @@ -548,7 +448,6 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, #endif } - } void lte_ue_measurements(PHY_VARS_UE *ue, @@ -647,8 +546,8 @@ void lte_ue_measurements(PHY_VARS_UE *ue, (((k1*((long long int)(ue->measurements.rx_power_avg[eNB_id]))) + (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10); - LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg, - ue->measurements.n0_power_tot); + //LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg, + // ue->measurements.n0_power_tot); ue->measurements.n0_power_avg = (int) (((k1*((long long int) (ue->measurements.n0_power_avg))) + (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); @@ -665,7 +564,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, ue->measurements.wideband_cqi_tot[eNB_id] = dB_fixed2(ue->measurements.rx_power_tot[eNB_id],ue->measurements.n0_power_tot); ue->measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(ue->measurements.rx_power_avg[eNB_id],ue->measurements.n0_power_avg); ue->measurements.rx_rssi_dBm[eNB_id] = ue->measurements.rx_power_avg_dB[eNB_id] - ue->rx_total_gain_dB; -//#ifdef DEBUG_MEAS_UE +#ifdef DEBUG_MEAS_UE LOG_I(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", eNB_id, subframe, @@ -674,7 +573,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, ue->measurements.wideband_cqi_avg[eNB_id], ue->measurements.rx_power_avg[eNB_id], ue->measurements.n0_power_avg); -//#endif +#endif } ue->measurements.n0_power_avg_dB = dB_fixed( ue->measurements.n0_power_avg); diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 7a147f8e66..aec6d734d3 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2982,7 +2982,7 @@ int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) break; case 25: - LOG_I(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", + LOG_D(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, @@ -6386,7 +6386,7 @@ int generate_ue_dlsch_params_from_dci(int frame, } -//#ifdef DEBUG_DCI +#ifdef DEBUG_DCI if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe); @@ -6395,15 +6395,15 @@ int generate_ue_dlsch_params_from_dci(int frame, printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid); //printf("PDSCH dlsch0 UE: tpc %d\n",TPC); - //printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); + printf("PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); printf("PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); printf("PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); printf("PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx); printf("PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS); printf("PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); - //printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); + printf("PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); } -//#endif +#endif #if T_TRACER if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) @@ -8021,11 +8021,11 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, } else { ulsch->harq_processes[harq_pid]->O_ACK = 0; } - LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe, + /*LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe, ue->dlsch[0][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, ue->dlsch[1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, harq_pid, - ulsch->harq_processes[harq_pid]->O_ACK); + ulsch->harq_processes[harq_pid]->O_ACK);*/ } else { if (ulsch->bundling) @@ -8039,7 +8039,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, dlsch[0]->harq_ack[subframe].vDAI_UL = dai+1; - LOG_I(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d" + /*LOG_I(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d" " ulsch->bundling %d, O_ACK %d \n", harq_pid, (frame_parms->frame_type == TDD? "TDD" : "FDD"), @@ -8047,7 +8047,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->bundling, - ulsch->harq_processes[harq_pid]->O_ACK); + ulsch->harq_processes[harq_pid]->O_ACK);*/ ulsch->beta_offset_cqi_times8 = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18; ulsch->beta_offset_ri_times8 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10; @@ -8099,7 +8099,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; -//#ifdef DEBUG_DCI +#ifdef DEBUG_DCI printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe); printf("Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); @@ -8121,9 +8121,9 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, printf("Format 0 DCI :ulsch (ue): Nsymb_pusch %d\n",ulsch->Nsymb_pusch); printf("Format 0 DCI :ulsch (ue): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); printf("Format 0 DCI :ulsch (ue): phich status %d\n",ulsch->harq_processes[harq_pid]->status); -//#else +#else UNUSED_VARIABLE(dai); -//#endif +#endif return(0); } else { LOG_E(PHY,"frame %d, subframe %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n", diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 3e499c35e6..1ee6907271 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -644,19 +644,6 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, //LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", // phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); - - if(0){// (harq_process->nb_rb==25 && r==3 && harq_process->round==0 ) { - write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); - write_output("rxdataF0.m" , "rxdataF0", &phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); - write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp00.m","rxdataF_comp00", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); - - AssertFatal (0,"number of soft bits %d nb_rb %d",G,frame_parms->N_RB_DL); - } - - dlsch->harq_ack[subframe].ack = 0; dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].send_harq_status = 1; @@ -671,7 +658,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, } if(is_crnti) { - LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } @@ -681,16 +668,6 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d harq_process->mcs %d harq_process->nb_rb %d\n", //phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); - if(0){// (harq_process->mcs==28 && (subframe ==5 || subframe==0)) { - write_output("decoder_llr_ok.m","decllr_ok",dlsch_llr,G,1,0); - write_output("rxdataF0_ok.m" , "rxdataF0_ok", &phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); - write_output("dl_ch_estimates_ext00.m", "dl_ch_estimates_ext00_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("rxdataF_comp00_ok.m","rxdataF_comp00_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("magDLFirst_ok.m", "magDLFirst_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); - write_output("magDLSecond_ok.m", "magDLSecond_ok", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); - AssertFatal (0,"number of soft bits %d",G); - } - harq_process->status = SCH_IDLE; harq_process->round = 0; dlsch->harq_ack[subframe].ack = 1; @@ -701,7 +678,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, if(is_crnti) { - LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); } //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index ce7299715f..ecaf7cd121 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -354,7 +354,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #ifdef DEBUG_PHY - LOG_I(PHY,"[DLSCH] nb_rb %d log2_maxh = %d (%d,%d)\n",nb_rb,pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); + LOG_D(PHY,"[DLSCH] nb_rb %d log2_maxh = %d (%d,%d)\n",nb_rb,pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs); LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); #endif @@ -465,14 +465,14 @@ int rx_pdsch(PHY_VARS_UE *ue, avg, symbol, nb_rb); -//#ifdef DEBUG_PHY +#ifdef DEBUG_PHY LOG_I(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", frame%1024,subframe, pdsch_vars[eNB_id]->log2_maxh, pdsch_vars[eNB_id]->log2_maxh0, pdsch_vars[eNB_id]->log2_maxh1, avg[0],avgs); LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); -//#endif +#endif } #if T_TRACER diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 9a8b272c83..e2de78f9ca 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -1092,8 +1092,6 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms, len2=len>>2; // length in quad words (4 REs) len2+=((len_mod4==0)?0:1); - //printf("Sym %d llr Length %d %d\n", symbol,len,len2); - for (i=0; iNcp==NORMAL) ? 14 : 12; - //printf("adjust_G2 : symbol %d, subframe %d\n",symbol,subframe); + // printf("adjust_G2 : symbol %d, subframe %d\n",symbol,subframe); if ((subframe!=0) && (subframe!=5) && (subframe!=6)) // if not PBCH/SSS or SSS return(0); @@ -234,7 +234,7 @@ int adjust_G2(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_ord } } - //printf("re_pbch_sss %d\n",re_pbch_sss); + // printf("re_pbch_sss %d\n",re_pbch_sss); return(re_pbch_sss); } diff --git a/openair1/PHY/LTE_TRANSPORT/sss.c b/openair1/PHY/LTE_TRANSPORT/sss.c index 40a5cc493f..5eada8bc9c 100644 --- a/openair1/PHY/LTE_TRANSPORT/sss.c +++ b/openair1/PHY/LTE_TRANSPORT/sss.c @@ -166,7 +166,7 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue, int32_t **rxdataF; - LOG_I(PHY,"do_pss_sss_extract subframe %d \n",subframe); + //LOG_I(PHY,"do_pss_sss_extract subframe %d \n",subframe); for (aarx=0; aarxnb_antennas_rx; aarx++) { if (frame_parms->frame_type == FDD) { diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index b84d4fad36..9ae1dc6603 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -515,10 +515,8 @@ uint32_t ulsch_encoding(uint8_t *a, G = G - Q_RI - Q_CQI; ulsch->harq_processes[harq_pid]->G = G; - - LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), " - "Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial, - ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK); +/* + LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK); LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n", frame_parms->Nid_cell,ulsch->rnti, @@ -529,7 +527,7 @@ uint32_t ulsch_encoding(uint8_t *a, ulsch->O_RI, ulsch->harq_processes[harq_pid]->O_ACK, G); - +*/ if ((int)G < 0) { LOG_E(PHY,"FATAL: ulsch_coding.c G < 0 (%d) : Q_RI %d, Q_CQI %d, O %d, betaCQI_times8 %d)\n",G,Q_RI,Q_CQI,ulsch->O,ulsch->beta_offset_cqi_times8); diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index ef2cd62882..3a3b3b4c0d 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -117,8 +117,6 @@ int slot_fep(PHY_VARS_UE *ue, if (l==0) { - LOG_I(PHY,"FFT odfm symbol %d Slot %d \n",symbol,Ns); - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((short *)&common_vars->rxdata[aa][frame_length_samples], (short *)&common_vars->rxdata[aa][0], diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index ae64cceb59..3b2071d735 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -343,7 +343,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, o_ACK[cw_idx] = harq_ack[subframe_dl0].ack; status = harq_ack[subframe_dl0].send_harq_status; - LOG_I(PHY,"dl subframe %d send_harq_status %d cw_idx %d, reset %d\n",subframe_dl0, status, cw_idx, do_reset); + //LOG_I(PHY,"dl subframe %d send_harq_status %d cw_idx %d, reset %d\n",subframe_dl0, status, cw_idx, do_reset); if(do_reset) harq_ack[subframe_dl0].send_harq_status = 0; //printf("get_ack: Getting ACK/NAK for PDSCH (subframe %d) => %d\n",subframe_dl,o_ACK[0]); @@ -472,9 +472,9 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, pN_bundled[0] = harq_ack[subframe_rx].vDAI_UL; status = harq_ack[subframe_dl0].send_harq_status + harq_ack[subframe_dl1].send_harq_status; - LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d o_Ack %d, dl Sfn1 %d status %d o_Ack %d subframe_rx %d N_bundled %d \n", - subframe_tx, subframe_dl0, harq_ack[subframe_dl0].send_harq_status,harq_ack[subframe_dl0].ack, - subframe_dl1, harq_ack[subframe_dl1].send_harq_status,harq_ack[subframe_dl1].ack, subframe_rx, pN_bundled[0]); + //LOG_D(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d o_Ack %d, dl Sfn1 %d status %d o_Ack %d subframe_rx %d N_bundled %d \n", + // subframe_tx, subframe_dl0, harq_ack[subframe_dl0].send_harq_status,harq_ack[subframe_dl0].ack, + // subframe_dl1, harq_ack[subframe_dl1].send_harq_status,harq_ack[subframe_dl1].ack, subframe_rx, pN_bundled[0]); if (do_reset) { // reset ACK/NACK status harq_ack[subframe_dl0].ack = 2; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 362356c3c1..c0ec782649 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -453,21 +453,15 @@ void compute_cqi_ri_resources(PHY_VARS_UE *ue, uint8_t cqi_status, uint8_t ri_status) { - PHY_MEASUREMENTS *meas = &ue->measurements; - uint8_t transmission_mode = ue->transmission_mode[eNB_id]; + //PHY_MEASUREMENTS *meas = &ue->measurements; + //uint8_t transmission_mode = ue->transmission_mode[eNB_id]; - LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format); + //LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format); if (cqi_status == 1 || ri_status == 1) { ulsch->O = 4; } - else - { - //ulsch->O_RI = 0; - //ulsch->O = 0; - //ulsch->uci_format = HLC_subband_cqi_nopmi; - } } void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS) @@ -1408,8 +1402,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); } -//#ifdef DEBUG_PHY_PROC - LOG_I(PHY, +#ifdef DEBUG_PHY_PROC + LOG_D(PHY, "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d, Nbundled %d, CQI %d, RI %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx, @@ -1428,7 +1422,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->bundling, Nbundled, cqi_status, ri_status); -//#endif +#endif @@ -1663,20 +1657,19 @@ void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8 int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) { - if ((ue->transmission_mode[eNB_id]<4)|| (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback // 4-bit CQI message - LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id], + /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id], ue->measurements.wideband_cqi_avg[eNB_id], sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id], - ue->transmission_mode[eNB_id])); + ue->transmission_mode[eNB_id]));*/ *len=4; return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id], ue->transmission_mode[eNB_id])); } else { // Mode 1-1 feedback, later - LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]); + //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]); *len=0; // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI) @@ -1792,7 +1785,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin if(ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag) { - LOG_I(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx); + LOG_D(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT); return; } @@ -1860,7 +1853,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // if nothing to report ==> exit function if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0) ) { - LOG_I(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n", + LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n", frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); return; } @@ -1885,7 +1878,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin (uint8_t *)&pucch_payload, &len); - LOG_I(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", + LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); @@ -1921,7 +1914,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif if(format == pucch_format1) { - LOG_I(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", + LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, @@ -1933,7 +1926,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin else { if (SR_payload>0) { - LOG_I(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", + LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, @@ -1946,7 +1939,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin Po_PUCCH, tx_amp); } else { - LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, @@ -3216,6 +3209,48 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs } // is_pmch_subframe=true } +void copy_harq_proc_struct(LTE_DL_UE_HARQ_t *harq_processes_dest, LTE_DL_UE_HARQ_t *current_harq_processes) +{ + harq_processes_dest->B = current_harq_processes->B ; + harq_processes_dest->C = current_harq_processes->C ; + harq_processes_dest->Cminus = current_harq_processes->Cminus ; + harq_processes_dest->Cplus = current_harq_processes->Cplus ; + harq_processes_dest->DCINdi = current_harq_processes->DCINdi ; + harq_processes_dest->F = current_harq_processes->F ; + harq_processes_dest->G = current_harq_processes->G ; + harq_processes_dest->Kminus = current_harq_processes->Kminus ; + harq_processes_dest->Kplus = current_harq_processes->Kplus ; + harq_processes_dest->Nl = current_harq_processes->Nl ; + harq_processes_dest->Qm = current_harq_processes->Qm ; + harq_processes_dest->TBS = current_harq_processes->TBS ; + harq_processes_dest->b = current_harq_processes->b ; + harq_processes_dest->codeword = current_harq_processes->codeword ; + harq_processes_dest->delta_PUCCH = current_harq_processes->delta_PUCCH ; + harq_processes_dest->dl_power_off = current_harq_processes->dl_power_off ; + harq_processes_dest->first_tx = current_harq_processes->first_tx ; + harq_processes_dest->mcs = current_harq_processes->mcs ; + harq_processes_dest->mimo_mode = current_harq_processes->mimo_mode ; + harq_processes_dest->nb_rb = current_harq_processes->nb_rb ; + harq_processes_dest->pmi_alloc = current_harq_processes->pmi_alloc ; + harq_processes_dest->rb_alloc_even[0] = current_harq_processes->rb_alloc_even[0] ; + harq_processes_dest->rb_alloc_even[1] = current_harq_processes->rb_alloc_even[1] ; + harq_processes_dest->rb_alloc_even[2] = current_harq_processes->rb_alloc_even[2] ; + harq_processes_dest->rb_alloc_even[3] = current_harq_processes->rb_alloc_even[3] ; + harq_processes_dest->rb_alloc_odd[0] = current_harq_processes->rb_alloc_odd[0] ; + harq_processes_dest->rb_alloc_odd[1] = current_harq_processes->rb_alloc_odd[1] ; + harq_processes_dest->rb_alloc_odd[2] = current_harq_processes->rb_alloc_odd[2] ; + harq_processes_dest->rb_alloc_odd[3] = current_harq_processes->rb_alloc_odd[3] ; + harq_processes_dest->round = current_harq_processes->round ; + harq_processes_dest->rvidx = current_harq_processes->rvidx ; + harq_processes_dest->status = current_harq_processes->status ; + harq_processes_dest->vrb_type = current_harq_processes->vrb_type ; +} + +void copy_ack_struct(harq_status_t *harq_ack_dest, harq_status_t *current_harq_ack) +{ + memcpy(harq_ack_dest, current_harq_ack, sizeof(harq_status_t)); +} + void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, LTE_UE_DLSCH_t *dlsch0, LTE_UE_DLSCH_t *dlsch1, int s0, int s1, int abstraction_flag) { int subframe_rx = proc->subframe_rx; @@ -3752,8 +3787,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue->frame_parms.samples_per_tti * 4)); // start timers - printf("\n"); - LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + + LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); start_meas(&ue->phy_proc_rx[subframe_rx&0x1]); start_meas(&ue->generic_stat); @@ -3808,8 +3843,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin l=1; } - LOG_I(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_I(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); for (; l<=l2; l++) { if (abstraction_flag == 0) { start_meas(&ue->ofdm_demod_stats); @@ -3827,7 +3862,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); if ((l==pilot1) || ((pmch_flag==1)&(l==l2))) { - LOG_I(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); + LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); @@ -3938,8 +3973,6 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin stop_meas(&ue->ofdm_demod_stats); } - LOG_I(PHY," Measurement slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); } // for l=1..l2 @@ -4097,6 +4130,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } // duplicate harq structure + uint8_t current_harq_pid = ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid; LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[current_harq_pid]; LTE_DL_UE_HARQ_t *harq_processes_dest = ue->dlsch[(subframe_rx+1)&0x1][eNB_id][0]->harq_processes[current_harq_pid]; @@ -4104,13 +4138,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_ack[subframe_rx]; harq_status_t *harq_ack_dest = &ue->dlsch[(subframe_rx+1)&0x1][eNB_id][0]->harq_ack[subframe_rx]; - memcpy(harq_processes_dest, current_harq_processes, sizeof(LTE_DL_UE_HARQ_t)); - memcpy(harq_ack_dest, current_harq_ack, sizeof(harq_status_t)); - - //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.status %d DestHarqProcess.status %d\n",frame_rx%1024,subframe_rx,current_harq_processes->status,harq_processes_dest->status); - //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.round %d DestHarqProcess.round %d\n",frame_rx%1024,subframe_rx,current_harq_processes->round,harq_processes_dest->round); - //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.delta_PUCCH %d DestHarqProcess.delta_PUCCH %d\n",frame_rx%1024,subframe_rx,current_harq_processes->delta_PUCCH,harq_processes_dest->delta_PUCCH); - //LOG_I(PHY,"AbsSubframe %d.%d CurrentHarqProcess.rvidx %d DestHarqProcess.rvidx %d\n",frame_rx%1024,subframe_rx,current_harq_processes->rvidx,harq_processes_dest->rvidx); + copy_harq_proc_struct(harq_processes_dest, current_harq_processes); + copy_ack_struct(harq_ack_dest, current_harq_ack); if (subframe_rx==9) { if (frame_rx % 10 == 0) { diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 0747c82949..f07a0628f8 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -754,8 +754,7 @@ void *UE_thread(void *arg) { UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) UE->rx_offset_diff = 1; - LOG_I(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); - + LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); readBlockSize=UE->frame_parms.samples_per_tti - UE->frame_parms.ofdm_symbol_size - UE->frame_parms.nb_prefix_samples0 - From f2f79a16478069bbfd5bfd2048ed7773af4635fa Mon Sep 17 00:00:00 2001 From: gabrielC Date: Wed, 3 May 2017 15:42:32 +0200 Subject: [PATCH 533/571] Remove subframe_DL function npot anymore needed --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 +- openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c | 6 +- .../PHY/LTE_TRANSPORT/dlsch_demodulation.c | 2 +- openair1/PHY/TOOLS/lte_phy_scope.c | 16 +- openair1/PHY/TOOLS/lte_phy_scope_tm4.c | 28 +- openair1/SCHED/defs.h | 5 - openair1/SCHED/phy_procedures_lte_common.c | 31 -- openair1/SCHED/phy_procedures_lte_ue.c | 96 +++--- openair1/SCHED/pucch_pc.c | 10 +- openair1/SIMULATION/LTE_PHY/dlsim.c | 38 +- openair1/SIMULATION/LTE_PHY/dlsim_tm4.c | 324 +++++++++--------- openair1/SIMULATION/LTE_PHY/dlsim_tm7.c | 108 +++--- openair1/SIMULATION/LTE_PHY/ulsim.c | 8 +- 13 files changed, 320 insertions(+), 356 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index aec6d734d3..5aa676da9a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -7209,7 +7209,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, uint8_t transmission_mode = ue->transmission_mode[eNB_id]; ANFBmode_t AckNackFBMode; LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; - LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][0]; + LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe&0x1][0]; PHY_MEASUREMENTS *meas = &ue->measurements; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; // uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; @@ -8016,7 +8016,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); int dl_subframe = subframe; - if (ue->dlsch[subframe_DL(&ue->frame_parms,dl_subframe)&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission + if (ue->dlsch[dl_subframe&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission ulsch->harq_processes[harq_pid]->O_ACK = 1; } else { ulsch->harq_processes[harq_pid]->O_ACK = 0; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 1ee6907271..05f458e94a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -929,7 +929,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; case PDSCH: // TB0 - dlsch_ue = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]; + dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]; harq_pid = dlsch_ue->current_harq_pid; ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[subframe & 0x1][(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]); DevAssert( ue_id != (uint32_t)-1 ); @@ -975,7 +975,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; case PDSCH1: { // TB1 - dlsch_ue = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]; + dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]; harq_pid = dlsch_ue->current_harq_pid; int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[subframe & 0x1][eNB_id]->crnti, PHY_vars_eNB_g[eNB_id2][CC_id] ); DevAssert( UE_id != -1 ); @@ -1029,7 +1029,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue, break; default: - dlsch_ue = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]; + dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]; LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id); dlsch_ue->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations; return(1+dlsch_ue->max_turbo_iterations); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index ecaf7cd121..1450209c26 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -146,7 +146,7 @@ int rx_pdsch(PHY_VARS_UE *ue, case PDSCH: pdsch_vars = ue->pdsch_vars[subframe&0x1]; - dlsch = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id]; + dlsch = ue->dlsch[subframe&0x1][eNB_id]; LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame,subframe,symbol,harq_pid, dlsch[0]->harq_processes[harq_pid]->status, diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 5bf5cf20e0..cea702ef78 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -514,16 +514,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { - harq_pid = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; + mcs = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 - if(!phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { + if(!phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { // we are in TM5 fl_show_object(form->button_0); } @@ -534,12 +534,12 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { coded_bits_per_codeword = get_G(frame_parms, - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs), - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index 322f8e02c7..92a0d9f218 100755 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -448,11 +448,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, int mcs1=0; unsigned char harq_pid = 0; int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { - harq_pid = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; if (harq_pid>=8) return; - mcs0 = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; + mcs0 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs; // Button 0 /* if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) { @@ -461,23 +461,23 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } */ } - if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]!=NULL) { - harq_pid = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid; + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) { + harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid; if (harq_pid>=8) return; - mcs1 = phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs; + mcs1 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs; } if (phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]!=NULL) { num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols; } // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); - if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]!=NULL) { + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) { mod0 = get_Qm(mcs0); coded_bits_per_codeword0 = get_G(frame_parms, - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs0), - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, @@ -486,13 +486,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); mod0=0; } - if (phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]!=NULL) { + if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) { mod1 = get_Qm(mcs1); coded_bits_per_codeword1 = get_G(frame_parms, - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->nb_rb, - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->nb_rb, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even, get_Qm(mcs1), - phy_vars_ue->dlsch[subframe_DL(&phy_vars_ue->frame_parms,subframe)&0x1][eNB_id][1]->harq_processes[harq_pid]->Nl, + phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->Nl, num_pdcch_symbols, frame, subframe, diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index 7d0ff20b9c..10d9d69c52 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -212,11 +212,6 @@ void prach_procedures(PHY_VARS_eNB *eNB); lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); -/*! - * \brief Function that return the DL SFN, used for TDD where the DL is not always 4 SFN before UL -*/ - -uint8_t subframe_DL(LTE_DL_FRAME_PARMS *frame_parms,uint8_t current_sfn); /*! \brief Function to compute which type of DCIs to detect in the given subframe @param frame_parms Pointer to DL frame parameter descriptor diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index 3b2071d735..314f934a81 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -619,37 +619,6 @@ lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub } } -uint8_t subframe_DL(LTE_DL_FRAME_PARMS *frame_parms,uint8_t current_sfn) -{ - - // if FDD return dummy value - if (frame_parms->frame_type == FDD) - return(current_sfn); - - switch (frame_parms->tdd_config) { - - case 1: - switch (current_sfn) { - case 3: - case 8: - return(current_sfn-3); - break; - - default: - return(current_sfn); - break; - } - - case 3: - return(current_sfn); - break; - - default: - AssertFatal(0,"TDD config %d not coded",frame_parms->tdd_config); - - } -} - dci_detect_mode_t dci_detect_mode_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { dci_detect_mode_t ret = 0; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index c0ec782649..05a22c5241 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -91,10 +91,10 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; coded_bits_per_codeword = get_G(&ue->frame_parms, - ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, - ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm, - ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm, + ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl, ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols, proc->frame_rx, subframe, @@ -528,7 +528,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id uint8_t pucch_ack_payload[2]; if (get_ack(&ue->frame_parms, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0) { is_sr_an_subframe = 1; @@ -829,11 +829,11 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; // set ACK/NAK to values if not DTX - if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed - harq_ack1 = ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack; + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack; - if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack0 = ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack[5+last_dl].ack; + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].ack; if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed @@ -1341,21 +1341,21 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } ack_status_cw0 = reset_ack(&ue->frame_parms, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx, proc->subframe_rx, ue->ulsch[eNB_id]->o_ACK, &Nbundled, 0); ack_status_cw1 = reset_ack(&ue->frame_parms, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][1]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack, subframe_tx, proc->subframe_rx, ue->ulsch[eNB_id]->o_ACK, &NbundledCw1, 1); - //Nbundled = ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack; + //Nbundled = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack; //ue->ulsch[eNB_id]->bundling = Nbundled; first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb; @@ -1383,14 +1383,14 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB if(ue->ulsch[eNB_id]->o_ACK[0]) { LOG_I(PHY,"PUSCH ACK\n"); - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } else { LOG_I(PHY,"PUSCH NACK\n"); - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } #endif @@ -1711,7 +1711,7 @@ void get_pucch_param(PHY_VARS_UE *ue, { pucch_resource[0] = get_n1_pucch(ue, proc, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, eNB_id, ack_payload, SR); @@ -1828,14 +1828,14 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } ack_status_cw0 = get_ack(&ue->frame_parms, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx, proc->subframe_rx, pucch_ack_payload, 0); ack_status_cw1 = get_ack(&ue->frame_parms, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][1]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack, subframe_tx, proc->subframe_rx, pucch_ack_payload, @@ -1910,13 +1910,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif if(format == pucch_format1) { LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, isShortenPucch, @@ -1928,7 +1928,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin if (SR_payload>0) { LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx % 1024, subframe_tx, (format == pucch_format1a? "1a": ( format == pucch_format1b? "1b" : "??")), @@ -1941,7 +1941,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } else { LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx,ue->rx_offset_diff, (format == pucch_format1a? "1a": ( format == pucch_format1b? "1b" : "??")), @@ -1956,13 +1956,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #if T_TRACER if(pucch_payload[0]) { - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } else { - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti), - T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->current_harq_pid)); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti), + T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid)); } #endif @@ -2015,12 +2015,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin #endif #if T_TRACER T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); #endif LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n", Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx, n2_pucch, Po_PUCCH, @@ -2045,13 +2045,13 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin case pucch_format2a: LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n", Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); break; case pucch_format2b: LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n", Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti, frame_tx%1024, subframe_tx); break; default: @@ -2194,17 +2194,17 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui // reset DL ACK/NACK status uint8_t N_bundled = 0; - if (ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0] != NULL) + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0] != NULL) { reset_ack(&ue->frame_parms, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->harq_ack, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack, subframe_tx, proc->subframe_rx, ue->ulsch[eNB_id]->o_ACK, &N_bundled, 0); reset_ack(&ue->frame_parms, - ue->dlsch[(subframe_DL(&ue->frame_parms,proc->subframe_rx)+1)&0x1][eNB_id][0]->harq_ack, + ue->dlsch[(proc->subframe_rx+1)&0x1][eNB_id][0]->harq_ack, subframe_tx, proc->subframe_rx, ue->ulsch[eNB_id]->o_ACK, @@ -2412,8 +2412,8 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id) emos_dump_UE.total_TBS_last = ue->total_TBS_last[eNB_id]; emos_dump_UE.bitrate = ue->bitrate[eNB_id]; emos_dump_UE.total_received_bits = ue->total_received_bits[eNB_id]; - emos_dump_UE.pmi_saved = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->pmi_alloc; - emos_dump_UE.mcs = ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_DL(&ue->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mcs; + emos_dump_UE.pmi_saved = ue->dlsch[subframe&0x1][eNB_id][0]->pmi_alloc; + emos_dump_UE.mcs = ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mcs; emos_dump_UE.use_ia_receiver = openair_daq_vars.use_ia_receiver; bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE)); @@ -2845,7 +2845,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint (dci_alloc_rx[i].format == format2A) || (dci_alloc_rx[i].format == format2B)) { - ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH; + ue->dlsch[subframe_rx&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH; } ue->dlsch_received[eNB_id]++; @@ -2853,7 +2853,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format); dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active); + LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_rx&0x1][eNB_id][0]->active); #endif // we received a CRNTI, so we're in PUSCH @@ -3796,10 +3796,10 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // deactivate reception until we scan pdcch - if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]) - ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active = 0; - if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][1]) - ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][1]->active = 0; + if (ue->dlsch[subframe_rx&0x1][eNB_id][0]) + ue->dlsch[subframe_rx&0x1][eNB_id][0]->active = 0; + if (ue->dlsch[subframe_rx&0x1][eNB_id][1]) + ue->dlsch[subframe_rx&0x1][eNB_id][1]->active = 0; if (ue->dlsch_SI[eNB_id]) ue->dlsch_SI[eNB_id]->active = 0; @@ -3895,13 +3895,13 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin start_meas(&ue->generic_stat); // do procedures for C-RNTI - if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active == 1) { + if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0], + ue->dlsch[subframe_rx&0x1][eNB_id][0], NULL, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols, ue->frame_parms.symbols_per_tti>>1, @@ -4002,14 +4002,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // do procedures for C-RNTI LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - if (ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0]->active == 1) { + if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); start_meas(&ue->pdsch_procedures_stat); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0], + ue->dlsch[subframe_rx&0x1][eNB_id][0], NULL, 1+(ue->frame_parms.symbols_per_tti>>1), ue->frame_parms.symbols_per_tti-1, @@ -4024,8 +4024,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin proc, eNB_id, PDSCH, - ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][0], - ue->dlsch[subframe_DL(&ue->frame_parms,subframe_rx)&0x1][eNB_id][1], + ue->dlsch[subframe_rx&0x1][eNB_id][0], + ue->dlsch[subframe_rx&0x1][eNB_id][1], &ue->dlsch_errors[eNB_id], mode, abstraction_flag); diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c index 3f7ec5bc34..1a1289ab88 100644 --- a/openair1/SCHED/pucch_pc.c +++ b/openair1/SCHED/pucch_pc.c @@ -52,7 +52,7 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u Po_PUCCH = get_PL(ue->Mod_id,ue->CC_id,eNB_id)+ ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+ - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch; + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch; switch (pucch_fmt) { case pucch_format1: @@ -91,19 +91,19 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u if (pucch_fmt!=pucch_format1) { LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch); + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch); } else { LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n", ue->Mod_id, - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe, Po_PUCCH, ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH, get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->dlsch[subframe_DL(&ue->frame_parms,proc->subframe_rx)&0x1][eNB_id][0]->g_pucch); + ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch); } return(Po_PUCCH); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 9b12c4b27a..b8e23f2d98 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -2105,14 +2105,14 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]) { + if (!UE->dlsch[subframe&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]->rnti = n_rnti; + UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; } UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); @@ -2500,7 +2500,7 @@ int main(int argc, char **argv) if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); phy_procedures_UE_RX(UE,proc,0,0,normal_txrx,no_relay,NULL); - if (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->active == 0) { + if (UE->dlsch[subframe&0x1][0][0]->active == 0) { //printf("DCI not received\n"); dci_errors[round]++; UE->dlsch_errors[0] = 1; @@ -2558,7 +2558,7 @@ int main(int argc, char **argv) //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); @@ -2576,13 +2576,13 @@ int main(int argc, char **argv) if (UE->dlsch_errors[0] == 0) { - avg_iter += UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->last_iteration_cnt; + avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt; iter_trials++; if (n_frames==1) printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; @@ -2590,25 +2590,25 @@ int main(int argc, char **argv) else { errs[round]++; - avg_iter += UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->last_iteration_cnt-1; + avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt-1; iter_trials++; if (n_frames==1) { //if ((n_frames==1) || (SNR>=30)) { printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); - for (s=0; sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->C; s++) { - if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus; + for (s=0; sdlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) { + if (sdlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0; idlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -2659,13 +2659,13 @@ int main(int argc, char **argv) } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); //write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); //write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); //write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - //write_output("dlsch_w.m","w",UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + //write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); //pdcch_vars write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); @@ -2679,7 +2679,7 @@ int main(int argc, char **argv) // printf("round %d errors %d/%d\n",round,errs[round],trials); round++; - // UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round++; + // UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++; } if (xforms==1) { @@ -2869,7 +2869,7 @@ int main(int argc, char **argv) //rate*effective_rate, 100*effective_rate, //rate, - //rate*get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), + //rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -2946,7 +2946,7 @@ int main(int argc, char **argv) printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -3235,7 +3235,7 @@ int main(int argc, char **argv) printf("eNB %d\n",i); free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]); + free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index a09d71062a..57742c5e13 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -981,15 +981,15 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]) { + if (!UE->dlsch[subframe&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]->rnti = n_rnti; + UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; } // structure for SIC at UE @@ -2137,8 +2137,8 @@ int main(int argc, char **argv) eNB2UE[0]->first_run = 1; - ret[0] = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations+1; - ret[1] = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations+1; + ret[0] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; + ret[1] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; resend_cw0_cw1=1; resend_cw1=0; @@ -2146,10 +2146,10 @@ int main(int argc, char **argv) TB1_active=1; while (((transmission_mode == 3 || transmission_mode == 4) && - ((round < num_rounds) && ((ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) || - (ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)))) || + ((round < num_rounds) && ((ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) || + (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) || ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) && - (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)))) { + (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) { #ifdef DEBUG_HARQ printf("\n [DLSIM] On top round is %d\n", round); #endif @@ -2160,10 +2160,10 @@ int main(int argc, char **argv) //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]); - /*if (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) { + /*if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) { round_trials[0][round]++; round_trials[1][round]++; - } else if ((ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)) + } else if ((ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) round_trials[1][round]++;*/ @@ -2626,7 +2626,7 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->pmi_alloc, + UE->dlsch[subframe&0x1][0][1]->pmi_alloc, transmission_mode>=7?transmission_mode:0 ); break; @@ -2854,7 +2854,7 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->pmi_alloc, + UE->dlsch[subframe&0x1][0][1]->pmi_alloc, transmission_mode>=7?transmission_mode:0 ); break; @@ -2985,7 +2985,7 @@ int main(int argc, char **argv) // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); if (n_users>1) eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); /* @@ -3009,7 +3009,7 @@ int main(int argc, char **argv) printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); } else if (updated_csi == 0){ @@ -3022,7 +3022,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); } else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ @@ -3033,7 +3033,7 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I am calling from the eNode B 2\n"); #endif - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); } } else if (updated_csi == 1){ @@ -3052,11 +3052,11 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I quantize from ENodeB 2\n"); #endif - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); #ifdef DEBUG_HARQ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL); } else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){ #ifdef DEBUG_HARQ @@ -3072,11 +3072,11 @@ int main(int argc, char **argv) #ifdef DEBUG_HARQ printf ("[DLSIM] I quantize from ENodeB 2\n"); #endif - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); #ifdef DEBUG_HARQ printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n"); #endif - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL); } } @@ -3525,10 +3525,10 @@ int main(int argc, char **argv) //printf("Generating dlsch parameters for RNTI %x\n",dci_alloc_rx[i].rnti); if (round == 0) { - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; } if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) { - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1; } if ((dci_alloc_rx[i].rnti == n_rnti) && @@ -3537,7 +3537,7 @@ int main(int argc, char **argv) dci_alloc_rx[i].dci_pdu, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3547,30 +3547,30 @@ int main(int argc, char **argv) UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0)==0)) { dump_dci(&UE->frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword[0]= get_G(&eNB->frame_parms, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->nb_rb, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->Nl, - UE->pdcch_vars[subframe_DL(&UE->frame_parms,subframe)&0x1][0]->num_pdcch_symbols, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, + UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); if (transmission_mode == 3 || transmission_mode == 4) { coded_bits_per_codeword[1]= get_G(&eNB->frame_parms, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->nb_rb, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->Nl, + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[subframe&0x1][1]->num_pdcch_symbols, 0, subframe, transmission_mode>=7?transmission_mode:0); } /* - rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); - rate*=get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs); + rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs); */ - printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->TBS); + printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); dlsch_active = 1; // what does it indicates??? } else { @@ -3594,8 +3594,8 @@ int main(int argc, char **argv) UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti; UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols; if (round == 0) { - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx=1; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1; } switch (transmission_mode) { @@ -3606,7 +3606,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format1 : format1A, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3617,14 +3617,14 @@ int main(int argc, char **argv) break; case 3: - //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); + //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); generate_ue_dlsch_params_from_dci(0, subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2A : format1A, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3632,7 +3632,7 @@ int main(int argc, char **argv) P_RNTI, transmission_mode<7?0:transmission_mode, UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0); - //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); + //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); break; case 4: generate_ue_dlsch_params_from_dci(0, @@ -3640,7 +3640,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A,//format1A only for a codeblock - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3657,7 +3657,7 @@ int main(int argc, char **argv) &DLSCH_alloc_pdu2_1E[0], C_RNTI, format1E_2A_M10PRB, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3673,13 +3673,13 @@ int main(int argc, char **argv) if (dlsch_active == 1) { if (TB0_active==1) - cur_harq_pid =UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid; + cur_harq_pid =UE->dlsch[subframe&0x1][0][0]->current_harq_pid; else - cur_harq_pid =UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid; + cur_harq_pid =UE->dlsch[subframe&0x1][0][1]->current_harq_pid; if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix /* if (transmission_mode == 5) { - if ((UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && + if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) && (openair_daq_vars.use_ia_receiver ==1)) { rx_type = rx_IC_single_stream; } else { @@ -3701,7 +3701,7 @@ int main(int argc, char **argv) (m==UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols)?1:0, rx_type, i_mod, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1){ + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1){ dlsch_active = 0; break; } @@ -3788,7 +3788,7 @@ int main(int argc, char **argv) break; } - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe&0x1][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[TB] = get_G(&eNB->frame_parms, eNB->dlsch[0][TB]->harq_processes[0]->nb_rb, eNB->dlsch[0][TB]->harq_processes[0]->rb_alloc, @@ -3798,12 +3798,12 @@ int main(int argc, char **argv) 0,subframe, transmission_mode>=7?transmission_mode:0); - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs); + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB]; + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs); if (n_frames==2) { printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->TBS); + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]); @@ -3812,7 +3812,7 @@ int main(int argc, char **argv) sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB); sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB); - write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); + write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0); sprintf(fname,"dlsch_cw%d_e.m", TB); sprintf(vname,"dlschcw%d_e", TB); write_output(fname, vname,eNB->dlsch[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4); @@ -3820,7 +3820,7 @@ int main(int argc, char **argv) printf("trials=%d\n", trials); for (i=0;idlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword][i]<0)) { + if (eNB->dlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } @@ -3842,22 +3842,22 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, 0, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB], + UE->dlsch[subframe&0x1][0][TB], coded_bits_per_codeword[TB], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword], TB, subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); start_meas(&UE->dlsch_decoding_stats[subframe&0x1]); ret[TB] = dlsch_decoding(UE, - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword], &UE->frame_parms, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid], + UE->dlsch[subframe&0x1][0][TB], + UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid], 0, subframe, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->current_harq_pid, + UE->dlsch[subframe&0x1][0][TB]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]); #ifdef DEBUG_HARQ @@ -3865,11 +3865,11 @@ int main(int argc, char **argv) #endif //printf("retr cw 0 = %d\n", ret[0]); - //printf("current round = %d\n", UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw_non_sic]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw_non_sic]->current_harq_pid]->round); + //printf("current round = %d\n", UE->dlsch[subframe&0x1][0][cw_non_sic]->harq_processes[UE->dlsch[subframe&0x1][0][cw_non_sic]->current_harq_pid]->round); - if (ret[TB] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 + if (ret[TB] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1 #ifdef DEBUG_HARQ printf("[DLSIM] TB%d is decoded\n", TB); #endif @@ -3880,33 +3880,33 @@ int main(int argc, char **argv) if (n_frames==2) { printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->C;s++) { - if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); } #endif } - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][TB]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][TB]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][TB]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][TB]->current_harq_pid]->TBS; // If the receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained) - if (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* - //for (round = 0 ; round < UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { + //for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { // we assume here that the second stream has a lower MCS and is thus more likely to be decoded // re-encoding of second stream - dlsch0_ue_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = LARGE_CDD; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0]; @@ -3920,14 +3920,14 @@ int main(int argc, char **argv) dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->active = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->active; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->rnti = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->rnti; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; + UE->dlsch[subframe&0x1][eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; + UE->dlsch[subframe&0x1][eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; + UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; - dlsch_encoding(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->b, + dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id], + UE->dlsch[subframe&0x1][eNB_id], 0,subframe, &UE->dlsch_rate_matching_stats, &UE->dlsch_turbo_encoding_stats, @@ -3935,10 +3935,10 @@ int main(int argc, char **argv) ); coded_bits_per_codeword = get_G(&UE->frame_parms, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->nb_rb, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->rb_alloc, - get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->mcs), - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->current_harq_pid]->Nl, + UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->rb_alloc, + get_Qm(UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->Nl, num_pdcch_symbols, 0,subframe); @@ -3946,7 +3946,7 @@ int main(int argc, char **argv) //scrambling dlsch_scrambling(&UE->frame_parms, 0, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id], + UE->dlsch[subframe&0x1][eNB_id], coded_bits_per_codeword, 0, subframe<<1); @@ -3958,7 +3958,7 @@ int main(int argc, char **argv) subframe, &UE->frame_parms, num_pdcch_symbols, - &UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0], + &UE->dlsch[subframe&0x1][0][0], NULL); // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding // precoding is contained in effective channel estimate @@ -3998,8 +3998,8 @@ int main(int argc, char **argv) } - if ((UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && + if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) && (rx_type==rx_SIC_dual_stream)) { #ifdef DEBUG_HARQ printf("[DLSIM] Starting SIC procedure\n"); @@ -4018,10 +4018,10 @@ int main(int argc, char **argv) #endif //printf("I enter round_sic loop \n"); //printf("round_sic= %d\n", round_sic); - dlsch0_ue_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq->mimo_mode = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode; + dlsch0_eNB_harq->mimo_mode = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs; @@ -4033,25 +4033,25 @@ int main(int argc, char **argv) dlsch0_eNB_harq->status = dlsch0_ue_harq->status; if (round_sic == 0){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 0; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=0; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 0; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=0; } else if (round_sic == 1){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 1; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=1; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 1; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=1; } else if (round_sic == 2){ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 2; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=2; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 2; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=2; } else{ - UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][1]->current_harq_pid]->rvidx = 3; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->rvidx=3; + UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx = 3; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=3; } - UE->dlsch_eNB[eNB_id]->active = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->active; - UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->rnti; - UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid; + UE->dlsch_eNB[eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; + UE->dlsch_eNB[eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; + UE->dlsch_eNB[eNB_id]->current_harq_pid = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid; dlsch_encoding_SIC(UE, input_buffer0[0], //UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,, @@ -4089,8 +4089,8 @@ int main(int argc, char **argv) coded_bits_per_codeword[0]); // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1); - // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); - // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); + // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1); switch (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){ @@ -4100,58 +4100,58 @@ int main(int argc, char **argv) case 2: dlsch_qpsk_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]); + UE->dlsch[subframe&0x1][eNB_id][0]); break; case 4: dlsch_16qam_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs), - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]); + UE->dlsch[subframe&0x1][eNB_id][0]); break; case 6: dlsch_64qam_llr_SIC(&UE->frame_parms, - UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], sic_buffer, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], num_pdcch_symbols, - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], - UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], + UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic], dlsch0_eNB_harq->nb_rb, subframe, dlsch0_eNB_harq->rb_alloc[0], get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][TB]); + UE->dlsch[subframe&0x1][eNB_id][TB]); break; } //}// rouns sic #ifdef DEBUG_HARQ - printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword); + printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword); #endif // write_output("rxdata_llr1.m","llr1", UE->pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0); // replace cw_sic with TB+1 - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe&0x1][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword[1]= get_G(&eNB->frame_parms, eNB->dlsch[0][1]->harq_processes[0]->nb_rb, eNB->dlsch[0][1]->harq_processes[0]->rb_alloc, @@ -4162,12 +4162,12 @@ int main(int argc, char **argv) subframe, transmission_mode>=7?transmission_mode:0); - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs); + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1]; + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs); if (n_frames==2) { printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->TBS); + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->TBS); // calculate uncoded BER uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]); @@ -4181,7 +4181,7 @@ int main(int argc, char **argv) uncoded_ber=0; printf("trials=%d\n", trials); for (i=0;idlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword][i]<0)) { + if (eNB->dlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; } @@ -4203,7 +4203,7 @@ int main(int argc, char **argv) 0, UE->dlsch[subframe&0x1][0][1], coded_bits_per_codeword[1], - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], 1, subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); @@ -4211,13 +4211,13 @@ int main(int argc, char **argv) start_meas(&UE->dlsch_decoding_stats[subframe&0x1]); ret[1] = dlsch_decoding(UE, - UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid]->codeword], + UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword], &UE->frame_parms, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid], + UE->dlsch[subframe&0x1][0][1], + UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid], 0, subframe, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->current_harq_pid, + UE->dlsch[subframe&0x1][0][1]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]); @@ -4227,7 +4227,7 @@ int main(int argc, char **argv) //printf("ret TB 1 = %d round %d \n", ret[1], round); - if (ret[1] <=UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations ) { + if (ret[1] <=UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { decoded_in_sic[round]++; round_sic = round+1; // to exit round_sic #ifdef DEBUG_HARQ @@ -4241,19 +4241,19 @@ int main(int argc, char **argv) printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->C;s++) { - if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); } #endif } @@ -4261,7 +4261,7 @@ int main(int argc, char **argv) } //round_sic - if (ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations ){ + if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ){ errs[1][round]++; #ifdef DEBUG_HARQ printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]); @@ -4276,23 +4276,23 @@ int main(int argc, char **argv) //if ((n_frames==1) || (SNR>=30)) { printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->C;s++) { - if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]); } #endif } //n_frames==1 // exit(0); - } //if (ret > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][1]->max_turbo_iterations ) + } //if (ret > UE->dlsch[subframe&0x1][0][1]->max_turbo_iterations ) }//if SIC } else { @@ -4307,8 +4307,8 @@ int main(int argc, char **argv) iter_trials[0]++; }*/ - if ((UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && + if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) { errs[1][round]++; #ifdef DEBUG_HARQ @@ -4327,18 +4327,18 @@ int main(int argc, char **argv) //if ((n_frames==1) || (SNR>=30)) { printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber); #ifdef PRINT_BYTES - for (s=0;sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->C;s++) { - if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kminus; + for (s=0;sdlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) { + if (sdlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0;idlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i], + UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]); } #endif } @@ -4410,12 +4410,12 @@ int main(int argc, char **argv) UE->frame_parms.ofdm_symbol_size*nsymb,1,1); } //pdsch_vars - dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid); + dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid); /* write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("dlsch_eNB_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - write_output("dlsch_UE_w.m","w",UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + write_output("dlsch_UE_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); */ //pdcch_vars @@ -4439,15 +4439,15 @@ int main(int argc, char **argv) printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]); #endif - if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)){ + if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)){ //printf("flag 1 \n"); round++; } if (transmission_mode == 3 || transmission_mode == 4 ) { - if (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations && - ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations){ + if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && + ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ resend_both[round]++; round++; resend_cw0_cw1=1; //resend both cws @@ -4455,8 +4455,8 @@ int main(int argc, char **argv) TB0_active=1; TB1_active=1; } - else if (ret[1] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations && - ret[0] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations){ + else if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && + ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ resend_one[round]++; resend_cw0_cw1=0; TB0_active=0; @@ -4476,8 +4476,8 @@ int main(int argc, char **argv) #endif round++; } - else if (ret[0] > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations && - ret[1] <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations){ + else if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations && + ret[1] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){ resend_one[round]++; resend_cw0_cw1=0; TB0_active=1; @@ -4796,7 +4796,7 @@ int main(int argc, char **argv) rate[0]*effective_rate, 100*effective_rate, rate[0], - rate[0]*get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), + rate[0]*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+ 4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2]) @@ -4901,7 +4901,7 @@ int main(int argc, char **argv) printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -5326,7 +5326,7 @@ int main(int argc, char **argv) free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]); + free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 4f461cee39..3055e99b07 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -953,14 +953,14 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]) { + if (!UE->dlsch[subframe&0x1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]->rnti = n_rnti; + UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; } // structure for SIC at UE @@ -2112,9 +2112,9 @@ int main(int argc, char **argv) //if (trials%100==0) eNB2UE[0]->first_run = 1; - ret = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations+1; + ret = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1; - while ((round < num_rounds) && (ret > UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations)) { + while ((round < num_rounds) && (ret > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) { //printf("Trial %d, round %d\n",trials,round); round_trials[round]++; @@ -2601,7 +2601,7 @@ PMI_FEEDBACK: // use the PMI from previous trial if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL); - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL); if (n_users>1) eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555); @@ -3227,7 +3227,7 @@ PMI_FEEDBACK: for (i=0; idlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->first_tx=1; + if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->first_tx=1; if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, @@ -3235,7 +3235,7 @@ PMI_FEEDBACK: dci_alloc_rx[i].dci_pdu, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3244,23 +3244,23 @@ PMI_FEEDBACK: transmission_mode<7?0:transmission_mode))) { //dump_dci(&UE->frame_parms,&dci_alloc_rx[i]); coded_bits_per_codeword = get_G(&eNB->frame_parms, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->nb_rb, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->rb_alloc_even, - get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->Nl, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb, + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even, + get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[0]->num_pdcch_symbols, 0, subframe, (transmission_mode<7?0:transmission_mode)); /*if (transmission_mode==7 && common_flag==0) - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->mimo_mode = TM7; */ + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7; */ /* - rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); - rate*=get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs); + rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword); + rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs); */ printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->TBS); + UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS); dlsch_active = 1; } else { @@ -3288,7 +3288,7 @@ PMI_FEEDBACK: UE->pdcch_vars[0]->crnti = n_rnti; UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; - if (round == 0) UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx=1; + if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1; switch (transmission_mode) { case 1: @@ -3299,7 +3299,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format1 : format1A, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3307,24 +3307,24 @@ PMI_FEEDBACK: P_RNTI, transmission_mode<7?0:transmission_mode); /*if(transmission_mode==7 && common_flag==0) - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->mimo_mode = TM7;*/ + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7;*/ break; case 3: - // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); + // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); generate_ue_dlsch_params_from_dci(0, subframe, &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2A : format1A, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, 0, P_RNTI, 0); - // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->first_tx); + // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx); break; case 4: @@ -3333,7 +3333,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu_1[0], (common_flag==0)? C_RNTI : SI_RNTI, (common_flag==0)? format2 : format1A, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3349,7 +3349,7 @@ PMI_FEEDBACK: &DLSCH_alloc_pdu2_1E[0], C_RNTI, format1E_2A_M10PRB, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -3381,7 +3381,7 @@ PMI_FEEDBACK: if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix) if ((transmission_mode == 5) && - (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->dl_power_off==0) && + (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->dl_power_off==0) && (UE->use_ia_receiver ==1)) { dual_stream_UE = 1; } else { @@ -3404,7 +3404,7 @@ PMI_FEEDBACK: (m==UE->pdcch_vars[0]->num_pdcch_symbols)?1:0, dual_stream_UE, i_mod, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { dlsch_active = 0; break; } @@ -3430,7 +3430,7 @@ PMI_FEEDBACK: 0, dual_stream_UE, i_mod, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { dlsch_active=0; break; } @@ -3456,7 +3456,7 @@ PMI_FEEDBACK: 0, dual_stream_UE, i_mod, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid)==-1) { + UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) { dlsch_active=0; break; } @@ -3534,7 +3534,7 @@ PMI_FEEDBACK: } for (int cw=Kmimo-1; cw>=0; cw--) { - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; + UE->dlsch[subframe&0x1][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI; coded_bits_per_codeword = get_G(&eNB->frame_parms, eNB->dlsch[0][cw]->harq_processes[0]->nb_rb, eNB->dlsch[0][cw]->harq_processes[0]->rb_alloc, @@ -3545,7 +3545,7 @@ PMI_FEEDBACK: subframe, (transmission_mode<7?0:transmission_mode)); - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->current_harq_pid]->G = coded_bits_per_codeword; + UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid]->G = coded_bits_per_codeword; @@ -3580,15 +3580,15 @@ PMI_FEEDBACK: ret = dlsch_decoding(UE, UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw], &UE->frame_parms, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw], - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->current_harq_pid], + UE->dlsch[subframe&0x1][0][cw], + UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid], subframe, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->current_harq_pid, + UE->dlsch[subframe&0x1][0][cw]->current_harq_pid, 1,llr8_flag); stop_meas(&UE->dlsch_decoding_stats); if (cw==1) { - if (ret <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][cw]->max_turbo_iterations) { + if (ret <= UE->dlsch[subframe&0x1][0][cw]->max_turbo_iterations) { } else { errs2[round]++; } @@ -3599,7 +3599,7 @@ PMI_FEEDBACK: stop_meas(&UE->phy_proc_rx[subframe&0x1]); - if (ret <= UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->max_turbo_iterations) { + if (ret <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) { avg_iter += ret; iter_trials++; @@ -3607,15 +3607,15 @@ PMI_FEEDBACK: if (n_frames==1) printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); - UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->TBS; + UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; - if (UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC /* - for (round = 0 ; round < UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { + for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) { // re-encoding of first stream - dlsch0_ue_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; - dlsch0_eNB_harq = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; + dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]; dlsch0_eNB_harq->mimo_mode = LARGE_CDD; dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0]; dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb; @@ -3627,13 +3627,13 @@ PMI_FEEDBACK: dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off; dlsch0_eNB_harq->status = dlsch0_ue_harq->status; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->active = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->active; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id]->rnti = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->rnti; + UE->dlsch[subframe&0x1][eNB_id]->active = UE->dlsch[subframe&0x1][eNB_id][0]->active; + UE->dlsch[subframe&0x1][eNB_id]->rnti = UE->dlsch[subframe&0x1][eNB_id][0]->rnti; - dlsch_encoding(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][eNB_id][0]->current_harq_pid]->b, + dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b, &UE->frame_parms, num_pdcch_symbols, - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0], + UE->dlsch[subframe&0x1][0], 0,subframe, &UE->dlsch_rate_matching_stats, &UE->dlsch_turbo_encoding_stats, @@ -3660,18 +3660,18 @@ PMI_FEEDBACK: //if ((n_frames==1) || (SNR>=30)) printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); - for (s=0; sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->C; s++) { - if (sdlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus) - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus; + for (s=0; sdlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) { + if (sdlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus) + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus; else - Kr = UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus; + Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; printf("Decoded_output (Segment %d):\n",s); for (i=0; idlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -3726,7 +3726,7 @@ PMI_FEEDBACK: write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); - write_output("dlsch_w.m","w",UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); + write_output("dlsch_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); */ if (round == 3) exit(-1); @@ -3735,7 +3735,7 @@ PMI_FEEDBACK: // printf("round %d errors %d/%d\n",round,errs[round],trials); round++; - // UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->round++; + // UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++; } if (xforms==1) { @@ -3925,7 +3925,7 @@ PMI_FEEDBACK: rate*effective_rate, 100*effective_rate, rate, - rate*get_Qm(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->current_harq_pid]->mcs), + rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs), (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); @@ -4001,7 +4001,7 @@ PMI_FEEDBACK: printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][0]->harq_processes[0]->Kplus, + UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -4290,7 +4290,7 @@ PMI_FEEDBACK: printf("eNB %d\n",i); free_eNB_dlsch(eNB->dlsch[0][i]); printf("UE %d\n",i); - free_ue_dlsch(UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&0x1][0][i]); + free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 8fe055a309..f3abbb7e3d 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -709,20 +709,20 @@ int main(int argc, char **argv) // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms); - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch[subframe&1][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); if (!eNB->dlsch[0][i]) { printf("Can't get eNB dlsch structures\n"); exit(-1); } - if (!UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][i]) { + if (!UE->dlsch[subframe&1][0][i]) { printf("Can't get ue dlsch structures\n"); exit(-1); } eNB->dlsch[0][i]->rnti = 14; - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][i]->rnti = 14; + UE->dlsch[subframe&1][0][i]->rnti = 14; } @@ -763,7 +763,7 @@ int main(int argc, char **argv) init_ul_hopping(&eNB->frame_parms); - UE->dlsch[subframe_DL(&UE->frame_parms,subframe)&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; + UE->dlsch[subframe&1][0][0]->harq_ack[ul_subframe2pdcch_alloc_subframe(&eNB->frame_parms,subframe)].send_harq_status = 1; UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; From 5904734d99d54ee0573a42b7fbf0fcd510be22de Mon Sep 17 00:00:00 2001 From: hbilel Date: Wed, 3 May 2017 16:59:27 +0200 Subject: [PATCH 534/571] [OAI_UE] Compute O_ACK with ack status only for FDD --- openair1/SCHED/phy_procedures_lte_ue.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 05a22c5241..1903745594 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -1377,7 +1377,11 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB // check if we received a PDSCH at subframe_tx - 4 // ==> send ACK/NACK on PUSCH - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; + if (ue->frame_parms.frame_type == FDD) + { + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; + } + #if T_TRACER if(ue->ulsch[eNB_id]->o_ACK[0]) @@ -1405,7 +1409,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB #ifdef DEBUG_PHY_PROC LOG_D(PHY, "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " - "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d, Nbundled %d, CQI %d, RI %d\n", + "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx, first_rb,nb_rb, ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, @@ -1419,6 +1423,8 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1], ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, + ack_status_cw0, + ack_status_cw1, ue->ulsch[eNB_id]->bundling, Nbundled, cqi_status, ri_status); From 261353680c4f15c95e0afb09988b4ea5392e6b6b Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Fri, 12 May 2017 09:44:43 +0200 Subject: [PATCH 535/571] Fix shared lib build problem, where shared lib sources were also included in main exec's Discovered and fix problems in shared lib build for usrp,bladerf and lime --- cmake_targets/CMakeLists.txt | 93 +++----------------------------- cmake_targets/tools/build_helper | 17 +++++- 2 files changed, 24 insertions(+), 86 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 94a88c095b..8ce3c0ab2f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -499,18 +499,18 @@ set(HWLIB_EXMIMO_SOURCE add_library(oai_exmimodevif MODULE ${HWLIB_EXMIMO_SOURCE} ) include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/") -set (option_HWUSRPLIB_lib "-l uhd") set(HWLIB_USRP_SOURCE ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp ) add_library(oai_usrpdevif MODULE ${HWLIB_USRP_SOURCE} ) +target_link_libraries(oai_usrpdevif uhd) include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/") -set (option_HWBLADERFLIB_lib "-l bladerf") set(HWLIB_BLADERF_SOURCE ${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c ) add_library(oai_bladerfdevif MODULE ${HWLIB_BLADERF_SOURCE} ) +target_link_libraries(oai_bladerfdevif bladeRF) include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/") @@ -518,6 +518,8 @@ set(HWLIB_LMSSDR_SOURCE ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp ) add_library(oai_lmssdrdevif MODULE ${HWLIB_LMSSDR_SOURCE} ) +target_include_directories(oai_lmssdrdevif PRIVATE /usr/local/include/lime) +target_link_libraries(oai_lmssdrdevif LimeSuite ) include_directories("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/") set(TPLIB_ETHERNET_SOURCE @@ -528,70 +530,6 @@ set(TPLIB_ETHERNET_SOURCE add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} ) -# RF devices / transport protocols settings -###################################################################### -if (${RF_BOARD} STREQUAL "EXMIMO") - set(DRIVER2013) - include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/") - include_directories ("${OPENAIR_TARGETS}/ARCH/EXMIMO/DEFS/") - set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c) -# ${OPENAIR_TARGETS}/ARCH/EXMIMO/USERSPACE/LIB/gain_control.c) - set(option_HW_lib "-rdynamic -ldl") - -elseif (${RF_BOARD} STREQUAL "OAI_USRP") - include_directories("${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/") - include_directories("/opt/include/uhd") - set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp) - LINK_DIRECTORIES("/opt/lib") - set(option_HW_lib "-luhd -rdynamic -ldl -lboost_system") - -elseif (${RF_BOARD} STREQUAL "OAI_BLADERF") - include_directories("${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/") - include_directories("${OPENAIR2_DIR}/UTIL/LOG") - include_directories("/usr/include") - set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c - ) - LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") - - set(option_HW_lib "bladeRF -rdynamic -ldl") - -elseif (${RF_BOARD} STREQUAL "OAI_LMSSDR") - include_directories("${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB") - include_directories("/usr/local/include/lime") - include_directories("/usr/include/lime") - LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") - LINK_DIRECTORIES("/usr/local/lib") - LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/lmsSDR") - LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/lms7002m") - LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/Si5351C") - set(HW_SOURCE ${HW_SOURCE} ${OPENAIR_TARGETS}/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp) - set(option_HW_lib "-lLimeSuite -rdynamic -ldl") - -elseif (${RF_BOARD} STREQUAL "CPRIGW") - set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/cprigw_lib.c - ) - include_directories("${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/") - set(option_HW_lib "-rdynamic dl") - -endif (${RF_BOARD} STREQUAL "EXMIMO") - - -if (${TRANSP_PRO} STREQUAL "ETHERNET") - - include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB") - set(TRANSPORT_SOURCE ${TRANSPORT_SOURCE} - ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c - ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c - ) - set(option_TP_lib "-rdynamic -ldl") - - -endif (${TRANSP_PRO} STREQUAL "ETHERNET") ########################################################## include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") @@ -1773,8 +1711,6 @@ add_executable(lte-softmodem ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${GTPU_need_ITTI} - ${HW_SOURCE} - ${TRANSPORT_SOURCE} ${RTAI_SOURCE} ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} @@ -1787,7 +1723,7 @@ target_link_libraries (lte-softmodem -ldl -Wl,--end-group ) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${option_TP_lib} ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem ${T_LIB}) @@ -1809,8 +1745,6 @@ add_executable(lte-softmodem-nos1 ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR_DIR}/common/utils/system.c - ${HW_SOURCE} - ${TRANSPORT_SOURCE} ${RTAI_SOURCE} ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} @@ -1822,7 +1756,7 @@ target_link_libraries (lte-softmodem-nos1 -Wl,--end-group ) target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${option_HW_lib} ${option_TP_lib} ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${T_LIB}) @@ -1835,8 +1769,6 @@ add_executable(rrh_gw ${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${HW_SOURCE} - ${TRANSPORT_SOURCE} ${T_SOURCE} ) target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti) @@ -1845,14 +1777,9 @@ target_link_libraries(rrh_gw UTIL LFDS -Wl,--end-group ) target_link_libraries (rrh_gw rt pthread m ) -target_link_libraries (rrh_gw ${option_HW_lib} ${option_TP_lib}) target_link_libraries (rrh_gw ${LIB_LMS_LIBRARIES}) target_link_libraries (rrh_gw ${T_LIB}) -Message("-- option_HW_lib=${option_HW_lib}") -Message("-- HW_SOURCE=${HW_SOURCE}") -Message("-- option_TP_lib=${option_TP_lib}") -Message("-- TRANSPORT_SOURCE=${TRANSPORT_SOURCE}") # USIM process ################# @@ -1907,8 +1834,6 @@ add_executable(oaisim ${OPENAIR_DIR}/common/utils/system.c ${GTPU_need_ITTI} ${OPENAIR_TARGETS}/COMMON/create_tasks.c - ${HW_SOURCE} - ${TRANSPORT_SOURCE} ${XFORMS_SOURCE} ${T_SOURCE} ) @@ -1921,7 +1846,7 @@ target_link_libraries (oaisim -Wl,--end-group ) target_link_libraries (oaisim ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) -target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${option_HW_lib} ${option_TP_lib} +target_link_libraries (oaisim pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES}) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim forms) @@ -1952,8 +1877,6 @@ add_executable(oaisim_nos1 ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_DIR}/common/utils/system.c - ${HW_SOURCE} - ${TRANSPORT_SOURCE} ${XFORMS_SOURCE} ${T_SOURCE} ) @@ -1964,7 +1887,7 @@ target_link_libraries (oaisim_nos1 -Wl,--end-group ) target_link_libraries (oaisim_nos1 ${LIBXML2_LIBRARIES} ${LAPACK_LIBRARIES}) -target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${option_HW_lib} ${option_TP_lib} +target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${OPENPGM_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) #Force link with forms, regardless XFORMS option target_link_libraries (oaisim_nos1 forms) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index ede8ef4196..a57040449c 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -243,7 +243,7 @@ check_install_bladerf_driver(){ $SUDO add-apt-repository -y ppa:bladerf/bladerf $SUDO apt-get update fi - $SUDO apt-get install -y--allow-unauthenticated bladerf libbladerf-dev + $SUDO apt-get install -y --allow-unauthenticated bladerf libbladerf-dev $SUDO apt-get install -y --allow-unauthenticated bladerf-firmware-fx3 $SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40 } @@ -252,6 +252,21 @@ flash_firmware_bladerf() { $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img } +check_install_lmssdr_driver(){ + if ( [ -d "/usr/local/include/lime" ] && + [ -f "/usr/local/include/lime/LimeSuite.h" ] ) + then + echo_success "Found lmssdr drivers and tools installed from source" + else + echo_error "lmssdr support implies installing lmssdr drivers and tools" \ + " from sources. check:" + echo_info "https://open-cells.com/index.php/2017/05/10/limesdr-installation/" + echo_fatal "Cannot compile lmssdr device" + fi + + +} + check_install_additional_tools (){ $SUDO apt-get update $SUDO apt-get install -y \ From bdaef7956d5b7f0b97dda2605c69438e73736680 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 11 May 2017 11:48:30 +0200 Subject: [PATCH 536/571] bug fixes from Fujitsu (bugs 18, 19, 20) ---------------------------------------------------------- bug 18 Ttile: Probably he/she wants to copy the contents of arrays, but this coding doesn't copy anything, moreover index overflow occurs. Bug Location: u2e_t[UE_id][eNB_id]->tx_data[3]=tx[eNB_id][3]; u2e_t[UE_id][eNB_id]->rx_data[3]=rx[NB_eNB_INST+UE_id][3]; Note: Detected by CppCheck ---------------------------------------------------------- bug 19 Title: Probably he/she wants to copy the contents of arrays, but this coding doesn't copy anything, moreover index overflow occurs. Bug Location: e2u_t[eNB_id][UE_id]->tx_data[3]=tx[NB_eNB_INST+UE_id][3]; e2u_t[eNB_id][UE_id]->rx_data[3]=rx[eNB_id][3]; Note: Detected by CppCheck ---------------------------------------------------------- bug 20 Title: Probably he/she wants to copy the contents of arrays, but this coding doesn't copy anything, moreover index overflow occurs. Bug Location: tx_data[3]=cthread->tx_data[3]; rx_data[3]=cthread->rx_data[3]; Note: Detected by CppCheck ---------------------------------------------------------- --- targets/SIMU/PROC/Process.c | 15 +++++++++++---- targets/SIMU/PROC/channel_sim_proc.c | 9 +++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/targets/SIMU/PROC/Process.c b/targets/SIMU/PROC/Process.c index ee3d6d5c53..9d80c74d99 100644 --- a/targets/SIMU/PROC/Process.c +++ b/targets/SIMU/PROC/Process.c @@ -284,8 +284,12 @@ void Channel_Inst(int node_id,int port,double **s_re[MAX_eNB+MAX_UE],double **s_ u2e_t[UE_id][eNB_id]->next_slot=&next_slot; u2e_t[UE_id][eNB_id]->abstraction_flag=&abstraction_flag; u2e_t[UE_id][eNB_id]->frame_parms=frame_parms; - u2e_t[UE_id][eNB_id]->tx_data[3]=tx[eNB_id][3]; - u2e_t[UE_id][eNB_id]->rx_data[3]=rx[NB_eNB_INST+UE_id][3]; + + for (int i=0;i<3;i++) + { + u2e_t[UE_id][eNB_id]->tx_data[i]=tx[eNB_id][i]; + u2e_t[UE_id][eNB_id]->rx_data[i]=rx[NB_eNB_INST+UE_id][i]; + } if(pthread_cond_init (&downlink_cond[eNB_id][UE_id], NULL)) exit(1); @@ -316,8 +320,11 @@ void Channel_Inst(int node_id,int port,double **s_re[MAX_eNB+MAX_UE],double **s_ e2u_t[eNB_id][UE_id]->next_slot=&next_slot; e2u_t[eNB_id][UE_id]->abstraction_flag=&abstraction_flag; e2u_t[eNB_id][UE_id]->frame_parms=frame_parms; - e2u_t[eNB_id][UE_id]->tx_data[3]=tx[NB_eNB_INST+UE_id][3]; - e2u_t[eNB_id][UE_id]->rx_data[3]=rx[eNB_id][3]; + for (int i=0;i<3;i++) + { + e2u_t[eNB_id][UE_id]->tx_data[i]=tx[NB_eNB_INST+UE_id][i]; + e2u_t[eNB_id][UE_id]->rx_data[i]=rx[eNB_id][i]; + } if(pthread_cond_init (&uplink_cond[UE_id][eNB_id], NULL)) exit(1); diff --git a/targets/SIMU/PROC/channel_sim_proc.c b/targets/SIMU/PROC/channel_sim_proc.c index 0ffdd97ce0..b54fe36460 100644 --- a/targets/SIMU/PROC/channel_sim_proc.c +++ b/targets/SIMU/PROC/channel_sim_proc.c @@ -183,8 +183,13 @@ void do_DL_sig_channel_T(void *param) next_slot=(cthread->next_slot); abstraction_flag=*(cthread->abstraction_flag); thread_id=(cthread->thread_id); - tx_data[3]=cthread->tx_data[3]; - rx_data[3]=cthread->rx_data[3]; + + for (int i=0;i<3;i++) + { + tx_data[i]=cthread->tx_data[i]; + rx_data[i]=cthread->rx_data[i]; + } + s32 att_eNB_id=-1; s32 **txdata,**rxdata; From 98a7a16eadd7c062881c5629dc20b7483c576d51 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 11 May 2017 11:51:09 +0200 Subject: [PATCH 537/571] bug fixes from Fujitsu (bug 21) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: this fix does not solve the issue with how this buffer is used in this function, but I'm not sure this code is used at all (Cédric Roux). ---------------------------------------------------------- bug 21 Ttile: PAYLOAD_MAX=1500, so this coding results in index overflow. Additionally, operator "!=" just compairs something, this coding is meaningless. Bug Location: buffer[PAYLOAD_MAX] != '\0'; Note: Detected by CppCheck ---------------------------------------------------------- --- openair2/UTIL/OTG/otg_rx_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/UTIL/OTG/otg_rx_socket.c b/openair2/UTIL/OTG/otg_rx_socket.c index 2caeee4f52..98e03532a1 100644 --- a/openair2/UTIL/OTG/otg_rx_socket.c +++ b/openair2/UTIL/OTG/otg_rx_socket.c @@ -98,7 +98,7 @@ void *recv_ip4_tcp(void* csock) LOG_I(OTG,"SOCKET:: TCP-IP4 :: size=%d received=%d, Received buffer: %s \n\n\n", strlen(buffer), sock_rcv, buffer); - buffer[PAYLOAD_MAX] != '\0'; + //buffer[PAYLOAD_MAX] != '\0'; } From 34c6805f7a211894d17146998cbf18259dd99906 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 11 May 2017 11:54:15 +0200 Subject: [PATCH 538/571] bug fixes from Fujitsu (bug 22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: not sure that the code is correct, to be checked (Cédric Roux). ---------------------------------------------------------- bug 22 Ttile: (subframe!=2)||(subframe!=7) is always TRUE. This coding is really intended? Operator || should be && instead? Bug Location: ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe!=2)||(subframe!=7)))) { Note: Detected by CppCheck ---------------------------------------------------------- --- openair1/SCHED/phy_procedures_lte_eNb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 2f2be51aaa..673583f78c 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -2272,7 +2272,7 @@ void pucch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int UE_id,int harq if ((fp->frame_type==FDD) || (bundling_flag==bundling) || - ((fp->frame_type==TDD)&&(fp->tdd_config==1)&&((subframe!=2)||(subframe!=7)))) { + ((fp->frame_type==TDD)&&(fp->tdd_config==1)&&((subframe!=2)&&(subframe!=7)))) { format = pucch_format1a; } else { format = pucch_format1b; From adb3b25c67c1c76e002dfbb9d07dac7230c8581d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 12 May 2017 11:52:52 +0200 Subject: [PATCH 539/571] bug fixes from Fujitsu (bug 24) ---------------------------------------------------------- bug 24 Ttile: The last line "multicast_group = multicast_group" is hard to understand. The local variable should be different name than the global variable. Bug Location: const char *multicast_group_list[MULTICAST_LINK_NUM_GROUPS] = { "239.0.0.161", "239.0.0.162", "239.0.0.163", "239.0.0.164" }; : : void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), unsigned char multicast_group, char *multicast_ifname) { rx_handler = rx_handlerP; multicast_group = multicast_group; Note: Detected by CppCheck ---------------------------------------------------------- --- openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c index 306ec12ad2..d161da6a74 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/multicast_link.c @@ -308,10 +308,10 @@ void* multicast_link_main_loop (void *param) } void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), - unsigned char multicast_group, char *multicast_ifname) + unsigned char _multicast_group, char *multicast_ifname) { rx_handler = rx_handlerP; - multicast_group = multicast_group; + multicast_group = _multicast_group; multicast_if = multicast_ifname; LOG_I(EMU, "[MULTICAST] LINK START on interface=%s for group=%d: handler=%p\n", (multicast_if == NULL) ? "not specified" : multicast_if, multicast_group, From 899d150621e08575f0e5324d5ba5d394f00bc91e Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 11 May 2017 11:57:51 +0200 Subject: [PATCH 540/571] bug fixes from Fujitsu (bug 26) ---------------------------------------------------------- bug 26 Ttile: g_buffer has only 32 index, but he/she tries to zero clear 1024 index. Bug Location: static uint8_t g_buffer[32]; : memset (g_buffer, 0, 1024); Note: Detected by CppCheck ---------------------------------------------------------- --- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c index 8e201a949b..86cafb89ce 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c @@ -228,7 +228,7 @@ void rlc_am_v9_3_0_test_read_write_bit_field() uint8_t* byte_pos_read = g_buffer; uint16_t read_value; - memset (g_buffer, 0, 1024); + memset (g_buffer, 0, sizeof(g_buffer)); // byte 0 rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 1); rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 0); From 893f36e81e1917b20f39b2cafeaf766c89037d82 Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 11 May 2017 11:58:49 +0200 Subject: [PATCH 541/571] bug fixes from Fujitsu (bug 29) ---------------------------------------------------------- bug 29 Ttile: FDD should be TDD. Bug Location: switch (oai_emulation.info.frame_type[0]) { case FDD: frame_type = "FDD"; break; case TDD: frame_type = "FDD"; break; } ---------------------------------------------------------- --- targets/SIMU/USER/oaisim_functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index 8f357458ec..f6fc55852a 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1486,7 +1486,7 @@ void init_ocm(void) break; case TDD: - frame_type = "FDD"; + frame_type = "TDD"; break; } From ad6d0ac59e28da0c44168ae17d0f771f1eb200fa Mon Sep 17 00:00:00 2001 From: gabrielC Date: Thu, 11 May 2017 13:55:20 +0200 Subject: [PATCH 542/571] bug fixes from Fujitsu (bug 37) ---------------------------------------------------------- bug 37 Ttile: Sending side is as follows. rar[3] = (((mcs&0x7)<<5)) | ((TPC&7)<<2) | ((ULdelay&1)<<1) | (cqireq&1); So, 2 bit shift looks correct. Bug Location: ulsch->harq_processes[harq_pid]->TPC = (rar[3]>>3)&7;//rar->TPC; ---------------------------------------------------------- --- openair1/PHY/LTE_TRANSPORT/rar_tools.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c index b7550d5573..2d29d8c13f 100644 --- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c @@ -238,7 +238,7 @@ int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue, - ulsch->harq_processes[harq_pid]->TPC = (rar[3]>>3)&7;//rar->TPC; + ulsch->harq_processes[harq_pid]->TPC = (rar[3]>>2)&7;//rar->TPC; rballoc = (((uint16_t)(rar[1]&7))<<7)|(rar[2]>>1); cqireq=rar[3]&1; From 3d4ba1a3b0263040521edba74ba5248324f1465a Mon Sep 17 00:00:00 2001 From: Tien-Thinh Nguyen Date: Fri, 12 May 2017 15:23:07 +0200 Subject: [PATCH 543/571] fix the errors related to multiple carriers (for a given UE considering only the CCs which this UE belongs to) --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 32 ++++++++++++----------- openair2/LAYER2/MAC/pre_processor.c | 11 +++++--- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 188eab9c95..595d16587c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -520,25 +520,27 @@ schedule_ue_spec( // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n"); continue_flag=1; } - - switch(mac_xface->get_transmission_mode(module_idP,CC_id,rnti)){ - case 1: - case 2: - case 7: - aggregation = get_aggregation(get_bw_index(module_idP,CC_id), + + if (continue_flag != 1){ + switch(mac_xface->get_transmission_mode(module_idP,CC_id,rnti)){ + case 1: + case 2: + case 7: + aggregation = get_aggregation(get_bw_index(module_idP,CC_id), eNB_UE_stats->DL_cqi[0], format1); - break; - case 3: - aggregation = get_aggregation(get_bw_index(module_idP,CC_id), + break; + case 3: + aggregation = get_aggregation(get_bw_index(module_idP,CC_id), eNB_UE_stats->DL_cqi[0], format2A); - break; - default: - LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(module_idP,CC_id,rnti)); - aggregation = 2; - } - + break; + default: + LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(module_idP,CC_id,rnti)); + aggregation = 2; + } + } /* if (continue_flag != 1 */ + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti) ) { diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 74e0a43d7d..29972d6a1a 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -71,9 +71,14 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) { int CC_id; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) - if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL) - return 0; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++){ + int UE_id = find_UE_id(Mod_id,rnti); + if (UE_id == -1) + continue; //skip if UE is not valid + if (CC_id == UE_PCCID(Mod_id,UE_id)) //get stats for only the CCs which the UE belongs to + if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL) + return 0; + } return 1; } From 9eaee53bb647d2f971d0b81e27a5920581d61fd2 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sat, 13 May 2017 12:45:17 +0200 Subject: [PATCH 544/571] rewrite phy_stats_exist We have to test that all active CCs of a given UE exist in the PHY layer. Maybe not the end of the story... --- openair2/LAYER2/MAC/pre_processor.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 29972d6a1a..1be9a2ba3a 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -66,18 +66,28 @@ */ /* this function checks that get_eNB_UE_stats returns - * a non-NULL pointer for all CCs for a given UE + * a non-NULL pointer for all the active CCs of an UE */ int phy_stats_exist(module_id_t Mod_id, int rnti) { int CC_id; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++){ - int UE_id = find_UE_id(Mod_id,rnti); - if (UE_id == -1) - continue; //skip if UE is not valid - if (CC_id == UE_PCCID(Mod_id,UE_id)) //get stats for only the CCs which the UE belongs to - if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL) - return 0; + int i; + int UE_id = find_UE_id(Mod_id, rnti); + UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list; + if (UE_id == -1) { + LOG_W(MAC, "[eNB %d] UE %x not found, should be there (in phy_stats_exist)\n", + Mod_id, rnti); + return 0; + } + if (UE_list->numactiveCCs[UE_id] == 0) { + LOG_W(MAC, "[eNB %d] UE %x has no active CC (in phy_stats_exist)\n", + Mod_id, rnti); + return 0; + } + for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + if (mac_xface->get_eNB_UE_stats(Mod_id, CC_id, rnti) == NULL) + return 0; } return 1; } From 11006597c98994fdd78bee243e29f016fe6989ec Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 15 May 2017 10:52:55 +0200 Subject: [PATCH 545/571] integration fix: let dlsim and ulsim work again There is now the function copy_harq_proc_struct and some procedures for the UE have changed, which makes necessary to have UE->dlsch valid for both subframes (odd and even). We increase memory usage, maybe it's not the correct solution. To be kept in mind if something goes wrong at some point. --- openair1/SIMULATION/LTE_PHY/dlsim.c | 22 +++++++++++++++------- openair1/SIMULATION/LTE_PHY/ulsim.c | 28 +++++++++++++++++----------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index b8e23f2d98..379f28c190 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1379,6 +1379,7 @@ int main(int argc, char **argv) uint8_t Kmimo; uint8_t ue_category=4; uint32_t Nsoft; + int sf; @@ -2104,15 +2105,22 @@ int main(int argc, char **argv) } } - for (i=0; i<2; i++) { - UE->dlsch[subframe&0x1][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + /* allocate memory for both subframes (only one is really used + * but there is now "copy_harq_proc_struct" which needs both + * to be valid) + * TODO: refine this somehow (necessary?) + */ + for (sf = 0; sf < 2; sf++) { + for (i=0; i<2; i++) { + UE->dlsch[sf][0][i] = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!UE->dlsch[subframe&0x1][0][i]) { - printf("Can't get ue dlsch structures\n"); - exit(-1); + if (!UE->dlsch[sf][0][i]) { + printf("Can't get ue dlsch structures\n"); + exit(-1); + } + + UE->dlsch[sf][0][i]->rnti = n_rnti; } - - UE->dlsch[subframe&0x1][0][i]->rnti = n_rnti; } UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index f3abbb7e3d..60e7a74ed6 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -275,6 +275,7 @@ int main(int argc, char **argv) uint8_t max_turbo_iterations=4; uint8_t parallel_flag=0; int nb_rb_set = 0; + int sf; int threequarter_fs=0; int ndi; @@ -709,22 +710,27 @@ int main(int argc, char **argv) // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[0][i] = new_eNB_dlsch(1,8,1827072,N_RB_DL,0,&eNB->frame_parms); - UE->dlsch[subframe&1][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); - if (!eNB->dlsch[0][i]) { printf("Can't get eNB dlsch structures\n"); exit(-1); } - - if (!UE->dlsch[subframe&1][0][i]) { - printf("Can't get ue dlsch structures\n"); - exit(-1); - } - eNB->dlsch[0][i]->rnti = 14; - UE->dlsch[subframe&1][0][i]->rnti = 14; - - } + } + /* allocate memory for both subframes (only one is really used + * but there is now "copy_harq_proc_struct" which needs both + * to be valid) + * TODO: refine this somehow (necessary?) + */ + for (sf = 0; sf < 2; sf++) { + for (i=0; i<2; i++) { + UE->dlsch[sf][0][i] = new_ue_dlsch(1,8,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); + if (!UE->dlsch[sf][0][i]) { + printf("Can't get ue dlsch structures\n"); + exit(-1); + } + UE->dlsch[sf][0][i]->rnti = 14; + } + } UE->dlsch_SI[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->dlsch_ra[0] = new_ue_dlsch(1,1,1827072,MAX_TURBO_ITERATIONS,N_RB_DL,0); From 9cd3e2e887fd69137816db5d08eac069e14b43af Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 15 May 2017 15:42:01 +0200 Subject: [PATCH 546/571] integration fix: remove warnings in ulsim --- openair1/SIMULATION/LTE_PHY/ulsim.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 60e7a74ed6..dbce858516 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -253,7 +253,7 @@ int main(int argc, char **argv) uint8_t N_RB_DL=25,osf=1; - uint8_t cyclic_shift = 0; + //uint8_t cyclic_shift = 0; uint8_t cooperation_flag = 0; //0 no cooperation, 1 delay diversity, 2 Alamouti uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; uint8_t tdd_config=3,frame_type=FDD; @@ -463,9 +463,9 @@ int main(int argc, char **argv) first_rb = atoi(optarg); break; - case 'c': - cyclic_shift = atoi(optarg); - break; + //case 'c': + // cyclic_shift = atoi(optarg); + // break; case 'E': threequarter_fs=1; @@ -557,7 +557,9 @@ int main(int argc, char **argv) case 'h': default: - printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -c cyclic_shift -o (srs on) -g channel_model [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M'), -d Channel delay, -D maximum Doppler shift \n", + /* option "-c cyclic_shift" is not used, let's remove from documentation */ + //printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -c cyclic_shift -o (srs on) -g channel_model [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M'), -d Channel delay, -D maximum Doppler shift \n", + printf("%s -h(elp) -a(wgn on) -m mcs -n n_frames -s snr0 -t delay_spread -p (extended prefix on) -r nb_rb -f first_rb -o (srs on) -g channel_model [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M'), -d Channel delay, -D maximum Doppler shift \n", argv[0]); exit(1); break; From f12350ce622a97fbfcc2d2c2e9dcc39fec36f62a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 15 May 2017 15:42:27 +0200 Subject: [PATCH 547/571] integration fix: remove warnings in dlsim --- openair1/SIMULATION/LTE_PHY/dlsim.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 379f28c190..951b5f75f6 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1341,7 +1341,7 @@ int main(int argc, char **argv) //int iii; int ch_realization; - int pmi_feedback=0; + //int pmi_feedback=0; int hold_channel=0; // void *data; @@ -1391,7 +1391,7 @@ int main(int argc, char **argv) FILE *csv_fd=NULL; char csv_fname[32]; - int dci_flag=1; + //int dci_flag=1; int two_thread_flag=0; int DLSCH_RB_ALLOC = 0; @@ -1453,9 +1453,9 @@ int main(int argc, char **argv) Nid_cell = atoi(optarg); break; - case 'd': - dci_flag = 1; - break; + //case 'd': + // dci_flag = 1; + // break; case 'D': frame_type=TDD; @@ -1482,7 +1482,7 @@ int main(int argc, char **argv) case 'i': input_fd = fopen(optarg,"r"); input_file=1; - dci_flag = 1; + //dci_flag = 1; break; case 'I': @@ -2325,10 +2325,10 @@ int main(int argc, char **argv) // printf("Trial %d, round %d\n",trials,round); round_trials[round]++; - if(transmission_mode>=5) - pmi_feedback=1; - else - pmi_feedback=0; + //if(transmission_mode>=5) + // pmi_feedback=1; + //else + // pmi_feedback=0; if (abstx) { if (trials==0 && round==0 && SNR==snr0) //generate a new channel From 15bb39704ad8bd80a71f6446923527fa5d649cd5 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 15 May 2017 15:56:49 +0200 Subject: [PATCH 548/571] integration fix: remove warnings introduced by PUCCH format 3 handling --- openair1/PHY/LTE_TRANSPORT/pucch.c | 48 +++++++++++++++----------- openair1/SCHED/phy_procedures_lte_ue.c | 4 +++ openair1/SCHED/pucch_pc.c | 4 +++ 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 9a03c52c90..8adc693b31 100755 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -512,6 +512,10 @@ void generate_pucch1x(int32_t **txdataF, case pucch_format2b: AssertFatal(1==0,"should not go here\n"); break; + + case pucch_format3: + fprintf(stderr, "PUCCH format 3 not handled\n"); + abort(); } // switch fmt } else { // These are PUCCH reference symbols @@ -870,7 +874,7 @@ void generate_pucch3x(int32_t **txdataF, uint16_t rnti) { - uint32_t u, v, n; + uint32_t u, v; uint16_t i, j, re_offset; uint32_t z[12*14], *zptr; uint32_t y_tilda[12*14]={}, *y_tilda_ptr; @@ -889,7 +893,7 @@ void generate_pucch3x(int32_t **txdataF, // variables for channel coding uint8_t chcod_tbl_idx = 0; - uint8_t chcod_dt[48] = {}; + //uint8_t chcod_dt[48] = {}; // variables for Scrambling uint32_t cinit = 0; @@ -911,8 +915,8 @@ void generate_pucch3x(int32_t **txdataF, uint8_t dt_offset; uint8_t sym_offset; - int16_t y_re[14][12]={0}; - int16_t y_im[14][12]={0}; + int16_t y_re[14][12]; //={0}; + int16_t y_im[14][12]; //={0}; // DMRS uint8_t alpha_idx=0; @@ -1184,17 +1188,17 @@ uint16_t pucchfmt3_Baseseq_csh_remove( int16_t SubCarrierDeMapData[NB_ANTENNAS_R uint8_t subframe, uint8_t ncs_cell[20][7] ) { - int16_t calctmp_baSeq[2]; + //int16_t calctmp_baSeq[2]; int16_t calctmp_beta[2]; int16_t calctmp_alphak[2]; int16_t calctmp_SCDeMapData_alphak[2]; int32_t n_cell_cs_div64; int32_t n_cell_cs_modNSC_RB; - int32_t NSlot1subframe = D_NSLT1SF; + //int32_t NSlot1subframe = D_NSLT1SF; int32_t NSym1slot = D_NSYM1SLT; // Symbol per 1slot int32_t NSym1subframe = D_NSYM1SF; // Symbol per 1subframe - int32_t aa, symNo, slotNo, sym, k, i; + int32_t aa, symNo, slotNo, sym, k; for (aa=0; aanb_antennas_rx; aa++) { // Antenna @@ -1247,16 +1251,18 @@ uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX uint16_t n3_pucch_array[NUMBER_OF_UE_MAX], uint8_t ncs_cell[20][7] ) { - uint32_t aa, symNo, k, rb, sltNo, ueNo, slotNo, sym, i, j; - int16_t np, np_n, ip_np, npucch_sf, ip_ind; - int16_t calctmp[2], calctmp_cs[2]; + uint32_t aa, symNo, k, slotNo, sym, i, j; + int16_t np, np_n, ip_ind; + //int16_t npucch_sf; + int16_t calctmp[2]; int16_t BsCshData[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2]; - int16_t delta_theta_calctmp[NB_ANTENNAS_RX][4][D_NSC1RB][2], delta_theta_comp[NB_ANTENNAS_RX][D_NSC1RB][2]; + //int16_t delta_theta_calctmp[NB_ANTENNAS_RX][4][D_NSC1RB][2], delta_theta_comp[NB_ANTENNAS_RX][D_NSC1RB][2]; + int16_t delta_theta_comp[NB_ANTENNAS_RX][D_NSC1RB][2]; int16_t CsData_allavg[NB_ANTENNAS_RX][14][2]; int16_t CsData_temp[NB_ANTENNAS_RX][D_NSYM1SF][D_NSC1RB][2]; int32_t IP_CsData_allsfavg[NB_ANTENNAS_RX][14][4][2]; int32_t IP_allavg[D_NPUCCH_SF5]; - int16_t temp_ch[2]; + //int16_t temp_ch[2]; int16_t m[NUMBER_OF_UE_MAX], m_self, same_m_number; uint16_t n3_pucch_sameRB[NUMBER_OF_UE_MAX]; int16_t n_oc0[NUMBER_OF_UE_MAX]; @@ -1273,8 +1279,8 @@ uint16_t pucchfmt3_ChannelEstimation( int16_t SubCarrierDeMapData[NB_ANTENNAS_RX uint32_t u=u0; uint32_t v=v0; - double d_theta[32]={0.0}; - int32_t temp_theta[32][2]={0}; + //double d_theta[32]={0.0}; + //int32_t temp_theta[32][2]={0}; for (aa=0; aanb_antennas_rx; aa++) { for (symNo=0; symNonb_antennas_rx; aa++) { sltNo = 0; @@ -1513,7 +1519,7 @@ uint16_t pucchfmt3_FrqDevRemove( int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14 int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2], LTE_DL_FRAME_PARMS *frame_parms ) { - int16_t ueNo, aa, sltNo, symNo1slt, k, n; + int16_t aa, sltNo, symNo1slt, k, n; double calctmp[2]; for (aa=0; aanb_antennas_rx; aa++) { @@ -1564,7 +1570,7 @@ uint16_t pucchfmt3_OrthSeqRemove( int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5 uint16_t n3_pucch, LTE_DL_FRAME_PARMS *frame_parms ) { - int16_t aa, sltNo, symNo, n, k; + int16_t aa, sltNo, n, k; int16_t Npucch_sf; int16_t noc; @@ -1609,7 +1615,7 @@ uint16_t pucchfmt3_AvgAnt( int16_t Fmt3xDataRmvOrth[NB_ANTENNAS_RX][2][5][12][2] uint8_t shortened_format, LTE_DL_FRAME_PARMS *frame_parms ) { - int16_t aa, sltNo, symNo, n, k; + int16_t aa, sltNo, n, k; int16_t Npucch_sf; for (sltNo=0; sltNo Date: Mon, 15 May 2017 15:57:26 +0200 Subject: [PATCH 549/571] integration fix: remove various warnings --- common/utils/itti/memory_pools.c | 2 +- openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c | 2 +- openair2/RRC/LITE/rrc_UE.c | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/common/utils/itti/memory_pools.c b/common/utils/itti/memory_pools.c index b317cfd2fa..955e29440a 100644 --- a/common/utils/itti/memory_pools.c +++ b/common/utils/itti/memory_pools.c @@ -77,7 +77,7 @@ typedef struct items_group_s { } items_group_t; /*------------------------------------------------------------------------------*/ -static const items_group_position_t ITEMS_GROUP_POSITION_INVALID = -1; +//static const items_group_position_t ITEMS_GROUP_POSITION_INVALID = -1; static const items_group_index_t ITEMS_GROUP_INDEX_INVALID = -1; /*------------------------------------------------------------------------------*/ diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index a344d2b208..051a3d5d83 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -583,7 +583,7 @@ int allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB, LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms; - int first_layer0; //= dlsch0_harq->first_layer; + int first_layer0 = -1; //= dlsch0_harq->first_layer; int Nlayers0 = -1; // = dlsch0_harq->Nlayers; uint8_t mod_order0=0; // = get_Qm(dlsch0_harq->mcs); uint8_t mod_order1=0; //=2; diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 84d9e802dd..2cf87c3e45 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -404,6 +404,7 @@ void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t* const ctxt_pP, mui_t rrc_mui=0; +#if !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) /* NAS Attach request with IMSI */ static const char const nas_attach_req_imsi[] = { 0x07, 0x41, @@ -417,7 +418,9 @@ static const char const nas_attach_req_imsi[] = { 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2, 0x01, 0x27, 0x11, }; +#endif /* !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) */ +#if 0 /* NAS Attach request with GUTI */ static const char const nas_attach_req_guti[] = { 0x07, 0x41, @@ -431,6 +434,7 @@ static const char const nas_attach_req_guti[] = { 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2, 0x01, 0x27, 0x11, }; +#endif //----------------------------------------------------------------------------- static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) From 0023d448f7250bc728f02301c4db5a36f04116ea Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 15 May 2017 16:12:33 +0200 Subject: [PATCH 550/571] integration fix: expressMIMO should be aligned with the rest now No need for this special case. Plus, it fails with the work from Nokia on compilation cleanup. --- targets/ARCH/COMMON/common_lib.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 7433b5d618..19036de204 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -139,11 +139,6 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) { int rc=0; - //ToDo: EXMIMO harmonization is not complete. That is the reason for this ifdef - #ifdef EXMIMO - int device_init(openair0_device *device, openair0_config_t *openair0_cfg); - rc = device_init(device, openair0_cfg); - #else rc=load_lib(device, openair0_cfg, NULL,BBU_LOCAL_RADIO_HEAD ); if ( rc >= 0) { if ( set_device(device) < 0) { @@ -151,7 +146,6 @@ int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cf return -1; } } - #endif return rc; } From 099b7f2ac6b5c1fa12718ae1be384187a20d56b7 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 15 May 2017 16:13:32 +0200 Subject: [PATCH 551/571] integration fix: fix rrh_gw compilation --- cmake_targets/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 8ce3c0ab2f..e20718ac36 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1774,7 +1774,7 @@ add_executable(rrh_gw target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti) target_link_libraries(rrh_gw -Wl,--start-group - UTIL LFDS + UTIL LFDS -ldl -Wl,--end-group ) target_link_libraries (rrh_gw rt pthread m ) target_link_libraries (rrh_gw ${LIB_LMS_LIBRARIES}) From dd07d878a39aa3f6a613a1e80a834f9e630c506d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 17 May 2017 12:58:21 +0200 Subject: [PATCH 552/571] bugfix: fix compilation for express MIMO target --- cmake_targets/build_oai | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 07278d82b1..93a7ac073e 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -785,20 +785,19 @@ function main() { build_dir=$rrh_build_dir fi - # build RF device libraries (currently EXMIMO is not complied with the rest of HW targets) + # build RF device libraries if [ "$HW" != "None" ] ; then rm -f liboai_device.so rm -f $dbin/liboai_device.so - # link liboai_device.so with the selected RF device library if [ "$HW" == "EXMIMO" ] ; then - - #add exmimo compilation - #TODO EXMIMO library support compilations \ $build_dir oai_exmimodevif \ liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL + + ln -sf liboai_exmimodevif.so liboai_device.so + ln -sf $dbin/liboai_exmimodevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to EXMIMO device library" elif [ "$HW" == "OAI_USRP" ] ; then if [ -d "/usr/include/uhd" ] ; then From 5e323eefa2f413fec8b24055228fb1ac989de737 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 May 2017 10:39:25 +0200 Subject: [PATCH 553/571] improve logging in oaisim - print current working directory - print git version (if available) - print security keys this last one is a security breach, but as of today it's not a problem --- openair3/NAS/TOOLS/display.c | 8 ++++++ openair3/NAS/UE/EMM/emm_main.c | 46 ++++++++++++++++++++++++++++++++++ targets/SIMU/USER/oaisim.c | 16 ++++++++++++ 3 files changed, 70 insertions(+) diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c index 7d145d1f3b..363fae76b8 100644 --- a/openair3/NAS/TOOLS/display.c +++ b/openair3/NAS/TOOLS/display.c @@ -248,6 +248,14 @@ void display_usim_data(const char *filename) { memcpy(key, data.keys.ik, USIM_IK_SIZE); printf("\tIK\t: \"%s\"\n", key); + printf("\n\tusim_api_k:"); + for (int i = 0; i < 16; i++) + printf(" %2.2x", data.keys.usim_api_k[i]); + printf("\n\topc :"); + for (int i = 0; i < 16; i++) + printf(" %2.2x", data.keys.opc[i]); + printf("\n\n"); + printf("EPS NAS security context:\n"); printf("\tKSIasme\t: 0x%.2x\n", data.securityctx.KSIasme.value[0]); char kasme[USIM_K_ASME_SIZE + 1]; diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index c64fd6df26..8f3ed17e4c 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -203,6 +203,52 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c LOG_TRACE(INFO, "EMM-MAIN - USIM application data successfully read"); user->emm_data->usim_is_valid = TRUE; + /* print keys (for debugging) */ + { + char usim_api_k[256]; + char opc[256]; + sprintf(usim_api_k, + "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x " + "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x", + user->usim_data.keys.usim_api_k[0], + user->usim_data.keys.usim_api_k[1], + user->usim_data.keys.usim_api_k[2], + user->usim_data.keys.usim_api_k[3], + user->usim_data.keys.usim_api_k[4], + user->usim_data.keys.usim_api_k[5], + user->usim_data.keys.usim_api_k[6], + user->usim_data.keys.usim_api_k[7], + user->usim_data.keys.usim_api_k[8], + user->usim_data.keys.usim_api_k[9], + user->usim_data.keys.usim_api_k[10], + user->usim_data.keys.usim_api_k[11], + user->usim_data.keys.usim_api_k[12], + user->usim_data.keys.usim_api_k[13], + user->usim_data.keys.usim_api_k[14], + user->usim_data.keys.usim_api_k[15]); + sprintf(opc, + "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x " + "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x", + user->usim_data.keys.opc[0], + user->usim_data.keys.opc[1], + user->usim_data.keys.opc[2], + user->usim_data.keys.opc[3], + user->usim_data.keys.opc[4], + user->usim_data.keys.opc[5], + user->usim_data.keys.opc[6], + user->usim_data.keys.opc[7], + user->usim_data.keys.opc[8], + user->usim_data.keys.opc[9], + user->usim_data.keys.opc[10], + user->usim_data.keys.opc[11], + user->usim_data.keys.opc[12], + user->usim_data.keys.opc[13], + user->usim_data.keys.opc[14], + user->usim_data.keys.opc[15]); + LOG_TRACE(INFO, "EMM-MAIN - usim_api_k: %s", usim_api_k); + LOG_TRACE(INFO, "EMM-MAIN - opc: %s", opc); + } + /* Get the Home PLMN derived from the IMSI */ user->emm_data->hplmn.MCCdigit1 = user->usim_data.imsi.u.num.digit1; user->emm_data->hplmn.MCCdigit2 = user->usim_data.imsi.u.num.digit2; diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index b60e73e37c..d07cd759d1 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -1188,6 +1188,15 @@ int T_port = 2021; /* default port to listen to to wait for the tracer */ int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ #endif +static void print_current_directory(void) +{ + char dir[8192]; /* arbitrary size (should be big enough) */ + if (getcwd(dir, 8192) == NULL) + printf("ERROR getting working directory\n"); + else + printf("working directory: %s\n", dir); +} + /*------------------------------------------------------------------------------*/ int main (int argc, char **argv) @@ -1195,6 +1204,8 @@ main (int argc, char **argv) clock_t t; + print_current_directory(); + start_background_system(); #ifdef SMBV @@ -1350,6 +1361,11 @@ main (int argc, char **argv) LOG_N(EMU, ">>>>>>>>>>>>>>>>>>>>>>>>>>> OAIEMU initialization done <<<<<<<<<<<<<<<<<<<<<<<<<<\n\n"); +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#endif + LOG_I(EMU, "Version: %s\n", PACKAGE_VERSION); + #if defined(ENABLE_ITTI) // Handle signals until all tasks are terminated From 4eefaffb475c9443c8836bbbc562a041af96d02e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 May 2017 11:12:11 +0200 Subject: [PATCH 554/571] minor: change files mode (from 755 to 644) --- openair1/PHY/INIT/lte_init.c | 0 openair1/PHY/LTE_TRANSPORT/defs.h | 0 openair1/PHY/LTE_TRANSPORT/if4_tools.c | 0 openair1/PHY/LTE_TRANSPORT/proto.h | 0 openair1/PHY/LTE_TRANSPORT/pucch.c | 0 openair1/PHY/TOOLS/lte_phy_scope_tm4.c | 0 openair1/PHY/impl_defs_lte.h | 0 openair1/SIMULATION/LTE_PHY/pucchsim.c | 0 8 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 openair1/PHY/INIT/lte_init.c mode change 100755 => 100644 openair1/PHY/LTE_TRANSPORT/defs.h mode change 100755 => 100644 openair1/PHY/LTE_TRANSPORT/if4_tools.c mode change 100755 => 100644 openair1/PHY/LTE_TRANSPORT/proto.h mode change 100755 => 100644 openair1/PHY/LTE_TRANSPORT/pucch.c mode change 100755 => 100644 openair1/PHY/TOOLS/lte_phy_scope_tm4.c mode change 100755 => 100644 openair1/PHY/impl_defs_lte.h mode change 100755 => 100644 openair1/SIMULATION/LTE_PHY/pucchsim.c diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c old mode 100755 new mode 100644 diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h old mode 100755 new mode 100644 diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c old mode 100755 new mode 100644 diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h old mode 100755 new mode 100644 diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c old mode 100755 new mode 100644 diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c old mode 100755 new mode 100644 diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h old mode 100755 new mode 100644 diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c old mode 100755 new mode 100644 From f6693af628615512744eab3a964129305d74ab3e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 May 2017 11:24:40 +0200 Subject: [PATCH 555/571] add CQI to periodic logging of UE --- openair2/LAYER2/MAC/eNB_scheduler.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 6509471124..e7fbbce3c9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -140,10 +140,14 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, rnti = UE_RNTI(module_idP, i); CC_id = UE_PCCID(module_idP, i); - if ((frameP==0)&&(subframeP==0)) - LOG_I(MAC,"UE rnti %x : %s, PHR %d dB\n", rnti, - UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync", - UE_list->UE_template[CC_id][i].phr_info); + if ((frameP==0)&&(subframeP==0)) { + LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti); + int cqi = eNB_UE_stats == NULL ? -1 : eNB_UE_stats->DL_cqi[0]; + LOG_I(MAC,"UE rnti %x : %s, PHR %d dB CQI %d\n", rnti, + UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync", + UE_list->UE_template[CC_id][i].phr_info, + cqi); + } PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63; if (i==UE_list->head) From 94dd884325e4b613a08a3b572c8689cfb85bd047 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 May 2017 11:34:58 +0200 Subject: [PATCH 556/571] redo commit cb67d586a451fd77f862b1462e8b778c43169a23 Seems like this commit got lost at some point. Here was the message: ----------------------------------------------------------------------------- Author: Cedric Roux Date: Tue Jan 10 14:21:02 2017 +0100 add format indicator to get LOG_X warnings The LOG_X macros emit a lot of warnings when compiling with the T because they call the function logRecord (or logRecord_mt) which has not been "marked" as calling printf, so gcc won't emit typical printf warnings. With the T, they directly translate to sprintf, so those warnings pop up, much more verbose due to several macro expansions. Let's make them pop up all the time so it's easier to fix them. ----------------------------------------------------------------------------- --- openair2/UTIL/LOG/log.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index 3a67e85d3d..5140a08dbd 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -259,8 +259,8 @@ void log_set_instance_type (log_instance_type_t instance); # include "log_if.h" /*----------------------------------------------------------------------------*/ int logInit (void); -void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...); -void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...); +void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); +void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); int set_comp_log(int component, int level, int verbosity, int interval); int set_log(int component, int level, int interval); void set_glog(int level, int verbosity); From 9d65f4dd09f1d391e4cc786289ad426c24a66cf3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 May 2017 14:15:16 +0200 Subject: [PATCH 557/571] warnings removal in LOG_X those popped up thanks to previous commit --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/phich.c | 1 + openair2/RRC/LITE/rrc_UE.c | 4 ++-- openair2/RRC/LITE/rrc_eNB_S1AP.c | 4 ++-- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 4 ++-- targets/RT/USER/lte-enb.c | 4 ++-- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 5aa676da9a..59d16c7a39 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -4888,7 +4888,7 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, if(rballoc > RIV_max) { - LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %d \n",rballoc, RIV_max); + LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); // DCI false detection return(0); } @@ -5124,7 +5124,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, if( (rballoc > RIV_max) && (rah == 1) ) { // DCI false detection - LOG_I(PHY,"bad rballoc %d RIV_max %d\n", rballoc, RIV_max); + LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); return(0); } diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index d363d4dcf6..194eea402b 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -1396,6 +1396,7 @@ void rx_phich(PHY_VARS_UE *ue, HI16, nseq_PHICH, ngroup_PHICH, + ulsch->harq_processes[harq_pid]->round, ulsch->Mlimit); //#endif diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 2cf87c3e45..dd3690e2ac 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -1042,7 +1042,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio // Update cqi_ReportConfig if(radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig != NULL) { - LOG_I(RRC,"Update cqi_ReportConfig config (size=%d,%d)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig), sizeof(CQI_ReportConfig_t)); + LOG_I(RRC,"Update cqi_ReportConfig config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig), sizeof(CQI_ReportConfig_t)); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig = CALLOC(1,sizeof(CQI_ReportConfig_t)); @@ -1052,7 +1052,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); if (radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { - LOG_I(RRC,"Update cqi_ReportPeriodic config (size=%d,%d)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic), sizeof(CQI_ReportPeriodic_t)); + LOG_I(RRC,"Update cqi_ReportPeriodic config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic), sizeof(CQI_ReportPeriodic_t)); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic == NULL) UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1,sizeof(CQI_ReportPeriodic_t)); diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c index 3642d02a1c..1ec7cc44e8 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c @@ -287,7 +287,7 @@ rrc_eNB_process_security( // translation LOG_D(RRC, - "[eNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %u NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n", + "[eNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n", ctxt_pP->module_id, ue_context_pP->ue_context.security_capabilities.encryption_algorithms, ue_context_pP->ue_context.ciphering_algorithm, @@ -308,7 +308,7 @@ rrc_eNB_process_security( changed = TRUE; } - LOG_I (RRC, "[eNB %d][UE %x] Selected security algorithms (%p): %x, %x, %s\n", + LOG_I (RRC, "[eNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti, security_capabilities_pP, diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index dc2589de44..df91796049 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -261,7 +261,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp LOG_E(PHY,"[recv] received %d samples out of %d\n",samples_received,nsamps); if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) - LOG_E(PHY,s->rx_md.to_pp_string(true).c_str()); + LOG_E(PHY, "%s\n", s->rx_md.to_pp_string(true).c_str()); s->rx_count += nsamps; s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); @@ -664,7 +664,7 @@ extern "C" { LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); if ( samples < max ) stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); - LOG_I(PHY,"rx_max_num_samps %u\n", + LOG_I(PHY,"rx_max_num_samps %zu\n", s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); for (int i = 0; itimestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance; if (recv_if_count != 0 ) { recv_if_count = recv_if_count-1; - LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); - LOG_D(HW,"[From Timestamp %d to Timestamp %d] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); + LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); + LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); From dcfdd76113ce9c887c120c948ca19e665634a81e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 May 2017 15:35:00 +0200 Subject: [PATCH 558/571] minor: warnings removal It seems that ciphering_algorithm is "unsigned int" in RRC Rel10 and "unsigned long" in RRC Rel14 (as processed by asn1c) Let's force it to unsigned long in the log to avoid compilation-time warnings. --- openair2/RRC/LITE/rrc_eNB_S1AP.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c index 1ec7cc44e8..f3c22abeff 100644 --- a/openair2/RRC/LITE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c @@ -290,7 +290,7 @@ rrc_eNB_process_security( "[eNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n", ctxt_pP->module_id, ue_context_pP->ue_context.security_capabilities.encryption_algorithms, - ue_context_pP->ue_context.ciphering_algorithm, + (unsigned long)ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.security_capabilities.integrity_algorithms, ue_context_pP->ue_context.integrity_algorithm); /* Select relevant algorithms */ @@ -312,7 +312,7 @@ rrc_eNB_process_security( ctxt_pP->module_id, ue_context_pP->ue_context.rnti, security_capabilities_pP, - cipheringAlgorithm, + (unsigned long)cipheringAlgorithm, integrityProtAlgorithm, changed ? "changed" : "same"); From c08bd6ba9c5f6d85720aa40dbd49ed5d72e3b0cb Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 May 2017 15:42:44 +0200 Subject: [PATCH 559/571] warning removal force j to -1, there is a compilation warning with the T tracer (variable may be used uninitialized) --- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 2d3e96bec3..56582f936c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -87,7 +87,7 @@ int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_fra unsigned char header_len_mcch=0,header_len_msi=0,header_len_mtch=0, header_len_mtch_temp=0, header_len_mcch_temp=0, header_len_msi_temp=0; int ii=0, msi_pos=0; int mcch_mcs = -1; - uint16_t TBS,j,padding=0,post_padding=0; + uint16_t TBS,j=-1,padding=0,post_padding=0; mac_rlc_status_resp_t rlc_status; int num_mtch; int msi_length,i,k; From 8160f8a23fa600fe16a2378aa472c8eb43725318 Mon Sep 17 00:00:00 2001 From: Tomohiro Date: Fri, 19 May 2017 09:24:49 +0900 Subject: [PATCH 560/571] Fujitsu No.39 Correct pdcch symbol calculation --- openair1/PHY/LTE_TRANSPORT/dci.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) mode change 100644 => 100755 openair1/PHY/LTE_TRANSPORT/dci.c diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c old mode 100644 new mode 100755 index 21c4c8aba8..d376fcac3b --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -1979,6 +1979,9 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci, uint16_t numCCE = 0; uint8_t i; uint8_t nCCEmin = 0; + uint16_t CCE_max_used_index = 0; + uint16_t firstCCE_max = dci_alloc[0].firstCCE; + uint8_t L = dci_alloc[0].L; // check pdcch duration imposed by PHICH duration (Section 6.9 of 36-211) if (frame_parms->Ncp==1) { // extended prefix @@ -1995,16 +1998,24 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci, for (i=0; i %d\n",i,dci_alloc[i].L); numCCE += (1<<(dci_alloc[i].L)); + + if(firstCCE_max < dci_alloc[i].firstCCE) { + firstCCE_max = dci_alloc[i].firstCCE; + L = dci_alloc[i].L; + } + if(i == (num_dci - 1)) { + CCE_max_used_index = firstCCE_max + (1<N_RB_DL*2)) - if (numCCE <= get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) + if (CCE_max_used_index <= get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) return(cmax(1,nCCEmin)); //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5))) - else if (numCCE <= get_nCCE(2, frame_parms, get_mi(frame_parms, subframe))) + else if (CCE_max_used_index <= get_nCCE(2, frame_parms, get_mi(frame_parms, subframe))) return(cmax(2,nCCEmin)); //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8))) - else if (numCCE <= get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))) + else if (CCE_max_used_index <= get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))) return(cmax(3,nCCEmin)); else if (frame_parms->N_RB_DL<=10) { if (frame_parms->Ncp == 0) { // normal CP From d79c186a136f706868d3bf6d07428b68322383e5 Mon Sep 17 00:00:00 2001 From: echigoya Date: Fri, 19 May 2017 09:36:47 +0900 Subject: [PATCH 561/571] Fujitsu No.6 Correct DAI incrementation --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) mode change 100644 => 100755 openair2/LAYER2/MAC/eNB_scheduler_dlsch.c diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c old mode 100644 new mode 100755 index 595d16587c..68f99bf721 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -612,17 +612,15 @@ schedule_ue_spec( if (round > 0) { - if (frame_parms[CC_id]->frame_type == TDD) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI); - LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); - } - // get freq_allocation nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; if (nb_rb <= nb_available_rb) { + if (frame_parms[CC_id]->frame_type == TDD) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI); + LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", CC_id,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI); + } if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { for(j=0; jN_RBG; j++) { // for indicating the rballoc for each sub-band From 667bfb017304571686b232cd8cce7e1034603033 Mon Sep 17 00:00:00 2001 From: hbilel Date: Fri, 19 May 2017 15:37:57 +0200 Subject: [PATCH 562/571] TDD config 4,5 harq,bundling,multiplexing,ack,nack config 4 tested with Amarisoft --- openair1/PHY/LTE_TRANSPORT/phich.c | 11 + openair1/SCHED/phy_procedures_lte_common.c | 177 ++++++++++++++- openair1/SCHED/phy_procedures_lte_ue.c | 251 ++++++++++++++++++++- 3 files changed, 431 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index d363d4dcf6..5ebe555d4f 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -135,6 +135,17 @@ unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char su break; + case 4: + if ( (subframe == 8) || (subframe == 9) ) { + return(subframe-8); + } else { + LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + } return(0); diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c index 314f934a81..0779341334 100644 --- a/openair1/SCHED/phy_procedures_lte_common.c +++ b/openair1/SCHED/phy_procedures_lte_common.c @@ -105,7 +105,47 @@ void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms, *frame = (current_frame+2) & 1023; break; } - } + } else if (frame_parms->tdd_config == 4) { + switch (current_subframe) { + + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame+1) & 1023; + break; + + case 7: + *subframe = 3; + *frame = (current_frame+1) & 1023; + break; + + case 8: + case 9: + *subframe = 2; + *frame = (current_frame+2) & 1023; + break; + } + } else if (frame_parms->tdd_config == 5) { + switch (current_subframe) { + + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame+1) & 1023; + break; + + case 7: + case 8: + case 9: + *subframe = 2; + *frame = (current_frame+2) & 1023; + break; + } + } } } @@ -137,6 +177,13 @@ void get_Msg3_alloc_ret(LTE_DL_FRAME_PARMS *frame_parms, // original PUSCH in 3, PHICH in 9, ret in 3 next frame // original PUSCH in 4, PHICH in 0, ret in 4 next frame *frame=(current_frame+1) & 1023; + } else if (frame_parms->tdd_config == 4) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + // original PUSCH in 3, PHICH in 9, ret in 3 next frame + *frame=(current_frame+1) & 1023; + } else if (frame_parms->tdd_config == 5) { + // original PUSCH in 2, PHICH in 8, ret in 2 next frame + *frame=(current_frame+1) & 1023; } } } @@ -253,6 +300,24 @@ unsigned char ul_ACK_subframe2_dl_subframe(LTE_DL_FRAME_PARMS *frame_parms,unsig break; + case 4: + if (subframe == 2) { // ACK subframes 0, 4 and 5 + //if (ACK_index==2) + // return(1); TBC + if (ACK_index==2) + return(0); + + return(4+ACK_index); + } else if (subframe == 3) { // ACK subframes 6, 7 8 and 9 + return(6+ACK_index); // To be updated + } else { + LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + case 1: if (subframe == 2) { // ACK subframes 5 and 6 return(5+ACK_index); @@ -297,6 +362,30 @@ unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char s break; + case 4: + if (subframe == 2) { // ACK subframes 0,4 and 5 + return(3); // should be 4 + } else if (subframe == 3) { // ACK subframes 6,7,8 and 9 + return(4); + } else { + LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + + case 5: + if (subframe == 2) { // ACK subframes 0,3,4,5,6,7,8 and 9 + return(8); // should be 3 + } else { + LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + case 1: if (subframe == 2) { // ACK subframes 5 and 6 return(2); @@ -331,7 +420,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, uint8_t do_reset) // 1 to reset ACK/NACK status : 0 otherwise { uint8_t status=0; - uint8_t subframe_ul=0xff, subframe_dl0=0xff, subframe_dl1=0xff; + uint8_t subframe_ul=0xff, subframe_dl0=0xff, subframe_dl1=0xff,subframe_dl2=0xff, subframe_dl3=0xff; // printf("get_ack: SF %d\n",subframe); if (frame_parms->frame_type == FDD) { @@ -485,6 +574,63 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms, break; + case 4: + if (subframe_tx == 2) { // ACK subframes 4, 5 and 0 + subframe_dl0 = 4; + subframe_dl1 = 5; + subframe_dl2 = 0; + subframe_ul = 2; + //printf("subframe_tx 2, TDD config 3: harq_ack[5] = %d (%d),harq_ack[6] = %d (%d)\n",harq_ack[5].ack,harq_ack[5].send_harq_status,harq_ack[6].ack,harq_ack[6].send_harq_status); + } else if (subframe_tx == 3) { // ACK subframes 6, 7 8 and 9 + subframe_dl0 = 6; + subframe_dl1 = 7; + subframe_dl2 = 8; + subframe_dl3 = 9; + subframe_ul = 3; + //printf("Subframe 3, TDD config 3: harq_ack[7] = %d,harq_ack[8] = %d\n",harq_ack[7].ack,harq_ack[8].ack); + //printf("status %d : o_ACK (%d,%d)\n", status,o_ACK[0],o_ACK[1]); + } else { + LOG_E(PHY,"phy_procedures_lte.c: get_ack, illegal subframe_tx %d for tdd_config %d\n", + subframe_tx,frame_parms->tdd_config); + return(0); + } + + // report ACK/NACK status + o_ACK[cw_idx] = 0; + if (harq_ack[subframe_dl0].send_harq_status == 1) + o_ACK[cw_idx] = harq_ack[subframe_dl0].ack; + + if (harq_ack[subframe_dl1].send_harq_status == 1) + o_ACK[cw_idx] &= harq_ack[subframe_dl1].ack; + + if (harq_ack[subframe_dl2].send_harq_status == 1) + o_ACK[cw_idx] &= harq_ack[subframe_dl2].ack; + + if (harq_ack[subframe_dl3].send_harq_status == 1) + o_ACK[cw_idx] &= harq_ack[subframe_dl3].ack; + + pN_bundled[0] = harq_ack[subframe_rx].vDAI_UL; + status = harq_ack[subframe_dl0].send_harq_status + harq_ack[subframe_dl1].send_harq_status + harq_ack[subframe_dl2].send_harq_status + harq_ack[subframe_dl3].send_harq_status; + + LOG_I(PHY,"TDD Config3 UL Sfn %d, dl Sfn0 %d status %d o_Ack %d, dl Sfn1 %d status %d o_Ack %d dl Sfn2 %d status %d o_Ack %d dl Sfn3 %d status %d o_Ack %d subframe_rx %d N_bundled %d status %d\n", + subframe_tx, subframe_dl0, harq_ack[subframe_dl0].send_harq_status,harq_ack[subframe_dl0].ack, + subframe_dl1, harq_ack[subframe_dl1].send_harq_status,harq_ack[subframe_dl1].ack, + subframe_dl2, harq_ack[subframe_dl2].send_harq_status,harq_ack[subframe_dl2].ack, + subframe_dl3, harq_ack[subframe_dl3].send_harq_status,harq_ack[subframe_dl3].ack,subframe_rx, pN_bundled[0], status); + if (do_reset) { + // reset ACK/NACK status + harq_ack[subframe_dl0].ack = 2; + harq_ack[subframe_dl1].ack = 2; + harq_ack[subframe_dl2].ack = 2; + harq_ack[subframe_dl3].ack = 2; + harq_ack[subframe_dl0].send_harq_status = 0; + harq_ack[subframe_dl1].send_harq_status = 0; + harq_ack[subframe_dl2].send_harq_status = 0; + harq_ack[subframe_dl3].send_harq_status = 0; + } + + break; + } } @@ -609,6 +755,29 @@ lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub return(255); } + case 4: + if ((subframe<1) || (subframe>=4)) + return(SF_DL); + else if ((subframe>1) && (subframe < 4)) + return(SF_UL); + else if (subframe==1) + return (SF_S); + else { + LOG_E(PHY,"[PHY_PROCEDURES_LTE] Unknown subframe number\n"); + return(255); + } + + case 5: + if ((subframe<1) || (subframe>=3)) + return(SF_DL); + else if ((subframe>1) && (subframe < 3)) + return(SF_UL); + else if (subframe==1) + return (SF_S); + else { + LOG_E(PHY,"[PHY_PROCEDURES_LTE] Unknown subframe number\n"); + return(255); + } break; default: @@ -683,13 +852,13 @@ unsigned int is_phich_subframe(LTE_DL_FRAME_PARMS *frame_parms,unsigned char sub break; case 4: - if ((subframe == 0) || (subframe == 8) ) + if ((subframe == 8) || (subframe == 9) ) return(1); break; case 5: - if (subframe == 0) + if (subframe == 8) return(1); break; diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 663dc33b49..cba893eafb 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -700,13 +700,14 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, { LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - uint8_t nCCE0,nCCE1,harq_ack1,harq_ack0; + uint8_t nCCE0,nCCE1,nCCE2,nCCE3,harq_ack1,harq_ack0,harq_ack3,harq_ack2; ANFBmode_t bundling_flag; - uint16_t n1_pucch0=0,n1_pucch1=0; + uint16_t n1_pucch0=0,n1_pucch1=0,n1_pucch2=0,n1_pucch3=0,n1_pucch_inter,pucch_sel_inter; static uint8_t candidate_dl[9]; // which downlink(s) the current ACK/NACK is associating to uint8_t last_dl=0xff; // the last downlink with valid DL-DCI. for calculating the PUCCH resource index int sf; int M; + uint8_t ack_counter=0; // clear this, important for case where n1_pucch selection is not used int subframe=proc->subframe_tx; @@ -726,10 +727,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, #ifdef DEBUG_PHY_PROC if (bundling_flag==bundling) { - LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, + LOG_I(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); } else { - LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, + LOG_I(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); } @@ -835,6 +836,11 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].ack; + LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n", + proc->frame_tx%1024, + proc->subframe_tx, + nCCE0,n1_pucch0, + nCCE1,n1_pucch1); if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed @@ -891,6 +897,243 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, break; + case 4: // DL:S:UL:UL:DL:DL:DL:DL:DL:DL + // in this configuration we have M=4 from pg 68 of 36.213 (v8.6) + // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2) + // set ACK/NAKs to DTX + harq_ack3 = 2; // DTX + harq_ack2 = 2; // DTX + harq_ack1 = 2; // DTX + harq_ack0 = 2; // DTX + // This is the offset for a particular subframe (2,3,4) => (0,2,4) + //last_dl = (subframe-2)<<1; + if (subframe == 2) { + // i=0 + //nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[2+subframe]; + nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(8+subframe)%10]; + n1_pucch0 = 2*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; + // i=1 + nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[2+subframe]; + n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; + // i=2 + nCCE2 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(8+subframe)%10]; + n1_pucch2 = 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN; + // i=3 + //nCCE3 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(9+subframe)%10]; + //n1_pucch3 = get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN; + + // set ACK/NAK to values if not DTX + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(8+subframe)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(8+subframe)%10].ack; + + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[2+subframe].ack; + + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack2 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].ack; + + //if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + //harq_ack3 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(9+subframe)%10].ack; + //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d cce2=%d n1_pucch2=%d\n", + // proc->frame_tx%1024, + // proc->subframe_tx, + // nCCE0,n1_pucch0, + // nCCE1,n1_pucch1, nCCE2, n1_pucch2); + }else if (subframe == 3) { + // i=0 + + nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[4+subframe]; + n1_pucch0 = 3*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; + // i=1 + nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[5+subframe]; + n1_pucch1 = 2*get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; + // i=2 + nCCE2 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(6+subframe)]; + n1_pucch2 = get_Np(frame_parms->N_RB_DL,nCCE2,0) + 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN; + // i=3 + nCCE3 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(3+subframe)]; + n1_pucch3 = 3*get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN; + + // set ACK/NAK to values if not DTX + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[4+subframe].ack; + + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+subframe].ack; + + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack2 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+subframe)].ack; + + if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack3 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(3+subframe)].ack; + } + + //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n", + // proc->frame_tx%1024, + // proc->subframe_tx, + // nCCE0,n1_pucch0,harq_ack0, + // nCCE1,n1_pucch1,harq_ack1, nCCE2, n1_pucch2, harq_ack2, + // nCCE3, n1_pucch3, harq_ack3, bundling_flag); + + if ((bundling_flag==bundling)&&(SR == 0)) { // This is for bundling without SR, + if ((harq_ack0!=2) ) { + b[0] = harq_ack0; + n1_pucch_inter = n1_pucch0; + pucch_sel_inter = 0; + } + if ((harq_ack1!=2) ) { + b[0] = b[0]&harq_ack1; + n1_pucch_inter = n1_pucch1; + pucch_sel_inter = 1; + } + if ((harq_ack2!=2) ) { + b[0] = b[0]&harq_ack2; + n1_pucch_inter = n1_pucch2; + pucch_sel_inter = 2; + } + if ((harq_ack3!=2) ) { + b[0] = b[0]&harq_ack3; + n1_pucch_inter = n1_pucch3; + pucch_sel_inter = 3; + } + + if (subframe == 3) { + n1_pucch_inter = n1_pucch2; + } else if (subframe == 2) { + n1_pucch_inter = n1_pucch2; + } + + //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d pucch_sel_inter=%d b[0]=%d b[1]=%d \n", + // proc->frame_tx%1024, + // proc->subframe_tx,n1_pucch_inter, + // pucch_sel_inter,b[0],b[1]); + + return(n1_pucch_inter); + + } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 + + if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[1] = 1; + b[0] = 1; + return(n1_pucch1); + } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 1; + b[1] = 0; + return(n1_pucch1); + } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 0) && (harq_ack3 == 2)) { + b[1] = 1; + b[0] = 1; + return(n1_pucch2); + } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { + b[1] = 1; + b[0] = 0; + return(n1_pucch1); + } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) { + b[1] = 1; + b[0] = 0; + return(n1_pucch0); + } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[1] = 1; + b[0] = 0; + return(n1_pucch1); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch3); + } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 0)) { + b[1] = 1; + b[0] = 1; + return(n1_pucch3); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 1; + return(n1_pucch2); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch0); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 1; + return(n1_pucch0); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch3); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 0) && (harq_ack2 == 2) && (harq_ack3 == 2)) { + b[0] = 0; + b[1] = 0; + return(n1_pucch1); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 1; + b[1] = 0; + return(n1_pucch2); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { + b[0] = 1; + b[1] = 0; + return(n1_pucch3); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 1; + return(n1_pucch1); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch3); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 0; + return(n1_pucch2); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack3 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { + b[0] = 0; + b[1] = 0; + return(n1_pucch3); + } + + } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213) + // this should be number of ACKs (including + if (harq_ack0==1) + ack_counter ++; + if (harq_ack1==1) + ack_counter ++; + if (harq_ack2==1) + ack_counter ++; + if (harq_ack3==1) + ack_counter ++; + + switch (ack_counter) { + case 0: + b[0] = 0; + b[1] = 0; + break; + + case 1: + b[0] = 1; + b[1] = 1; + break; + + case 2: + b[0] = 1; + b[1] = 0; + break; + + case 3: + b[0] = 0; + b[1] = 1; + break; + + case 4: + b[0] = 1; + b[1] = 1; + break; + } + + ack_counter = 0; + return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } + + break; + } // switch tdd_config } From 8625a8672a31db9e34f08a5bbb87f3ed6ba1ae09 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 19 May 2017 16:17:56 +0200 Subject: [PATCH 563/571] T: improve trace ENB_PHY_ULSCH_UE_DCI --- common/utils/T/T_messages.txt | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 09ed098ee0..c78bc92d36 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -28,7 +28,7 @@ ID = ENB_PHY_DLSCH_UE_NACK ID = ENB_PHY_ULSCH_UE_DCI DESC = eNodeB uplink UE specific DCI as sent by the PHY layer GROUP = ALL:PHY:GRAPHIC:ENB - FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS + FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS : int,L : int,firstCCE ID = ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION DESC = eNodeB uplink UE retransmission due to PHICH NACK (see generate_phich_top) GROUP = ALL:PHY:GRAPHIC:ENB diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 673583f78c..f8b9a9ae59 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -906,7 +906,9 @@ void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->round), T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->first_rb), T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->nb_rb), - T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->TBS)); + T_INT(eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->TBS), + T_INT(dci_alloc->L), + T_INT(dci_alloc->firstCCE)); } void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int num_pdcch_symbols) { From dd7691ec60eb83352e733a06bea8baec53ba81cc Mon Sep 17 00:00:00 2001 From: gabrielC Date: Fri, 19 May 2017 16:22:51 +0200 Subject: [PATCH 564/571] Fix warning compilation --- openair1/SCHED/phy_procedures_lte_ue.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index cba893eafb..d3d763cd56 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -702,7 +702,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; uint8_t nCCE0,nCCE1,nCCE2,nCCE3,harq_ack1,harq_ack0,harq_ack3,harq_ack2; ANFBmode_t bundling_flag; - uint16_t n1_pucch0=0,n1_pucch1=0,n1_pucch2=0,n1_pucch3=0,n1_pucch_inter,pucch_sel_inter; + uint16_t n1_pucch0=0,n1_pucch1=0,n1_pucch2=0,n1_pucch3=0,n1_pucch_inter; static uint8_t candidate_dl[9]; // which downlink(s) the current ACK/NACK is associating to uint8_t last_dl=0xff; // the last downlink with valid DL-DCI. for calculating the PUCCH resource index int sf; @@ -979,22 +979,18 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, if ((harq_ack0!=2) ) { b[0] = harq_ack0; n1_pucch_inter = n1_pucch0; - pucch_sel_inter = 0; } if ((harq_ack1!=2) ) { b[0] = b[0]&harq_ack1; n1_pucch_inter = n1_pucch1; - pucch_sel_inter = 1; } if ((harq_ack2!=2) ) { b[0] = b[0]&harq_ack2; n1_pucch_inter = n1_pucch2; - pucch_sel_inter = 2; } if ((harq_ack3!=2) ) { b[0] = b[0]&harq_ack3; n1_pucch_inter = n1_pucch3; - pucch_sel_inter = 3; } if (subframe == 3) { @@ -1003,10 +999,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, n1_pucch_inter = n1_pucch2; } - //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d pucch_sel_inter=%d b[0]=%d b[1]=%d \n", + //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d b[0]=%d b[1]=%d \n", // proc->frame_tx%1024, // proc->subframe_tx,n1_pucch_inter, - // pucch_sel_inter,b[0],b[1]); + // b[0],b[1]); return(n1_pucch_inter); From 685464c20495140d0b84d17678b83603b3fb2f37 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 19 May 2017 16:27:08 +0200 Subject: [PATCH 565/571] pre-integration fix: correct comparison get_nCCE returns the number of available CCEs. We can put the CCEs numbers [ 0 .. get_nCCE-1 ], so we need to use <, not <=. --- openair1/PHY/LTE_TRANSPORT/dci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index d376fcac3b..298dbd9791 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -2009,13 +2009,13 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci, } //if ((9*numCCE) <= (frame_parms->N_RB_DL*2)) - if (CCE_max_used_index <= get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) + if (CCE_max_used_index < get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) return(cmax(1,nCCEmin)); //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 4 : 5))) - else if (CCE_max_used_index <= get_nCCE(2, frame_parms, get_mi(frame_parms, subframe))) + else if (CCE_max_used_index < get_nCCE(2, frame_parms, get_mi(frame_parms, subframe))) return(cmax(2,nCCEmin)); //else if ((9*numCCE) <= (frame_parms->N_RB_DL*((frame_parms->nb_antenna_ports_eNB==4) ? 7 : 8))) - else if (CCE_max_used_index <= get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))) + else if (CCE_max_used_index < get_nCCE(3, frame_parms, get_mi(frame_parms, subframe))) return(cmax(3,nCCEmin)); else if (frame_parms->N_RB_DL<=10) { if (frame_parms->Ncp == 0) { // normal CP From 9cf288f6f3679e0c33df7f67a01a111b6c862faa Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 19 May 2017 16:29:07 +0200 Subject: [PATCH 566/571] pre-integration fix: minor improvement we can compute CCE_max_used_index out of the loop. --- openair1/PHY/LTE_TRANSPORT/dci.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 298dbd9791..8b7a818297 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -2000,13 +2000,11 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci, numCCE += (1<<(dci_alloc[i].L)); if(firstCCE_max < dci_alloc[i].firstCCE) { - firstCCE_max = dci_alloc[i].firstCCE; - L = dci_alloc[i].L; - } - if(i == (num_dci - 1)) { - CCE_max_used_index = firstCCE_max + (1<N_RB_DL*2)) if (CCE_max_used_index < get_nCCE(1, frame_parms, get_mi(frame_parms, subframe))) From 8e57a58dd632bef9b8534371709df25e080cb35f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 19 May 2017 17:00:36 +0200 Subject: [PATCH 567/571] fix run_enb_ue_virt_noS1 and run_enb_ue_virt_s1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problems reported by Jorge Muñoz Castañer . - use Rel14 binaries (those are produced by default) - let -x option work to have graphical output - fix VCD missing 'echo' --- cmake_targets/tools/run_enb_ue_virt_noS1 | 11 ++++++++--- cmake_targets/tools/run_enb_ue_virt_s1 | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/cmake_targets/tools/run_enb_ue_virt_noS1 b/cmake_targets/tools/run_enb_ue_virt_noS1 index a0f23ecb01..a5139d4b44 100755 --- a/cmake_targets/tools/run_enb_ue_virt_noS1 +++ b/cmake_targets/tools/run_enb_ue_virt_noS1 @@ -150,7 +150,7 @@ function main() # -u | --num-ue ) -V | --vcd) - "setting gtk-wave output" + echo "setting gtk-wave output" exe_arguments="$exe_arguments -V /tmp/oai_gtk_wave.vcd" shift ; ;; @@ -164,6 +164,11 @@ function main() exe_arguments="$exe_arguments -n $2" shift 2; ;; + -x | --xforms) + echo "running with xforms" + exe_arguments="$exe_arguments --xforms" + shift 1; + ;; *) echo "Unknown option $1" help @@ -212,11 +217,11 @@ function main() fi if [ $run_gdb -eq 0 ]; then - exec $SUDO $OPENAIR_DIR/targets/bin/oaisim_nos1.Rel10 $exe_arguments | tee /tmp/enb_ue_nos1.log.txt + exec $SUDO $OPENAIR_DIR/targets/bin/oaisim_nos1.Rel14 $exe_arguments | tee /tmp/enb_ue_nos1.log.txt else touch ~/.gdb_enb_ue_nos1 chmod 777 ~/.gdb_enb_ue_nos1 - echo "file $OPENAIR_DIR/targets/bin/oaisim_nos1.Rel10" > ~/.gdb_enb_ue_nos1 + echo "file $OPENAIR_DIR/targets/bin/oaisim_nos1.Rel14" > ~/.gdb_enb_ue_nos1 echo "set args $exe_arguments" >> ~/.gdb_enb_ue_nos1 echo "run" >> ~/.gdb_enb_ue_nos1 cat ~/.gdb_enb_ue_nos1 diff --git a/cmake_targets/tools/run_enb_ue_virt_s1 b/cmake_targets/tools/run_enb_ue_virt_s1 index ff65946803..8e717f393a 100755 --- a/cmake_targets/tools/run_enb_ue_virt_s1 +++ b/cmake_targets/tools/run_enb_ue_virt_s1 @@ -174,7 +174,7 @@ function main() ;; -V | --vcd) - "setting gtk-wave output" + echo "setting gtk-wave output" exe_arguments="$exe_arguments -V /tmp/oai_gtk_wave.vcd" shift ; ;; @@ -183,6 +183,11 @@ function main() exe_arguments="$exe_arguments -P wireshark" shift 2; ;; + -x | --xforms) + echo "running with xforms" + exe_arguments="$exe_arguments --xforms" + shift 1; + ;; *) echo "Unknown option $1" help @@ -258,11 +263,11 @@ function main() fi if [ $run_gdb -eq 0 ]; then - exec $OPENAIR_DIR/targets/bin/oaisim.Rel10 $exe_arguments | tee /tmp/enb_ue_s1.log.txt + exec $OPENAIR_DIR/targets/bin/oaisim.Rel14 $exe_arguments | tee /tmp/enb_ue_s1.log.txt else touch ~/.gdb_enb_ue_s1 chmod 777 ~/.gdb_enb_ue_s1 - echo "file $OPENAIR_DIR/targets/bin/oaisim.Rel10" > ~/.gdb_enb_ue_s1 + echo "file $OPENAIR_DIR/targets/bin/oaisim.Rel14" > ~/.gdb_enb_ue_s1 echo "set args $exe_arguments" >> ~/.gdb_enb_ue_s1 echo "run" >> ~/.gdb_enb_ue_s1 cat ~/.gdb_enb_ue_s1 From c15a9a8294555c5591db0d4329b22d4ef99caf6a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 22 May 2017 10:23:24 +0200 Subject: [PATCH 568/571] post-integration fix: remove compilation warnings --- openair1/PHY/TOOLS/lte_dfts.c | 12 +++++++++++ openair1/SIMULATION/TOOLS/random_channel.c | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 6 +++--- openair2/RRC/LITE/rrc_eNB.c | 4 ++-- targets/SIMU/USER/channel_sim.c | 2 +- targets/SIMU/USER/event_handler.c | 24 +++++++++++----------- targets/SIMU/USER/oaisim_config.c | 8 ++++---- targets/SIMU/USER/oaisim_functions.c | 12 +++++------ 8 files changed, 41 insertions(+), 29 deletions(-) diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index 1ba997af17..0aaea70d7d 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -2510,6 +2510,8 @@ const static int16_t tw64[96] __attribute__((aligned(32))) = { -30273,12539,-25330,20787,-18205,27244,-9512,31356 }; +#if 0 +/* this is defined but not used, let's comment */ const static int16_t tw64rep[192] __attribute__((aligned(32))) = { 32767,0,32609,-3212,32137,-6393,31356,-9512,32767,0,32609,-3212,32137,-6393,31356,-9512, 30272,-12540,28897,-15447,27244,-18205,25329,-20788,30272,-12540,28897,-15447,27244,-18205,25329,-20788, @@ -2524,6 +2526,7 @@ const static int16_t tw64rep[192] __attribute__((aligned(32))) = { -23170,-23170,-28898,-15447,-32138,-6393,-32610,3211,-23170,-23170,-28898,-15447,-32138,-6393,-32610,3211, -30273,12539,-25330,20787,-18205,27244,-9512,31356,-30273,12539,-25330,20787,-18205,27244,-9512,31356 }; +#endif const static int16_t tw64a[96] __attribute__((aligned(32))) = { 32767,0,32609,3212,32137,6393,31356,9512, @@ -2539,6 +2542,8 @@ const static int16_t tw64a[96] __attribute__((aligned(32))) = { -23170,23170,-28898,15447,-32138,6393,-32610,-3211, -30273,-12539,-25330,-20787,-18205,-27244,-9512,-31356 }; +#if 0 +/* this is defined but not used, let's comment */ const static int16_t tw64arep[192] __attribute__((aligned(32))) = { 32767,0,32609,3212,32137,6393,31356,9512,32767,0,32609,3212,32137,6393,31356,9512, 30272,12540,28897,15447,27244,18205,25329,20788,30272,12540,28897,15447,27244,18205,25329,20788, @@ -2553,6 +2558,7 @@ const static int16_t tw64arep[192] __attribute__((aligned(32))) = { -23170,23170,-28898,15447,-32138,6393,-32610,-3211,-23170,23170,-28898,15447,-32138,6393,-32610,-3211, -30273,-12539,-25330,-20787,-18205,-27244,-9512,-31356,-30273,-12539,-25330,-20787,-18205,-27244,-9512,-31356 }; +#endif const static int16_t tw64b[96] __attribute__((aligned(32))) = { 0,32767,-3212,32609,-6393,32137,-9512,31356, @@ -2569,6 +2575,8 @@ const static int16_t tw64b[96] __attribute__((aligned(32))) = { 12539,-30273,20787,-25330,27244,-18205,31356,-9512 }; +#if 0 +/* this is defined but not used, let's comment */ const static int16_t tw64brep[192] __attribute__((aligned(32))) = { 0,32767,-3212,32609,-6393,32137,-9512,31356,0,32767,-3212,32609,-6393,32137,-9512,31356, -12540,30272,-15447,28897,-18205,27244,-20788,25329,-12540,30272,-15447,28897,-18205,27244,-20788,25329, @@ -2583,6 +2591,7 @@ const static int16_t tw64brep[192] __attribute__((aligned(32))) = { -23170,-23170,-15447,-28898,-6393,-32138,3211,-32610,-23170,-23170,-15447,-28898,-6393,-32138,3211,-32610, 12539,-30273,20787,-25330,27244,-18205,31356,-9512,12539,-30273,20787,-25330,27244,-18205,31356,-9512 }; +#endif const static int16_t tw64c[96] __attribute__((aligned(32))) = { 0,32767,3212,32609,6393,32137,9512,31356, @@ -2599,6 +2608,8 @@ const static int16_t tw64c[96] __attribute__((aligned(32))) = { -12539,-30273,-20787,-25330,-27244,-18205,-31356,-9512 }; +#if 0 +/* this is defined but not used, let's comment */ const static int16_t tw64crep[192] __attribute__((aligned(32))) = { 0,32767,3212,32609,6393,32137,9512,31356,0,32767,3212,32609,6393,32137,9512,31356, 12540,30272,15447,28897,18205,27244,20788,25329,12540,30272,15447,28897,18205,27244,20788,25329, @@ -2613,6 +2624,7 @@ const static int16_t tw64crep[192] __attribute__((aligned(32))) = { 23170,-23170,15447,-28898,6393,-32138,-3211,-32610,23170,-23170,15447,-28898,6393,-32138,-3211,-32610, -12539,-30273,-20787,-25330,-27244,-18205,-31356,-9512,-12539,-30273,-20787,-25330,-27244,-18205,-31356,-9512 }; +#endif #if defined(__x86_64__) || defined(__i386__) diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index ea8781e216..98988ea4cb 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -101,7 +101,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, LOG_D(OCM,"[CHANNEL] Filling a (nb_taps %d)\n",nb_taps); for (i = 0; ia[i],nb_tx*nb_rx * sizeof(struct complex)); + LOG_D(OCM,"tap %d (%p,%zu)\n",i,&chan_desc->a[i],nb_tx*nb_rx * sizeof(struct complex)); chan_desc->a[i] = (struct complex*) malloc(nb_tx*nb_rx * sizeof(struct complex)); } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 0da894df82..2ebcf64cad 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -545,7 +545,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_state_g = 0; // print_active_requests() #ifdef PDCP_DEBUG - LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %d \n", + LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n", nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr)); #endif @@ -603,7 +603,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) if (h_rc == HASH_TABLE_OK) { #ifdef PDCP_DEBUG - LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n", + LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", ctxt.frame, pdcp_read_header_g.inst, len, @@ -693,7 +693,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) if (h_rc == HASH_TABLE_OK) { rab_id = pdcp_p->rb_id; #ifdef PDCP_DEBUG - LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", ctxt.frame, pdcp_read_header_g.inst, len, diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index da9d93c19a..3df39e62c6 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -2268,8 +2268,8 @@ rrc_eNB_process_MeasurementReport( LOG_I(RRC, "RSRP of Source %ld\n", measResults2->measResultPCell.rsrpResult); LOG_I(RRC, "RSRQ of Source %ld\n", measResults2->measResultPCell.rsrqResult); #else - LOG_I(RRC, "RSRP of Source %d\n", measResults2->measResultServCell.rsrpResult); - LOG_I(RRC, "RSRQ of Source %d\n", measResults2->measResultServCell.rsrqResult); + LOG_I(RRC, "RSRP of Source %ld\n", measResults2->measResultServCell.rsrpResult); + LOG_I(RRC, "RSRQ of Source %ld\n", measResults2->measResultServCell.rsrqResult); #endif if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) { diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index 3913de6016..04d7e1d233 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -281,7 +281,7 @@ void do_DL_sig(channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX][MAX_N LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr %f dBm/RE (%f dBm RSSI)for subframe %d\n",UE_id, 10*log10(rx_pwr), 10*log10(rx_pwr*(double)frame_parms->N_RB_DL*12),subframe); - LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (noise) -132 dBm/RE (N0fs = %.1f dBm, N0B = %.1f dBm) for slot %d (subframe %d)\n", + LOG_D(OCM,"[SIM][DL] UE %d : rx_pwr (noise) -132 dBm/RE (N0fs = %.1f dBm, N0B = %.1f dBm) for subframe %d\n", UE_id, 10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6)-174, 10*log10(eNB2UE[eNB_id][UE_id][CC_id]->sampling_rate*1e6*12*frame_parms->N_RB_DL/(double)frame_parms->ofdm_symbol_size)-174, diff --git a/targets/SIMU/USER/event_handler.c b/targets/SIMU/USER/event_handler.c index f2199ca910..c140dab50b 100644 --- a/targets/SIMU/USER/event_handler.c +++ b/targets/SIMU/USER/event_handler.c @@ -513,7 +513,7 @@ void update_mac(Event_t event) if(&mac_config[i].mac_ContentionResolutionTimer !=NULL) { oai_emulation->mac_config[i].mac_ContentionResolutionTimer= mac_config[i].mac_ContentionResolutionTimer; UE_list->UE_sched_ctrl[i].mac_ContentionResolutionTimer = oai_emulation->mac_config[i].mac_ContentionResolutionTimer; - LOG_I(EMU,"mac_ContentionResolutionTimer UE %:", i); + LOG_I(EMU,"mac_ContentionResolutionTimer UE %d:", i); LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_sched_ctrl[i].mac_ContentionResolutionTimer); } @@ -637,7 +637,7 @@ void update_mac(Event_t event) if(&mac_config[i].mac_ContentionResolutionTimer !=NULL) { oai_emulation->mac_config[i].mac_ContentionResolutionTimer= mac_config[i].mac_ContentionResolutionTimer; UE_list->UE_sched_ctrl[i].mac_ContentionResolutionTimer = oai_emulation->mac_config[i].mac_ContentionResolutionTimer; - LOG_I(EMU,"mac_ContentionResolutionTimer UE %:", i); + LOG_I(EMU,"mac_ContentionResolutionTimer UE %d:", i); LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_sched_ctrl[i].mac_ContentionResolutionTimer); } @@ -903,13 +903,13 @@ void update_mac(Event_t event) for(i=UE_list->head; i>=0; i=UE_list->next[i]) { oai_emulation->mac_config[i].cqiSchedInterval= mac_config[i].cqiSchedInterval; UE_list->UE_sched_ctrl[i].cqiSchedInterval = oai_emulation->mac_config[i].cqiSchedInterval; - LOG_I(EMU,"cqiSchedInterval UE :\n", i); + LOG_I(EMU,"cqiSchedInterval UE %d:\n", i); LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[i].cqiSchedInterval); } } else { oai_emulation->mac_config[event.ue].cqiSchedInterval= mac_config[event.ue].cqiSchedInterval; UE_list->UE_sched_ctrl[event.ue].cqiSchedInterval = oai_emulation->mac_config[event.ue].cqiSchedInterval; - LOG_I(EMU,"cqiSchedInterval UE :\n", event.ue); + LOG_I(EMU,"cqiSchedInterval UE %d:\n", event.ue); LOG_I(EMU,"%" PRIu16 "\n",UE_list->UE_sched_ctrl[event.ue].cqiSchedInterval); } } else if(!strcmp((char *) event.key, "mac_ContentionResolutionTimer") && event.value!=NULL && validate_mac(event)) { @@ -923,13 +923,13 @@ void update_mac(Event_t event) for(i=UE_list->head; i>=0; i=UE_list->next[i]) { oai_emulation->mac_config[i].mac_ContentionResolutionTimer= mac_config[i].mac_ContentionResolutionTimer; UE_list->UE_sched_ctrl[i].mac_ContentionResolutionTimer = oai_emulation->mac_config[i].mac_ContentionResolutionTimer; - LOG_I(EMU,"mac_ContentionResolutionTimer UE :\n", i); + LOG_I(EMU,"mac_ContentionResolutionTimer UE %d:\n", i); LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_sched_ctrl[i].mac_ContentionResolutionTimer); } } else { oai_emulation->mac_config[event.ue].mac_ContentionResolutionTimer= mac_config[event.ue].mac_ContentionResolutionTimer; UE_list->UE_sched_ctrl[event.ue].mac_ContentionResolutionTimer = oai_emulation->mac_config[event.ue].mac_ContentionResolutionTimer; - LOG_I(EMU,"mac_ContentionResolutionTimer UE :\n", event.ue); + LOG_I(EMU,"mac_ContentionResolutionTimer UE %d:\n", event.ue); LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_sched_ctrl[event.ue].mac_ContentionResolutionTimer); } } else if(!strcmp((char *) event.key, "max_allowed_rbs") && event.value!=NULL && validate_mac(event)) { @@ -1040,7 +1040,7 @@ void update_sys_model(Event_t event) LOG_I(EMU,"free_space_model_parameters.pathloss_exponent %G\n",oai_emulation->environment_system_config.fading.free_space_model_parameters.pathloss_exponent); LOG_I(EMU,"free_space_model_parameters.pathloss_0_dB %G\n",oai_emulation->environment_system_config.fading.free_space_model_parameters.pathloss_0_dB); - LOG_I(EMU,"ricean_8tap.rice_factor_dB %G\n",oai_emulation->environment_system_config.fading.ricean_8tap.rice_factor_dB); + LOG_I(EMU,"ricean_8tap.rice_factor_dB %d\n",oai_emulation->environment_system_config.fading.ricean_8tap.rice_factor_dB); //Antenna LOG_I(EMU,"antenna.eNB_antenna.number_of_sectors %d\n",oai_emulation->environment_system_config.antenna.eNB_antenna.number_of_sectors); @@ -1103,7 +1103,7 @@ void update_sys_model(Event_t event) } else if(!strcmp((char *) event.key, "free_space_model_parameters.pathloss_0_dB")) { LOG_I(EMU,"free_space_model_parameters.pathloss_0_dB %G\n",oai_emulation->environment_system_config.fading.free_space_model_parameters.pathloss_0_dB); } else if(!strcmp((char *) event.key, "ricean_8tap.rice_factor_dB")) { - LOG_I(EMU,"ricean_8tap.rice_factor_dB %G\n",oai_emulation->environment_system_config.fading.ricean_8tap.rice_factor_dB); + LOG_I(EMU,"ricean_8tap.rice_factor_dB %d\n",oai_emulation->environment_system_config.fading.ricean_8tap.rice_factor_dB); } else if(!strcmp((char *) event.key, "antenna.eNB_antenna.number_of_sectors")) { LOG_I(EMU,"antenna.eNB_antenna.number_of_sectors %d\n",oai_emulation->environment_system_config.antenna.eNB_antenna.number_of_sectors); } else if(!strcmp((char *) event.key, "antenna.eNB_antenna.beam_width_dB")) { @@ -1202,8 +1202,8 @@ void update_topo_model(Event_t event) LOG_I(EMU,"UE_moving_dynamics_max_speed_mps %G\n",oai_emulation->topology_config.mobility.UE_mobility.UE_moving_dynamics.max_speed_mps); LOG_I(EMU,"UE_moving_dynamics_min_journey_time_ms %G\n",oai_emulation->topology_config.mobility.UE_mobility.UE_moving_dynamics.min_journey_time_ms); LOG_I(EMU,"UE_moving_dynamics_max_journey_time_ms %G\n",oai_emulation->topology_config.mobility.UE_mobility.UE_moving_dynamics.max_journey_time_ms); - LOG_I(EMU,"grid_map_horizontal_grid %G\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid); - LOG_I(EMU,"grid_map_vertical_grid %G\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid); + LOG_I(EMU,"grid_map_horizontal_grid %d\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid); + LOG_I(EMU,"grid_map_vertical_grid %d\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid); LOG_I(EMU,"UE_initial_distribution_selected_option %s\n",oai_emulation->topology_config.mobility.UE_mobility.UE_initial_distribution.selected_option); LOG_I(EMU,"random_UE_distribution_number_of_nodes %d\n",oai_emulation->topology_config.mobility.UE_mobility.random_UE_distribution.number_of_nodes); LOG_I(EMU,"concentrated_UE_distribution_number_of_nodes %d\n",oai_emulation->topology_config.mobility.UE_mobility.concentrated_UE_distribution.number_of_nodes); @@ -1245,9 +1245,9 @@ void update_topo_model(Event_t event) } else if(!strcmp((char *) event.key, "UE_moving_dynamics_max_journey_time_ms")) { LOG_I(EMU,"UE_moving_dynamics_max_journey_time_ms %G\n",oai_emulation->topology_config.mobility.UE_mobility.UE_moving_dynamics.max_journey_time_ms); } else if(!strcmp((char *) event.key, "grid_map_horizontal_grid")) { - LOG_I(EMU,"grid_map_horizontal_grid %G\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid); + LOG_I(EMU,"grid_map_horizontal_grid %d\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.horizontal_grid); } else if(!strcmp((char *) event.key, "grid_map_vertical_grid")) { - LOG_I(EMU,"grid_map_vertical_grid %G\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid); + LOG_I(EMU,"grid_map_vertical_grid %d\n",oai_emulation->topology_config.mobility.UE_mobility.grid_walk.grid_map.vertical_grid); } else if(!strcmp((char *) event.key, "UE_initial_distribution_selected_option")) { LOG_I(EMU,"UE_initial_distribution_selected_option %s\n",oai_emulation->topology_config.mobility.UE_mobility.UE_initial_distribution.selected_option); } else if(!strcmp((char *) event.key, "random_UE_distribution_number_of_nodes")) { diff --git a/targets/SIMU/USER/oaisim_config.c b/targets/SIMU/USER/oaisim_config.c index e3aac4f481..70728875f5 100644 --- a/targets/SIMU/USER/oaisim_config.c +++ b/targets/SIMU/USER/oaisim_config.c @@ -468,7 +468,7 @@ int ocg_config_env(void) oai_emulation.info.frame_type[CC_id] = map_str_to_int(frame_type_names, oai_emulation.info.frame_type_name[CC_id]); if (oai_emulation.info.frame_type[CC_id] == -1) { - LOG_E(EMU,"frame type incorrect %s, set it to TDD \n",oai_emulation.info.frame_type_name); + LOG_E(EMU,"frame type incorrect %s, set it to TDD \n",oai_emulation.info.frame_type_name[CC_id]); oai_emulation.info.frame_type[CC_id]=TDD; } else LOG_I(EMU,"Frame type is %s \n",oai_emulation.info.frame_type_name[CC_id]); @@ -478,7 +478,7 @@ int ocg_config_env(void) LOG_E(EMU,"TDD config %d out of range, set it to 3\n",oai_emulation.info.tdd_config[CC_id]); oai_emulation.info.tdd_config[CC_id]=3; } else - LOG_I(EMU,"TDD config is set to \n",oai_emulation.info.tdd_config[CC_id]); + LOG_I(EMU,"TDD config is set to %d\n",oai_emulation.info.tdd_config[CC_id]); } } } @@ -1087,8 +1087,8 @@ int ocg_config_app(void) oai_emulation.application_config.customized_traffic.holding_time_pe_off[customized_traffic_config_index]; - LOG_I(OTG,"customized:: OCG_config_OTG: (2) FORMAT (%d:%d) source = %d, dest = %d, dist type for size = %d start/duration %d/%d\n", source_id_start, source_id_end, source_id_index, - destination_id_index, g_otg->size_dist[source_id_index][destination_id_index][0], + LOG_I(OTG,"customized:: OCG_config_OTG: (2) FORMAT (%s:%s) source = %d, dest = %d, dist type for size = %d [TODO: check code, printed value may not be correct, checks the indexes of the arry access] start/duration %d/%d\n", source_id_start, source_id_end, source_id_index, + destination_id_index, g_otg->size_dist[source_id_index][destination_id_index][0][0], g_otg->flow_start[source_id_index][destination_id_index][g_otg->application_idx[source_id_index][destination_id_index]], g_otg->flow_duration[source_id_index][destination_id_index][g_otg->application_idx[source_id_index][destination_id_index]]); per_source_id = strtok(NULL, comma); diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index f6fc55852a..71304aea8e 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -1050,15 +1050,15 @@ int eNB_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void * *ptimestamp = last_eNB_rx_timestamp[eNB_id][CC_id]; - LOG_D(EMU,"eNB_trx_read nsamps %d TS(%llu,%llu) => subframe %d\n",nsamps, - (unsigned long long)current_eNB_rx_timestamp[eNB_id][CC_id], - (unsigned long long)last_eNB_rx_timestamp[eNB_id][CC_id], - (*ptimestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10); + LOG_D(EMU,"eNB_trx_read nsamps %d TS(%"PRId64",%"PRId64") => subframe %d\n",nsamps, + current_eNB_rx_timestamp[eNB_id][CC_id], + last_eNB_rx_timestamp[eNB_id][CC_id], + (int)((*ptimestamp/PHY_vars_eNB_g[eNB_id][CC_id]->frame_parms.samples_per_tti)%10)); // if we're at a subframe boundary generate UL signals for this eNB while (nsamps) { while (current_eNB_rx_timestamp[eNB_id][CC_id] == last) { - LOG_D(EMU,"eNB: current TS %llu, last TS %llu, sleeping\n",current_eNB_rx_timestamp[eNB_id][CC_id],last_eNB_rx_timestamp[eNB_id][CC_id]); + LOG_D(EMU,"eNB: current TS %"PRId64", last TS %"PRId64", sleeping\n",current_eNB_rx_timestamp[eNB_id][CC_id],last_eNB_rx_timestamp[eNB_id][CC_id]); usleep(500); } @@ -1126,7 +1126,7 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** usleep(500); } while (current_UE_rx_timestamp[UE_id][CC_id] == last) { - LOG_D(EMU,"UE_trx_read : current TS %d, last TS %d, sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); + LOG_D(EMU,"UE_trx_read : current TS %"PRId64", last TS %"PRId64", sleeping\n",current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); usleep(500); } From 2237b431c2c7774655bde6a89d15e21ec7b76ab4 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 22 May 2017 10:34:55 +0200 Subject: [PATCH 569/571] integration fix: fix compilation warnings --- openair2/RRC/LITE/rrc_UE.c | 4 ++-- openair2/RRC/LITE/rrc_eNB.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index dd3690e2ac..6798212fb2 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -747,10 +747,10 @@ rrc_ue_establish_drb( # ifdef OAI_EMU oai_emulation.info.oai_ifup[ue_mod_idP]=1; # endif - LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %d to/from the protocol stack\n", + LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, - (eNB_index * maxDRB) + DRB_config->drb_Identity); + (long int)((eNB_index * maxDRB) + DRB_config->drb_Identity)); rb_conf_ipv4(0,//add ue_mod_idP,//cx align with the UE index diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 3df39e62c6..659f1c57b0 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -3613,9 +3613,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( dest_ip_offset = 8; # endif LOG_I(OIP, - "[eNB %d] Config the oai%d to send/receive pkt on DRB %d to/from the protocol stack\n", + "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", ctxt_pP->module_id, ctxt_pP->module_id, - (ue_context_pP->local_uid * maxDRB) + DRB_configList->list.array[i]->drb_Identity); + (long int)((ue_context_pP->local_uid * maxDRB) + DRB_configList->list.array[i]->drb_Identity)); ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; rb_conf_ipv4(0, //add ue_module_id, //cx From c98339e104c6bfb291eebd616e12543bed24be60 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 22 May 2017 10:41:33 +0200 Subject: [PATCH 570/571] integration fix: remove compilation warnings --- targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index bb9435413d..f22206eec8 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -297,7 +297,7 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value) { if (ret == -1) { fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); } else { - printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); + printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); } printf("[ETHERNET] Coalesce parameters %s\n",system_cmd); } else { @@ -314,7 +314,7 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value) { if (ret == -1) { fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); } else { - printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); + printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); } printf("[ETHERNET] Pause parameters %s\n",system_cmd); } else { @@ -329,7 +329,7 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value) { if (ret == -1) { fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); } else { - printf ("[ETHERNET] status of %s is %i\n",WEXITSTATUS(ret)); + printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); } printf("[ETHERNET] Ring parameters %s\n",system_cmd); } else { From 9bef36f23a9679a3fb2d6fc332b37d2f748c497e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 22 May 2017 11:41:14 +0200 Subject: [PATCH 571/571] Release 0.6. --- README.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.txt b/README.txt index 04d02bf9c7..bff09c7a2a 100644 --- a/README.txt +++ b/README.txt @@ -39,3 +39,7 @@ v0.3 -> Last stable commit on develop branch before the merge of feature-131-new v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0 v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB +v0.5.2 -> Last version with old code for oaisim (abstraction mode works) +v0.6 -> RRH functionality, UE greatly improved, better TDD support, + a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not + work, you need to use v0.5.2 for that.